| // Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:analyzer/dart/ast/ast.dart'; |
| import 'package:analyzer/dart/ast/visitor.dart'; |
| |
| class _SuperVisitor extends RecursiveAstVisitor<void> { |
| final String name; |
| final _Usage _usage; |
| |
| /// Set to `true` if a super invocation with the [name] is found. |
| bool hasSuperInvocation = false; |
| |
| _SuperVisitor(this.name, this._usage); |
| |
| @override |
| void visitAssignmentExpression(AssignmentExpression node) { |
| if (_usage == _Usage.writing) { |
| var left = node.leftHandSide; |
| if (left is PropertyAccess) { |
| if (left.target is SuperExpression && left.propertyName.name == name) { |
| hasSuperInvocation = true; |
| return; |
| } |
| } |
| } |
| super.visitAssignmentExpression(node); |
| } |
| |
| @override |
| void visitBinaryExpression(BinaryExpression node) { |
| if (_usage == _Usage.reading) { |
| if (node.leftOperand is SuperExpression && node.operator.lexeme == name) { |
| hasSuperInvocation = true; |
| return; |
| } |
| } |
| super.visitBinaryExpression(node); |
| } |
| |
| @override |
| void visitMethodInvocation(MethodInvocation node) { |
| if (_usage == _Usage.reading) { |
| if (node.target is SuperExpression && node.methodName.name == name) { |
| hasSuperInvocation = true; |
| return; |
| } |
| } |
| super.visitMethodInvocation(node); |
| } |
| |
| @override |
| void visitPropertyAccess(PropertyAccess node) { |
| if (_usage == _Usage.reading) { |
| var parent = node.parent; |
| if (parent is AssignmentExpression && parent.leftHandSide == node) { |
| // Not reading, skip. |
| } else { |
| if (node.target is SuperExpression && node.propertyName.name == name) { |
| hasSuperInvocation = true; |
| return; |
| } |
| } |
| } |
| super.visitPropertyAccess(node); |
| } |
| } |
| |
| enum _Usage { writing, reading } |
| |
| extension MethodDeclarationExtension on MethodDeclaration { |
| bool get invokesSuperSelf { |
| var visitor = _SuperVisitor( |
| name2.lexeme, |
| isSetter ? _Usage.writing : _Usage.reading, |
| ); |
| body.accept(visitor); |
| return visitor.hasSuperInvocation; |
| } |
| } |