| // Copyright (c) 2014, 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/token.dart'; |
| import 'package:analyzer/dart/ast/visitor.dart'; |
| import 'package:analyzer/exception/exception.dart'; |
| import 'package:analyzer/src/dart/ast/ast.dart'; |
| import 'package:analyzer/src/dart/element/element.dart'; |
| import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine; |
| |
| export 'package:analyzer/src/dart/ast/constant_evaluator.dart'; |
| |
| /// A function used to handle exceptions that are thrown by delegates while |
| /// using an [ExceptionHandlingDelegatingAstVisitor]. |
| typedef ExceptionInDelegateHandler = void Function( |
| AstNode node, AstVisitor visitor, dynamic exception, StackTrace stackTrace); |
| |
| /// An AstVisitor that compares the structure of two AstNodes to see whether |
| /// they are equal. |
| class AstComparator implements AstVisitor<bool> { |
| /// The AST node with which the node being visited is to be compared. This is |
| /// only valid at the beginning of each visit method (until [isEqualNodes] is |
| /// invoked). |
| AstNode? _other; |
| |
| /// Notify that [first] and second have different length. |
| /// This implementation returns `false`. Subclasses can override and throw. |
| bool failDifferentLength(List first, List second) { |
| return false; |
| } |
| |
| /// Check whether the values of the [first] and [second] nodes are [equal]. |
| /// Subclasses can override to throw. |
| bool failIfNotEqual( |
| AstNode first, Object? firstValue, AstNode second, Object? secondValue) { |
| return firstValue == secondValue; |
| } |
| |
| /// Check whether [second] is null. Subclasses can override to throw. |
| bool failIfNotNull(Object? first, Object? second) { |
| return second == null; |
| } |
| |
| /// Notify that [first] is not `null` while [second] one is `null`. |
| /// This implementation returns `false`. Subclasses can override and throw. |
| bool failIsNull(Object first, Object? second) { |
| return false; |
| } |
| |
| /// Notify that [first] and [second] have different types. |
| /// This implementation returns `false`. Subclasses can override and throw. |
| bool failRuntimeType(Object first, Object second) { |
| return false; |
| } |
| |
| /// Return `true` if the [first] node and the [second] node have the same |
| /// structure. |
| /// |
| /// *Note:* This method is only visible for testing purposes and should not be |
| /// used by clients. |
| bool isEqualNodes(AstNode? first, AstNode? second) { |
| if (first == null) { |
| return failIfNotNull(first, second); |
| } else if (second == null) { |
| return failIsNull(first, second); |
| } else if (first.runtimeType != second.runtimeType) { |
| return failRuntimeType(first, second); |
| } |
| _other = second; |
| return first.accept(this)!; |
| } |
| |
| /// Return `true` if the [first] token and the [second] token have the same |
| /// structure. |
| /// |
| /// *Note:* This method is only visible for testing purposes and should not be |
| /// used by clients. |
| bool isEqualTokens(Token? first, Token? second) { |
| if (first == null) { |
| return failIfNotNull(first, second); |
| } else if (second == null) { |
| return failIsNull(first, second); |
| } else if (identical(first, second)) { |
| return true; |
| } |
| return isEqualTokensNotNull(first, second); |
| } |
| |
| /// Return `true` if the [first] token and the [second] token have the same |
| /// structure. Both [first] and [second] are not `null`. |
| bool isEqualTokensNotNull(Token first, Token second) => |
| first.offset == second.offset && |
| first.length == second.length && |
| first.lexeme == second.lexeme; |
| |
| @override |
| bool visitAdjacentStrings(AdjacentStrings node) { |
| AdjacentStrings other = _other as AdjacentStrings; |
| return _isEqualNodeLists(node.strings, other.strings); |
| } |
| |
| @override |
| bool visitAnnotation(Annotation node) { |
| Annotation other = _other as Annotation; |
| return isEqualTokens(node.atSign, other.atSign) && |
| isEqualNodes(node.name, other.name) && |
| isEqualNodes(node.typeArguments, other.typeArguments) && |
| isEqualTokens(node.period, other.period) && |
| isEqualNodes(node.constructorName, other.constructorName) && |
| isEqualNodes(node.arguments, other.arguments); |
| } |
| |
| @override |
| bool visitArgumentList(ArgumentList node) { |
| ArgumentList other = _other as ArgumentList; |
| return isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| _isEqualNodeLists(node.arguments, other.arguments) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis); |
| } |
| |
| @override |
| bool visitAsExpression(AsExpression node) { |
| AsExpression other = _other as AsExpression; |
| return isEqualNodes(node.expression, other.expression) && |
| isEqualTokens(node.asOperator, other.asOperator) && |
| isEqualNodes(node.type, other.type); |
| } |
| |
| @override |
| bool visitAssertInitializer(AssertInitializer node) { |
| AssertInitializer other = _other as AssertInitializer; |
| return isEqualTokens(node.assertKeyword, other.assertKeyword) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.condition, other.condition) && |
| isEqualTokens(node.comma, other.comma) && |
| isEqualNodes(node.message, other.message) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis); |
| } |
| |
| @override |
| bool visitAssertStatement(AssertStatement node) { |
| AssertStatement other = _other as AssertStatement; |
| return isEqualTokens(node.assertKeyword, other.assertKeyword) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.condition, other.condition) && |
| isEqualTokens(node.comma, other.comma) && |
| isEqualNodes(node.message, other.message) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitAssignmentExpression(AssignmentExpression node) { |
| AssignmentExpression other = _other as AssignmentExpression; |
| return isEqualNodes(node.leftHandSide, other.leftHandSide) && |
| isEqualTokens(node.operator, other.operator) && |
| isEqualNodes(node.rightHandSide, other.rightHandSide); |
| } |
| |
| @override |
| bool visitAugmentationImportDirective(AugmentationImportDirective node) { |
| final other = _other as AugmentationImportDirective; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.importKeyword, other.importKeyword) && |
| isEqualNodes(node.uri, other.uri) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitAwaitExpression(AwaitExpression node) { |
| AwaitExpression other = _other as AwaitExpression; |
| return isEqualTokens(node.awaitKeyword, other.awaitKeyword) && |
| isEqualNodes(node.expression, other.expression); |
| } |
| |
| @override |
| bool visitBinaryExpression(BinaryExpression node) { |
| BinaryExpression other = _other as BinaryExpression; |
| return isEqualNodes(node.leftOperand, other.leftOperand) && |
| isEqualTokens(node.operator, other.operator) && |
| isEqualNodes(node.rightOperand, other.rightOperand); |
| } |
| |
| @override |
| bool visitBinaryPattern(BinaryPattern node) { |
| var other = _other as BinaryPattern; |
| return isEqualNodes(node.leftOperand, other.leftOperand) && |
| isEqualTokens(node.operator, other.operator) && |
| isEqualNodes(node.rightOperand, other.rightOperand); |
| } |
| |
| @override |
| bool visitBlock(Block node) { |
| Block other = _other as Block; |
| return isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.statements, other.statements) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitBlockFunctionBody(BlockFunctionBody node) { |
| BlockFunctionBody other = _other as BlockFunctionBody; |
| return isEqualNodes(node.block, other.block); |
| } |
| |
| @override |
| bool visitBooleanLiteral(BooleanLiteral node) { |
| BooleanLiteral other = _other as BooleanLiteral; |
| return isEqualTokens(node.literal, other.literal) && |
| failIfNotEqual(node, node.value, other, other.value); |
| } |
| |
| @override |
| bool visitBreakStatement(BreakStatement node) { |
| BreakStatement other = _other as BreakStatement; |
| return isEqualTokens(node.breakKeyword, other.breakKeyword) && |
| isEqualNodes(node.label, other.label) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitCascadeExpression(CascadeExpression node) { |
| CascadeExpression other = _other as CascadeExpression; |
| return isEqualNodes(node.target, other.target) && |
| _isEqualNodeLists(node.cascadeSections, other.cascadeSections); |
| } |
| |
| @override |
| bool visitCaseClause(CaseClause node) { |
| var other = _other as CaseClause; |
| return isEqualTokens(node.caseKeyword, other.caseKeyword) && |
| isEqualNodes(node.pattern, other.pattern) && |
| isEqualNodes(node.whenClause, other.whenClause); |
| } |
| |
| @override |
| bool visitCastPattern(CastPattern node) { |
| var other = _other as CastPattern; |
| return isEqualNodes(node.pattern, other.pattern) && |
| isEqualTokens(node.asToken, other.asToken) && |
| isEqualNodes(node.type, other.type); |
| } |
| |
| @override |
| bool visitCatchClause(CatchClause node) { |
| CatchClause other = _other as CatchClause; |
| return isEqualTokens(node.onKeyword, other.onKeyword) && |
| isEqualNodes(node.exceptionType, other.exceptionType) && |
| isEqualTokens(node.catchKeyword, other.catchKeyword) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.exceptionParameter, other.exceptionParameter) && |
| isEqualTokens(node.comma, other.comma) && |
| isEqualNodes(node.stackTraceParameter, other.stackTraceParameter) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis) && |
| isEqualNodes(node.body, other.body); |
| } |
| |
| @override |
| bool visitCatchClauseParameter(CatchClauseParameter node) { |
| CatchClauseParameter other = _other as CatchClauseParameter; |
| return isEqualTokens(node.name, other.name); |
| } |
| |
| @override |
| bool visitClassDeclaration(ClassDeclaration node) { |
| ClassDeclaration other = _other as ClassDeclaration; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.abstractKeyword, other.abstractKeyword) && |
| isEqualTokens(node.classKeyword, other.classKeyword) && |
| isEqualTokens(node.name, other.name) && |
| isEqualNodes(node.typeParameters, other.typeParameters) && |
| isEqualNodes(node.extendsClause, other.extendsClause) && |
| isEqualNodes(node.withClause, other.withClause) && |
| isEqualNodes(node.implementsClause, other.implementsClause) && |
| isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.members, other.members) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitClassTypeAlias(ClassTypeAlias node) { |
| ClassTypeAlias other = _other as ClassTypeAlias; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.typedefKeyword, other.typedefKeyword) && |
| isEqualTokens(node.name, other.name) && |
| isEqualNodes(node.typeParameters, other.typeParameters) && |
| isEqualTokens(node.equals, other.equals) && |
| isEqualTokens(node.abstractKeyword, other.abstractKeyword) && |
| isEqualNodes(node.superclass, other.superclass) && |
| isEqualNodes(node.withClause, other.withClause) && |
| isEqualNodes(node.implementsClause, other.implementsClause) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitComment(Comment node) { |
| Comment other = _other as Comment; |
| return _isEqualNodeLists(node.references, other.references); |
| } |
| |
| @override |
| bool visitCommentReference(CommentReference node) { |
| CommentReference other = _other as CommentReference; |
| return isEqualTokens(node.newKeyword, other.newKeyword) && |
| isEqualNodes(node.expression, other.expression); |
| } |
| |
| @override |
| bool visitCompilationUnit(CompilationUnit node) { |
| CompilationUnit other = _other as CompilationUnit; |
| return isEqualTokens(node.beginToken, other.beginToken) && |
| isEqualNodes(node.scriptTag, other.scriptTag) && |
| _isEqualNodeLists(node.directives, other.directives) && |
| _isEqualNodeLists(node.declarations, other.declarations) && |
| isEqualTokens(node.endToken, other.endToken); |
| } |
| |
| @override |
| bool visitConditionalExpression(ConditionalExpression node) { |
| ConditionalExpression other = _other as ConditionalExpression; |
| return isEqualNodes(node.condition, other.condition) && |
| isEqualTokens(node.question, other.question) && |
| isEqualNodes(node.thenExpression, other.thenExpression) && |
| isEqualTokens(node.colon, other.colon) && |
| isEqualNodes(node.elseExpression, other.elseExpression); |
| } |
| |
| @override |
| bool visitConfiguration(Configuration node) { |
| Configuration other = _other as Configuration; |
| return isEqualTokens(node.ifKeyword, other.ifKeyword) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.name, other.name) && |
| isEqualTokens(node.equalToken, other.equalToken) && |
| isEqualNodes(node.value, other.value) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis) && |
| isEqualNodes(node.uri, other.uri); |
| } |
| |
| @override |
| bool visitConstantPattern(ConstantPattern node) { |
| var other = _other as ConstantPattern; |
| return isEqualTokens(node.constKeyword, other.constKeyword) && |
| isEqualNodes(node.expression, other.expression); |
| } |
| |
| @override |
| bool visitConstructorDeclaration(ConstructorDeclaration node) { |
| ConstructorDeclaration other = _other as ConstructorDeclaration; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.externalKeyword, other.externalKeyword) && |
| isEqualTokens(node.constKeyword, other.constKeyword) && |
| isEqualTokens(node.factoryKeyword, other.factoryKeyword) && |
| isEqualNodes(node.returnType, other.returnType) && |
| isEqualTokens(node.period, other.period) && |
| isEqualTokens(node.name, other.name) && |
| isEqualNodes(node.parameters, other.parameters) && |
| isEqualTokens(node.separator, other.separator) && |
| _isEqualNodeLists(node.initializers, other.initializers) && |
| isEqualNodes(node.redirectedConstructor, other.redirectedConstructor) && |
| isEqualNodes(node.body, other.body); |
| } |
| |
| @override |
| bool visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
| ConstructorFieldInitializer other = _other as ConstructorFieldInitializer; |
| return isEqualTokens(node.thisKeyword, other.thisKeyword) && |
| isEqualTokens(node.period, other.period) && |
| isEqualNodes(node.fieldName, other.fieldName) && |
| isEqualTokens(node.equals, other.equals) && |
| isEqualNodes(node.expression, other.expression); |
| } |
| |
| @override |
| bool visitConstructorName(ConstructorName node) { |
| ConstructorName other = _other as ConstructorName; |
| return isEqualNodes(node.type, other.type) && |
| isEqualTokens(node.period, other.period) && |
| isEqualNodes(node.name, other.name); |
| } |
| |
| @override |
| bool visitConstructorReference(ConstructorReference node) { |
| ConstructorReference other = _other as ConstructorReference; |
| return isEqualNodes(node.constructorName, other.constructorName); |
| } |
| |
| @override |
| bool visitConstructorSelector(ConstructorSelector node) { |
| var other = _other as ConstructorSelector; |
| return isEqualTokens(node.period, other.period) && |
| isEqualNodes(node.name, other.name); |
| } |
| |
| @override |
| bool visitContinueStatement(ContinueStatement node) { |
| ContinueStatement other = _other as ContinueStatement; |
| return isEqualTokens(node.continueKeyword, other.continueKeyword) && |
| isEqualNodes(node.label, other.label) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitDeclaredIdentifier(DeclaredIdentifier node) { |
| DeclaredIdentifier other = _other as DeclaredIdentifier; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.keyword, other.keyword) && |
| isEqualNodes(node.type, other.type) && |
| isEqualTokens(node.name, other.name); |
| } |
| |
| @override |
| bool visitDefaultFormalParameter(covariant DefaultFormalParameterImpl node) { |
| var other = _other as DefaultFormalParameterImpl; |
| return isEqualNodes(node.parameter, other.parameter) && |
| node.kind == other.kind && |
| isEqualTokens(node.separator, other.separator) && |
| isEqualNodes(node.defaultValue, other.defaultValue); |
| } |
| |
| @override |
| bool visitDoStatement(DoStatement node) { |
| DoStatement other = _other as DoStatement; |
| return isEqualTokens(node.doKeyword, other.doKeyword) && |
| isEqualNodes(node.body, other.body) && |
| isEqualTokens(node.whileKeyword, other.whileKeyword) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.condition, other.condition) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitDottedName(DottedName node) { |
| DottedName other = _other as DottedName; |
| return _isEqualNodeLists(node.components, other.components); |
| } |
| |
| @override |
| bool visitDoubleLiteral(DoubleLiteral node) { |
| DoubleLiteral other = _other as DoubleLiteral; |
| return isEqualTokens(node.literal, other.literal) && |
| failIfNotEqual(node, node.value, other, other.value); |
| } |
| |
| @override |
| bool visitEmptyFunctionBody(EmptyFunctionBody node) { |
| EmptyFunctionBody other = _other as EmptyFunctionBody; |
| return isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitEmptyStatement(EmptyStatement node) { |
| EmptyStatement other = _other as EmptyStatement; |
| return isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitEnumConstantArguments(EnumConstantArguments node) { |
| var other = _other as EnumConstantArguments; |
| return isEqualNodes(node.typeArguments, other.typeArguments) && |
| isEqualNodes(node.constructorSelector, other.constructorSelector) && |
| isEqualNodes(node.argumentList, other.argumentList); |
| } |
| |
| @override |
| bool visitEnumConstantDeclaration(EnumConstantDeclaration node) { |
| EnumConstantDeclaration other = _other as EnumConstantDeclaration; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.name, other.name); |
| } |
| |
| @override |
| bool visitEnumDeclaration(EnumDeclaration node) { |
| EnumDeclaration other = _other as EnumDeclaration; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.enumKeyword, other.enumKeyword) && |
| isEqualTokens(node.name, other.name) && |
| isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.constants, other.constants) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitExportDirective(ExportDirective node) { |
| ExportDirective other = _other as ExportDirective; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.exportKeyword, other.exportKeyword) && |
| isEqualNodes(node.uri, other.uri) && |
| _isEqualNodeLists(node.combinators, other.combinators) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitExpressionFunctionBody(ExpressionFunctionBody node) { |
| ExpressionFunctionBody other = _other as ExpressionFunctionBody; |
| return isEqualTokens(node.functionDefinition, other.functionDefinition) && |
| isEqualNodes(node.expression, other.expression) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitExpressionStatement(ExpressionStatement node) { |
| ExpressionStatement other = _other as ExpressionStatement; |
| return isEqualNodes(node.expression, other.expression) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitExtendsClause(ExtendsClause node) { |
| ExtendsClause other = _other as ExtendsClause; |
| return isEqualTokens(node.extendsKeyword, other.extendsKeyword) && |
| isEqualNodes(node.superclass, other.superclass); |
| } |
| |
| @override |
| bool visitExtensionDeclaration(ExtensionDeclaration node) { |
| ExtensionDeclaration other = _other as ExtensionDeclaration; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.extensionKeyword, other.extensionKeyword) && |
| isEqualTokens(node.name, other.name) && |
| isEqualNodes(node.typeParameters, other.typeParameters) && |
| isEqualTokens(node.onKeyword, other.onKeyword) && |
| isEqualNodes(node.extendedType, other.extendedType) && |
| isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.members, other.members) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitExtensionOverride(ExtensionOverride node) { |
| ExtensionOverride other = _other as ExtensionOverride; |
| return isEqualNodes(node.extensionName, other.extensionName) && |
| isEqualNodes(node.typeArguments, other.typeArguments) && |
| isEqualNodes(node.argumentList, other.argumentList); |
| } |
| |
| @override |
| bool visitExtractorPattern(ExtractorPattern node) { |
| var other = _other as ExtractorPattern; |
| return isEqualNodes(node.type, other.type) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| _isEqualNodeLists(node.fields, other.fields) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis); |
| } |
| |
| @override |
| bool visitFieldDeclaration(FieldDeclaration node) { |
| FieldDeclaration other = _other as FieldDeclaration; |
| return isEqualTokens(node.abstractKeyword, other.abstractKeyword) && |
| isEqualTokens(node.covariantKeyword, other.covariantKeyword) && |
| isEqualNodes(node.documentationComment, other.documentationComment) && |
| isEqualTokens(node.externalKeyword, other.externalKeyword) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.staticKeyword, other.staticKeyword) && |
| isEqualNodes(node.fields, other.fields) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitFieldFormalParameter(FieldFormalParameter node) { |
| FieldFormalParameter other = _other as FieldFormalParameter; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.keyword, other.keyword) && |
| isEqualNodes(node.type, other.type) && |
| isEqualTokens(node.thisKeyword, other.thisKeyword) && |
| isEqualTokens(node.period, other.period) && |
| isEqualTokens(node.name, other.name); |
| } |
| |
| @override |
| bool visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) { |
| ForEachPartsWithDeclaration other = _other as ForEachPartsWithDeclaration; |
| return isEqualNodes(node.loopVariable, other.loopVariable) && |
| isEqualTokens(node.inKeyword, other.inKeyword) && |
| isEqualNodes(node.iterable, other.iterable); |
| } |
| |
| @override |
| bool visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) { |
| ForEachPartsWithIdentifier other = _other as ForEachPartsWithIdentifier; |
| return isEqualNodes(node.identifier, other.identifier) && |
| isEqualTokens(node.inKeyword, other.inKeyword) && |
| isEqualNodes(node.iterable, other.iterable); |
| } |
| |
| @override |
| bool visitForEachPartsWithPattern(ForEachPartsWithPattern node) { |
| var other = _other as ForEachPartsWithPattern; |
| return isEqualTokens(node.keyword, other.keyword) && |
| isEqualNodes(node.pattern, other.pattern) && |
| isEqualTokens(node.inKeyword, other.inKeyword) && |
| isEqualNodes(node.iterable, other.iterable); |
| } |
| |
| @override |
| bool visitForElement(ForElement node) { |
| ForElement other = _other as ForElement; |
| return isEqualTokens(node.awaitKeyword, other.awaitKeyword) && |
| isEqualTokens(node.forKeyword, other.forKeyword) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.forLoopParts, other.forLoopParts) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis) && |
| isEqualNodes(node.body, other.body); |
| } |
| |
| @override |
| bool visitFormalParameterList(FormalParameterList node) { |
| FormalParameterList other = _other as FormalParameterList; |
| return isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| _isEqualNodeLists(node.parameters, other.parameters) && |
| isEqualTokens(node.leftDelimiter, other.leftDelimiter) && |
| isEqualTokens(node.rightDelimiter, other.rightDelimiter) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis); |
| } |
| |
| @override |
| bool visitForPartsWithDeclarations(ForPartsWithDeclarations node) { |
| ForPartsWithDeclarations other = _other as ForPartsWithDeclarations; |
| return isEqualNodes(node.variables, other.variables) && |
| isEqualTokens(node.leftSeparator, other.leftSeparator) && |
| isEqualNodes(node.condition, other.condition) && |
| isEqualTokens(node.rightSeparator, other.rightSeparator) && |
| _isEqualNodeLists(node.updaters, other.updaters); |
| } |
| |
| @override |
| bool visitForPartsWithExpression(ForPartsWithExpression node) { |
| ForPartsWithExpression other = _other as ForPartsWithExpression; |
| return isEqualNodes(node.initialization, other.initialization) && |
| isEqualTokens(node.leftSeparator, other.leftSeparator) && |
| isEqualNodes(node.condition, other.condition) && |
| isEqualTokens(node.rightSeparator, other.rightSeparator) && |
| _isEqualNodeLists(node.updaters, other.updaters); |
| } |
| |
| @override |
| bool visitForPartsWithPattern(ForPartsWithPattern node) { |
| var other = _other as ForPartsWithPattern; |
| return isEqualNodes(node.variables, other.variables) && |
| isEqualTokens(node.leftSeparator, other.leftSeparator) && |
| isEqualNodes(node.condition, other.condition) && |
| isEqualTokens(node.rightSeparator, other.rightSeparator) && |
| _isEqualNodeLists(node.updaters, other.updaters); |
| } |
| |
| @override |
| bool visitForStatement(ForStatement node) { |
| ForStatement other = _other as ForStatement; |
| return isEqualTokens(node.forKeyword, other.forKeyword) && |
| isEqualTokens(node.awaitKeyword, other.awaitKeyword) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.forLoopParts, other.forLoopParts) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis) && |
| isEqualNodes(node.body, other.body); |
| } |
| |
| @override |
| bool visitFunctionDeclaration(FunctionDeclaration node) { |
| FunctionDeclaration other = _other as FunctionDeclaration; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.externalKeyword, other.externalKeyword) && |
| isEqualNodes(node.returnType, other.returnType) && |
| isEqualTokens(node.propertyKeyword, other.propertyKeyword) && |
| isEqualTokens(node.name, other.name) && |
| isEqualNodes(node.functionExpression, other.functionExpression); |
| } |
| |
| @override |
| bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) { |
| FunctionDeclarationStatement other = _other as FunctionDeclarationStatement; |
| return isEqualNodes(node.functionDeclaration, other.functionDeclaration); |
| } |
| |
| @override |
| bool visitFunctionExpression(FunctionExpression node) { |
| FunctionExpression other = _other as FunctionExpression; |
| return isEqualNodes(node.parameters, other.parameters) && |
| isEqualNodes(node.body, other.body); |
| } |
| |
| @override |
| bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| FunctionExpressionInvocation other = _other as FunctionExpressionInvocation; |
| return isEqualNodes(node.function, other.function) && |
| isEqualNodes(node.argumentList, other.argumentList); |
| } |
| |
| @override |
| bool visitFunctionReference(FunctionReference node) { |
| FunctionReference other = _other as FunctionReference; |
| return isEqualNodes(node.function, other.function) && |
| isEqualNodes(node.typeArguments, other.typeArguments); |
| } |
| |
| @override |
| bool visitFunctionTypeAlias(FunctionTypeAlias node) { |
| FunctionTypeAlias other = _other as FunctionTypeAlias; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.typedefKeyword, other.typedefKeyword) && |
| isEqualNodes(node.returnType, other.returnType) && |
| isEqualTokens(node.name, other.name) && |
| isEqualNodes(node.typeParameters, other.typeParameters) && |
| isEqualNodes(node.parameters, other.parameters) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| FunctionTypedFormalParameter other = _other as FunctionTypedFormalParameter; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualNodes(node.returnType, other.returnType) && |
| isEqualTokens(node.name, other.name) && |
| isEqualNodes(node.parameters, other.parameters); |
| } |
| |
| @override |
| bool visitGenericFunctionType(GenericFunctionType node) { |
| GenericFunctionType other = _other as GenericFunctionType; |
| return isEqualNodes(node.returnType, other.returnType) && |
| isEqualTokens(node.functionKeyword, other.functionKeyword) && |
| isEqualNodes(node.typeParameters, other.typeParameters) && |
| isEqualNodes(node.parameters, other.parameters) && |
| isEqualTokens(node.question, other.question); |
| } |
| |
| @override |
| bool visitGenericTypeAlias(GenericTypeAlias node) { |
| GenericTypeAlias other = _other as GenericTypeAlias; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.typedefKeyword, other.typedefKeyword) && |
| isEqualTokens(node.name, other.name) && |
| isEqualNodes(node.typeParameters, other.typeParameters) && |
| isEqualTokens(node.equals, other.equals) && |
| isEqualNodes(node.type, other.type); |
| } |
| |
| @override |
| bool visitHideClause(HideClause node) { |
| HideClause other = _other as HideClause; |
| return isEqualTokens(node.hideKeyword, other.hideKeyword) && |
| _isEqualNodeLists(node.elements, other.elements); |
| } |
| |
| @override |
| bool visitHideCombinator(HideCombinator node) { |
| HideCombinator other = _other as HideCombinator; |
| return isEqualTokens(node.keyword, other.keyword) && |
| _isEqualNodeLists(node.hiddenNames, other.hiddenNames); |
| } |
| |
| @override |
| bool visitIfElement(IfElement node) { |
| IfElement other = _other as IfElement; |
| return isEqualTokens(node.ifKeyword, other.ifKeyword) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.condition, other.condition) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis) && |
| isEqualNodes(node.thenElement, other.thenElement) && |
| isEqualTokens(node.elseKeyword, other.elseKeyword) && |
| isEqualNodes(node.elseElement, other.elseElement); |
| } |
| |
| @override |
| bool visitIfStatement(IfStatement node) { |
| IfStatement other = _other as IfStatement; |
| return isEqualTokens(node.ifKeyword, other.ifKeyword) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.condition, other.condition) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis) && |
| isEqualNodes(node.thenStatement, other.thenStatement) && |
| isEqualTokens(node.elseKeyword, other.elseKeyword) && |
| isEqualNodes(node.elseStatement, other.elseStatement); |
| } |
| |
| @override |
| bool visitImplementsClause(ImplementsClause node) { |
| ImplementsClause other = _other as ImplementsClause; |
| return isEqualTokens(node.implementsKeyword, other.implementsKeyword) && |
| _isEqualNodeLists(node.interfaces, other.interfaces); |
| } |
| |
| @override |
| bool visitImplicitCallReference(ImplicitCallReference node) { |
| ImplicitCallReference other = _other as ImplicitCallReference; |
| return isEqualNodes(node.expression, other.expression) && |
| isEqualNodes(node.typeArguments, other.typeArguments); |
| } |
| |
| @override |
| bool visitImportDirective(ImportDirective node) { |
| ImportDirective other = _other as ImportDirective; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.importKeyword, other.importKeyword) && |
| isEqualNodes(node.uri, other.uri) && |
| _isEqualNodeLists(node.configurations, other.configurations) && |
| isEqualTokens(node.deferredKeyword, other.deferredKeyword) && |
| isEqualTokens(node.asKeyword, other.asKeyword) && |
| isEqualNodes(node.prefix, other.prefix) && |
| _isEqualNodeLists(node.combinators, other.combinators) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitIndexExpression(IndexExpression node) { |
| IndexExpression other = _other as IndexExpression; |
| return isEqualNodes(node.target, other.target) && |
| isEqualTokens(node.leftBracket, other.leftBracket) && |
| isEqualNodes(node.index, other.index) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitInstanceCreationExpression(InstanceCreationExpression node) { |
| InstanceCreationExpression other = _other as InstanceCreationExpression; |
| return isEqualTokens(node.keyword, other.keyword) && |
| isEqualNodes(node.constructorName, other.constructorName) && |
| isEqualNodes(node.argumentList, other.argumentList); |
| } |
| |
| @override |
| bool visitIntegerLiteral(IntegerLiteral node) { |
| IntegerLiteral other = _other as IntegerLiteral; |
| return isEqualTokens(node.literal, other.literal) && |
| failIfNotEqual(node, node.value, other, other.value); |
| } |
| |
| @override |
| bool visitInterpolationExpression(InterpolationExpression node) { |
| InterpolationExpression other = _other as InterpolationExpression; |
| return isEqualTokens(node.leftBracket, other.leftBracket) && |
| isEqualNodes(node.expression, other.expression) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitInterpolationString(InterpolationString node) { |
| InterpolationString other = _other as InterpolationString; |
| return isEqualTokens(node.contents, other.contents) && |
| failIfNotEqual(node, node.value, other, other.value); |
| } |
| |
| @override |
| bool visitIsExpression(IsExpression node) { |
| IsExpression other = _other as IsExpression; |
| return isEqualNodes(node.expression, other.expression) && |
| isEqualTokens(node.isOperator, other.isOperator) && |
| isEqualTokens(node.notOperator, other.notOperator) && |
| isEqualNodes(node.type, other.type); |
| } |
| |
| @override |
| bool visitLabel(Label node) { |
| Label other = _other as Label; |
| return isEqualNodes(node.label, other.label) && |
| isEqualTokens(node.colon, other.colon); |
| } |
| |
| @override |
| bool visitLabeledStatement(LabeledStatement node) { |
| LabeledStatement other = _other as LabeledStatement; |
| return _isEqualNodeLists(node.labels, other.labels) && |
| isEqualNodes(node.statement, other.statement); |
| } |
| |
| @override |
| bool? visitLibraryAugmentationDirective(LibraryAugmentationDirective node) { |
| final other = _other as LibraryAugmentationDirective; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.libraryKeyword, other.libraryKeyword) && |
| isEqualTokens(node.augmentKeyword, other.augmentKeyword) && |
| isEqualNodes(node.uri, other.uri) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitLibraryDirective(LibraryDirective node) { |
| LibraryDirective other = _other as LibraryDirective; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.libraryKeyword, other.libraryKeyword) && |
| isEqualNodes(node.name2, other.name2) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitLibraryIdentifier(LibraryIdentifier node) { |
| LibraryIdentifier other = _other as LibraryIdentifier; |
| return _isEqualNodeLists(node.components, other.components); |
| } |
| |
| @override |
| bool visitListLiteral(ListLiteral node) { |
| ListLiteral other = _other as ListLiteral; |
| return isEqualTokens(node.constKeyword, other.constKeyword) && |
| isEqualNodes(node.typeArguments, other.typeArguments) && |
| isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.elements, other.elements) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitListPattern(ListPattern node) { |
| var other = _other as ListPattern; |
| return isEqualNodes(node.typeArguments, other.typeArguments) && |
| isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.elements, other.elements) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitMapLiteralEntry(MapLiteralEntry node) { |
| MapLiteralEntry other = _other as MapLiteralEntry; |
| return isEqualNodes(node.key, other.key) && |
| isEqualTokens(node.separator, other.separator) && |
| isEqualNodes(node.value, other.value); |
| } |
| |
| @override |
| bool visitMapPattern(MapPattern node) { |
| var other = _other as MapPattern; |
| return isEqualNodes(node.typeArguments, other.typeArguments) && |
| isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.entries, other.entries) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitMapPatternEntry(MapPatternEntry node) { |
| var other = _other as MapPatternEntry; |
| return isEqualNodes(node.key, other.key) && |
| isEqualTokens(node.separator, other.separator) && |
| isEqualNodes(node.value, other.value); |
| } |
| |
| @override |
| bool visitMethodDeclaration(MethodDeclaration node) { |
| MethodDeclaration other = _other as MethodDeclaration; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.externalKeyword, other.externalKeyword) && |
| isEqualTokens(node.modifierKeyword, other.modifierKeyword) && |
| isEqualNodes(node.returnType, other.returnType) && |
| isEqualTokens(node.propertyKeyword, other.propertyKeyword) && |
| isEqualTokens(node.operatorKeyword, other.operatorKeyword) && |
| isEqualTokens(node.name, other.name) && |
| isEqualNodes(node.parameters, other.parameters) && |
| isEqualNodes(node.body, other.body); |
| } |
| |
| @override |
| bool visitMethodInvocation(MethodInvocation node) { |
| MethodInvocation other = _other as MethodInvocation; |
| return isEqualNodes(node.target, other.target) && |
| isEqualTokens(node.operator, other.operator) && |
| isEqualNodes(node.methodName, other.methodName) && |
| isEqualNodes(node.argumentList, other.argumentList); |
| } |
| |
| @override |
| bool visitMixinDeclaration(MixinDeclaration node) { |
| MixinDeclaration other = _other as MixinDeclaration; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.mixinKeyword, other.mixinKeyword) && |
| isEqualTokens(node.name, other.name) && |
| isEqualNodes(node.typeParameters, other.typeParameters) && |
| isEqualNodes(node.onClause, other.onClause) && |
| isEqualNodes(node.implementsClause, other.implementsClause) && |
| isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.members, other.members) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitNamedExpression(NamedExpression node) { |
| NamedExpression other = _other as NamedExpression; |
| return isEqualNodes(node.name, other.name) && |
| isEqualNodes(node.expression, other.expression); |
| } |
| |
| @override |
| bool? visitNamedType(NamedType node) { |
| NamedType other = _other as NamedType; |
| return isEqualNodes(node.name, other.name) && |
| isEqualNodes(node.typeArguments, other.typeArguments) && |
| isEqualTokens(node.question, other.question); |
| } |
| |
| @override |
| bool visitNativeClause(NativeClause node) { |
| NativeClause other = _other as NativeClause; |
| return isEqualTokens(node.nativeKeyword, other.nativeKeyword) && |
| isEqualNodes(node.name, other.name); |
| } |
| |
| @override |
| bool visitNativeFunctionBody(NativeFunctionBody node) { |
| NativeFunctionBody other = _other as NativeFunctionBody; |
| return isEqualTokens(node.nativeKeyword, other.nativeKeyword) && |
| isEqualNodes(node.stringLiteral, other.stringLiteral) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitNullLiteral(NullLiteral node) { |
| NullLiteral other = _other as NullLiteral; |
| return isEqualTokens(node.literal, other.literal); |
| } |
| |
| @override |
| bool visitOnClause(OnClause node) { |
| OnClause other = _other as OnClause; |
| return isEqualTokens(node.onKeyword, other.onKeyword) && |
| _isEqualNodeLists( |
| node.superclassConstraints, other.superclassConstraints); |
| } |
| |
| @override |
| bool visitParenthesizedExpression(ParenthesizedExpression node) { |
| ParenthesizedExpression other = _other as ParenthesizedExpression; |
| return isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.expression, other.expression) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis); |
| } |
| |
| @override |
| bool visitParenthesizedPattern(ParenthesizedPattern node) { |
| var other = _other as ParenthesizedPattern; |
| return isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.pattern, other.pattern) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis); |
| } |
| |
| @override |
| bool visitPartDirective(PartDirective node) { |
| PartDirective other = _other as PartDirective; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.partKeyword, other.partKeyword) && |
| isEqualNodes(node.uri, other.uri) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitPartOfDirective(PartOfDirective node) { |
| PartOfDirective other = _other as PartOfDirective; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.partKeyword, other.partKeyword) && |
| isEqualTokens(node.ofKeyword, other.ofKeyword) && |
| isEqualNodes(node.libraryName, other.libraryName) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitPatternAssignment(PatternAssignment node) { |
| var other = _other as PatternAssignment; |
| return isEqualNodes(node.pattern, other.pattern) && |
| isEqualTokens(node.equals, other.equals) && |
| isEqualNodes(node.expression, other.expression); |
| } |
| |
| @override |
| bool visitPatternAssignmentStatement(PatternAssignmentStatement node) { |
| var other = _other as PatternAssignmentStatement; |
| return isEqualNodes(node.assignment, other.assignment) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitPatternVariableDeclaration(PatternVariableDeclaration node) { |
| var other = _other as PatternVariableDeclaration; |
| return isEqualTokens(node.keyword, other.keyword) && |
| isEqualNodes(node.pattern, other.pattern) && |
| isEqualTokens(node.equals, other.equals) && |
| isEqualNodes(node.expression, other.expression); |
| } |
| |
| @override |
| bool visitPatternVariableDeclarationStatement( |
| PatternVariableDeclarationStatement node) { |
| var other = _other as PatternVariableDeclarationStatement; |
| return isEqualNodes(node.declaration, other.declaration) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitPostfixExpression(PostfixExpression node) { |
| PostfixExpression other = _other as PostfixExpression; |
| return isEqualNodes(node.operand, other.operand) && |
| isEqualTokens(node.operator, other.operator); |
| } |
| |
| @override |
| bool visitPostfixPattern(PostfixPattern node) { |
| var other = _other as PostfixPattern; |
| return isEqualNodes(node.operand, other.operand) && |
| isEqualTokens(node.operator, other.operator); |
| } |
| |
| @override |
| bool visitPrefixedIdentifier(PrefixedIdentifier node) { |
| PrefixedIdentifier other = _other as PrefixedIdentifier; |
| return isEqualNodes(node.prefix, other.prefix) && |
| isEqualTokens(node.period, other.period) && |
| isEqualNodes(node.identifier, other.identifier); |
| } |
| |
| @override |
| bool visitPrefixExpression(PrefixExpression node) { |
| PrefixExpression other = _other as PrefixExpression; |
| return isEqualTokens(node.operator, other.operator) && |
| isEqualNodes(node.operand, other.operand); |
| } |
| |
| @override |
| bool visitPropertyAccess(PropertyAccess node) { |
| PropertyAccess other = _other as PropertyAccess; |
| return isEqualNodes(node.target, other.target) && |
| isEqualTokens(node.operator, other.operator) && |
| isEqualNodes(node.propertyName, other.propertyName); |
| } |
| |
| @override |
| bool visitRecordLiteral(RecordLiteral node) { |
| var other = _other as RecordLiteral; |
| return isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| _isEqualNodeLists(node.fields, other.fields) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis); |
| } |
| |
| @override |
| bool visitRecordPattern(RecordPattern node) { |
| var other = _other as RecordPattern; |
| return isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| _isEqualNodeLists(node.fields, other.fields) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis); |
| } |
| |
| @override |
| bool visitRecordPatternField(RecordPatternField node) { |
| var other = _other as RecordPatternField; |
| return isEqualNodes(node.fieldName, other.fieldName) && |
| isEqualNodes(node.pattern, other.pattern); |
| } |
| |
| @override |
| bool visitRecordPatternFieldName(RecordPatternFieldName node) { |
| var other = _other as RecordPatternFieldName; |
| return isEqualTokens(node.name, other.name) && |
| isEqualTokens(node.colon, other.colon); |
| } |
| |
| @override |
| bool visitRecordTypeAnnotation(RecordTypeAnnotation node) { |
| var other = _other as RecordTypeAnnotation; |
| return _isEqualNodeLists(node.positionalFields, other.positionalFields) && |
| isEqualNodes(node.namedFields, other.namedFields) && |
| isEqualTokens(node.question, other.question); |
| } |
| |
| @override |
| bool visitRecordTypeAnnotationNamedField( |
| RecordTypeAnnotationNamedField node) { |
| var other = _other as RecordTypeAnnotationNamedField; |
| return _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.name, other.name) && |
| isEqualNodes(node.type, other.type); |
| } |
| |
| @override |
| bool visitRecordTypeAnnotationNamedFields( |
| RecordTypeAnnotationNamedFields node) { |
| var other = _other as RecordTypeAnnotationNamedFields; |
| return isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.fields, other.fields) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitRecordTypeAnnotationPositionalField( |
| RecordTypeAnnotationPositionalField node) { |
| var other = _other as RecordTypeAnnotationPositionalField; |
| return _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.name, other.name) && |
| isEqualNodes(node.type, other.type); |
| } |
| |
| @override |
| bool visitRedirectingConstructorInvocation( |
| RedirectingConstructorInvocation node) { |
| RedirectingConstructorInvocation other = |
| _other as RedirectingConstructorInvocation; |
| return isEqualTokens(node.thisKeyword, other.thisKeyword) && |
| isEqualTokens(node.period, other.period) && |
| isEqualNodes(node.constructorName, other.constructorName) && |
| isEqualNodes(node.argumentList, other.argumentList); |
| } |
| |
| @override |
| bool visitRelationalPattern(RelationalPattern node) { |
| var other = _other as RelationalPattern; |
| return isEqualTokens(node.operator, other.operator) && |
| isEqualNodes(node.operand, other.operand); |
| } |
| |
| @override |
| bool visitRethrowExpression(RethrowExpression node) { |
| RethrowExpression other = _other as RethrowExpression; |
| return isEqualTokens(node.rethrowKeyword, other.rethrowKeyword); |
| } |
| |
| @override |
| bool visitReturnStatement(ReturnStatement node) { |
| ReturnStatement other = _other as ReturnStatement; |
| return isEqualTokens(node.returnKeyword, other.returnKeyword) && |
| isEqualNodes(node.expression, other.expression) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitScriptTag(ScriptTag node) { |
| ScriptTag other = _other as ScriptTag; |
| return isEqualTokens(node.scriptTag, other.scriptTag); |
| } |
| |
| @override |
| bool visitSetOrMapLiteral(SetOrMapLiteral node) { |
| SetOrMapLiteral other = _other as SetOrMapLiteral; |
| return isEqualTokens(node.constKeyword, other.constKeyword) && |
| isEqualNodes(node.typeArguments, other.typeArguments) && |
| isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.elements, other.elements) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitShowClause(ShowClause node) { |
| ShowClause other = _other as ShowClause; |
| return isEqualTokens(node.showKeyword, other.showKeyword) && |
| _isEqualNodeLists(node.elements, other.elements); |
| } |
| |
| @override |
| bool visitShowCombinator(ShowCombinator node) { |
| ShowCombinator other = _other as ShowCombinator; |
| return isEqualTokens(node.keyword, other.keyword) && |
| _isEqualNodeLists(node.shownNames, other.shownNames); |
| } |
| |
| @override |
| bool visitShowHideElement(ShowHideElement node) { |
| ShowHideElement other = _other as ShowHideElement; |
| return isEqualTokens(node.modifier, other.modifier) && |
| isEqualNodes(node.name, other.name); |
| } |
| |
| @override |
| bool visitSimpleFormalParameter(SimpleFormalParameter node) { |
| SimpleFormalParameter other = _other as SimpleFormalParameter; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.keyword, other.keyword) && |
| isEqualNodes(node.type, other.type) && |
| isEqualTokens(node.name, other.name); |
| } |
| |
| @override |
| bool visitSimpleIdentifier(SimpleIdentifier node) { |
| SimpleIdentifier other = _other as SimpleIdentifier; |
| return isEqualTokens(node.token, other.token); |
| } |
| |
| @override |
| bool visitSimpleStringLiteral(SimpleStringLiteral node) { |
| SimpleStringLiteral other = _other as SimpleStringLiteral; |
| return isEqualTokens(node.literal, other.literal) && |
| failIfNotEqual(node, node.value, other, other.value); |
| } |
| |
| @override |
| bool visitSpreadElement(SpreadElement node) { |
| SpreadElement other = _other as SpreadElement; |
| return isEqualTokens(node.spreadOperator, other.spreadOperator) && |
| isEqualNodes(node.expression, other.expression); |
| } |
| |
| @override |
| bool visitStringInterpolation(StringInterpolation node) { |
| StringInterpolation other = _other as StringInterpolation; |
| return _isEqualNodeLists(node.elements, other.elements); |
| } |
| |
| @override |
| bool visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| SuperConstructorInvocation other = _other as SuperConstructorInvocation; |
| return isEqualTokens(node.superKeyword, other.superKeyword) && |
| isEqualTokens(node.period, other.period) && |
| isEqualNodes(node.constructorName, other.constructorName) && |
| isEqualNodes(node.argumentList, other.argumentList); |
| } |
| |
| @override |
| bool visitSuperExpression(SuperExpression node) { |
| SuperExpression other = _other as SuperExpression; |
| return isEqualTokens(node.superKeyword, other.superKeyword); |
| } |
| |
| @override |
| bool visitSuperFormalParameter(SuperFormalParameter node) { |
| SuperFormalParameter other = _other as SuperFormalParameter; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.keyword, other.keyword) && |
| isEqualNodes(node.type, other.type) && |
| isEqualTokens(node.superKeyword, other.superKeyword) && |
| isEqualTokens(node.period, other.period) && |
| isEqualTokens(node.name, other.name); |
| } |
| |
| @override |
| bool visitSwitchCase(SwitchCase node) { |
| SwitchCase other = _other as SwitchCase; |
| return _isEqualNodeLists(node.labels, other.labels) && |
| isEqualTokens(node.keyword, other.keyword) && |
| isEqualNodes(node.expression, other.expression) && |
| isEqualTokens(node.colon, other.colon) && |
| _isEqualNodeLists(node.statements, other.statements); |
| } |
| |
| @override |
| bool visitSwitchDefault(SwitchDefault node) { |
| SwitchDefault other = _other as SwitchDefault; |
| return _isEqualNodeLists(node.labels, other.labels) && |
| isEqualTokens(node.keyword, other.keyword) && |
| isEqualTokens(node.colon, other.colon) && |
| _isEqualNodeLists(node.statements, other.statements); |
| } |
| |
| @override |
| bool visitSwitchExpression(SwitchExpression node) { |
| var other = _other as SwitchExpression; |
| return isEqualTokens(node.switchKeyword, other.switchKeyword) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.expression, other.expression) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis) && |
| isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.members, other.members) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitSwitchExpressionCase(SwitchExpressionCase node) { |
| var other = _other as SwitchExpressionCase; |
| return isEqualTokens(node.keyword, other.keyword) && |
| isEqualNodes(node.pattern, other.pattern) && |
| isEqualNodes(node.whenClause, other.whenClause) && |
| isEqualTokens(node.arrow, other.arrow) && |
| isEqualNodes(node.expression, other.expression); |
| } |
| |
| @override |
| bool visitSwitchExpressionDefault(SwitchExpressionDefault node) { |
| var other = _other as SwitchExpressionDefault; |
| return isEqualTokens(node.keyword, other.keyword) && |
| isEqualTokens(node.arrow, other.arrow) && |
| isEqualNodes(node.expression, other.expression); |
| } |
| |
| @override |
| bool visitSwitchPatternCase(SwitchPatternCase node) { |
| var other = _other as SwitchPatternCase; |
| return _isEqualNodeLists(node.labels, other.labels) && |
| isEqualTokens(node.keyword, other.keyword) && |
| isEqualNodes(node.pattern, other.pattern) && |
| isEqualNodes(node.whenClause, other.whenClause) && |
| isEqualTokens(node.colon, other.colon) && |
| _isEqualNodeLists(node.statements, other.statements); |
| } |
| |
| @override |
| bool visitSwitchStatement(SwitchStatement node) { |
| SwitchStatement other = _other as SwitchStatement; |
| return isEqualTokens(node.switchKeyword, other.switchKeyword) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.expression, other.expression) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis) && |
| isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.members, other.members) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitSymbolLiteral(SymbolLiteral node) { |
| SymbolLiteral other = _other as SymbolLiteral; |
| return isEqualTokens(node.poundSign, other.poundSign) && |
| _isEqualTokenLists(node.components, other.components); |
| } |
| |
| @override |
| bool visitThisExpression(ThisExpression node) { |
| ThisExpression other = _other as ThisExpression; |
| return isEqualTokens(node.thisKeyword, other.thisKeyword); |
| } |
| |
| @override |
| bool visitThrowExpression(ThrowExpression node) { |
| ThrowExpression other = _other as ThrowExpression; |
| return isEqualTokens(node.throwKeyword, other.throwKeyword) && |
| isEqualNodes(node.expression, other.expression); |
| } |
| |
| @override |
| bool visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { |
| TopLevelVariableDeclaration other = _other as TopLevelVariableDeclaration; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.externalKeyword, other.externalKeyword) && |
| isEqualNodes(node.variables, other.variables) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitTryStatement(TryStatement node) { |
| TryStatement other = _other as TryStatement; |
| return isEqualTokens(node.tryKeyword, other.tryKeyword) && |
| isEqualNodes(node.body, other.body) && |
| _isEqualNodeLists(node.catchClauses, other.catchClauses) && |
| isEqualTokens(node.finallyKeyword, other.finallyKeyword) && |
| isEqualNodes(node.finallyBlock, other.finallyBlock); |
| } |
| |
| @override |
| bool visitTypeArgumentList(TypeArgumentList node) { |
| TypeArgumentList other = _other as TypeArgumentList; |
| return isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.arguments, other.arguments) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitTypeLiteral(TypeLiteral node) { |
| TypeLiteral other = _other as TypeLiteral; |
| return isEqualNodes(node.type, other.type); |
| } |
| |
| @override |
| bool visitTypeParameter(TypeParameter node) { |
| TypeParameter other = _other as TypeParameter; |
| // TODO (kallentu) : Clean up TypeParameterImpl casting once variance is |
| // added to the interface. |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.name, other.name) && |
| isEqualTokens((node as TypeParameterImpl).varianceKeyword, |
| (other as TypeParameterImpl).varianceKeyword) && |
| isEqualTokens(node.extendsKeyword, other.extendsKeyword) && |
| isEqualNodes(node.bound, other.bound); |
| } |
| |
| @override |
| bool visitTypeParameterList(TypeParameterList node) { |
| TypeParameterList other = _other as TypeParameterList; |
| return isEqualTokens(node.leftBracket, other.leftBracket) && |
| _isEqualNodeLists(node.typeParameters, other.typeParameters) && |
| isEqualTokens(node.rightBracket, other.rightBracket); |
| } |
| |
| @override |
| bool visitVariableDeclaration(VariableDeclaration node) { |
| VariableDeclaration other = _other as VariableDeclaration; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.name, other.name) && |
| isEqualTokens(node.equals, other.equals) && |
| isEqualNodes(node.initializer, other.initializer); |
| } |
| |
| @override |
| bool visitVariableDeclarationList(VariableDeclarationList node) { |
| VariableDeclarationList other = _other as VariableDeclarationList; |
| return isEqualNodes( |
| node.documentationComment, other.documentationComment) && |
| _isEqualNodeLists(node.metadata, other.metadata) && |
| isEqualTokens(node.keyword, other.keyword) && |
| isEqualNodes(node.type, other.type) && |
| _isEqualNodeLists(node.variables, other.variables); |
| } |
| |
| @override |
| bool visitVariableDeclarationStatement(VariableDeclarationStatement node) { |
| VariableDeclarationStatement other = _other as VariableDeclarationStatement; |
| return isEqualNodes(node.variables, other.variables) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| @override |
| bool visitVariablePattern(VariablePattern node) { |
| var other = _other as VariablePattern; |
| return isEqualNodes(node.type, other.type) && |
| isEqualTokens(node.name, other.name); |
| } |
| |
| @override |
| bool visitWhenClause(WhenClause node) { |
| var other = _other as WhenClause; |
| return isEqualTokens(node.whenKeyword, other.whenKeyword) && |
| isEqualNodes(node.expression, other.expression); |
| } |
| |
| @override |
| bool visitWhileStatement(WhileStatement node) { |
| WhileStatement other = _other as WhileStatement; |
| return isEqualTokens(node.whileKeyword, other.whileKeyword) && |
| isEqualTokens(node.leftParenthesis, other.leftParenthesis) && |
| isEqualNodes(node.condition, other.condition) && |
| isEqualTokens(node.rightParenthesis, other.rightParenthesis) && |
| isEqualNodes(node.body, other.body); |
| } |
| |
| @override |
| bool visitWithClause(WithClause node) { |
| WithClause other = _other as WithClause; |
| return isEqualTokens(node.withKeyword, other.withKeyword) && |
| _isEqualNodeLists(node.mixinTypes, other.mixinTypes); |
| } |
| |
| @override |
| bool visitYieldStatement(YieldStatement node) { |
| YieldStatement other = _other as YieldStatement; |
| return isEqualTokens(node.yieldKeyword, other.yieldKeyword) && |
| isEqualNodes(node.expression, other.expression) && |
| isEqualTokens(node.semicolon, other.semicolon); |
| } |
| |
| /// Return `true` if the [first] and [second] lists of AST nodes have the same |
| /// size and corresponding elements are equal. |
| bool _isEqualNodeLists(NodeList? first, NodeList? second) { |
| if (first == null) { |
| return failIfNotNull(first, second); |
| } else if (second == null) { |
| return failIsNull(first, second); |
| } |
| int size = first.length; |
| if (second.length != size) { |
| return failDifferentLength(first, second); |
| } |
| for (int i = 0; i < size; i++) { |
| if (!isEqualNodes(first[i], second[i])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| /// Return `true` if the [first] and [second] lists of tokens have the same |
| /// length and corresponding elements are equal. |
| bool _isEqualTokenLists(List<Token> first, List<Token> second) { |
| int length = first.length; |
| if (second.length != length) { |
| return failDifferentLength(first, second); |
| } |
| for (int i = 0; i < length; i++) { |
| if (!isEqualTokens(first[i], second[i])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| /// Return `true` if the [first] and [second] nodes are equal. |
| static bool equalNodes(AstNode first, AstNode second) { |
| AstComparator comparator = AstComparator(); |
| return comparator.isEqualNodes(first, second); |
| } |
| } |
| |
| /// A recursive AST visitor that is used to run over [Expression]s to determine |
| /// whether the expression is composed by at least one deferred |
| /// [PrefixedIdentifier]. |
| /// |
| /// See [PrefixedIdentifier.isDeferred]. |
| class DeferredLibraryReferenceDetector extends RecursiveAstVisitor<void> { |
| /// A flag indicating whether an identifier from a deferred library has been |
| /// found. |
| bool _result = false; |
| |
| /// Return `true` if the visitor found a [PrefixedIdentifier] that returned |
| /// `true` to the [PrefixedIdentifier.isDeferred] query. |
| bool get result => _result; |
| |
| @override |
| void visitPrefixedIdentifier(PrefixedIdentifier node) { |
| if (!_result) { |
| if (node.isDeferred) { |
| _result = true; |
| } |
| } |
| } |
| } |
| |
| /// Class capable of handling exceptions generated during linting. |
| /// |
| /// Clients may not extend, implement or mix-in this class. |
| class LinterExceptionHandler { |
| /// Indicates whether linter exceptions should be propagated to the caller (by |
| /// re-throwing them) |
| final bool propagateExceptions; |
| |
| LinterExceptionHandler({ |
| required this.propagateExceptions, |
| }); |
| |
| /// A method that can be passed to the `LinterVisitor` constructor to handle |
| /// exceptions that occur during linting. |
| /// |
| /// Returns `true` if the exception was fully handled, and `false` if the |
| /// exception should be rethrown. |
| bool logException( |
| AstNode node, Object visitor, dynamic exception, StackTrace stackTrace) { |
| StringBuffer buffer = StringBuffer(); |
| buffer.write('Exception while using a ${visitor.runtimeType} to visit a '); |
| AstNode? currentNode = node; |
| bool first = true; |
| while (currentNode != null) { |
| if (first) { |
| first = false; |
| } else { |
| buffer.write(' in '); |
| } |
| buffer.write(currentNode.runtimeType); |
| currentNode = currentNode.parent; |
| } |
| // TODO(39284): should this exception be silent? |
| AnalysisEngine.instance.instrumentationService.logException( |
| SilentException(buffer.toString(), exception, stackTrace)); |
| return !propagateExceptions; |
| } |
| } |
| |
| /// An object used to locate the [AstNode] associated with a source range, given |
| /// the AST structure built from the source. More specifically, they will return |
| /// the [AstNode] with the shortest length whose source range completely |
| /// encompasses the specified range with some exceptions: |
| /// |
| /// - Offsets that fall between the name and type/formal parameter list of a |
| /// declaration will return the declaration node and not the parameter list |
| /// node. |
| class NodeLocator extends UnifyingAstVisitor<void> { |
| /// The start offset of the range used to identify the node. |
| final int _startOffset; |
| |
| /// The end offset of the range used to identify the node. |
| final int _endOffset; |
| |
| /// The element that was found that corresponds to the given source range, or |
| /// `null` if there is no such element. |
| AstNode? _foundNode; |
| |
| /// Initialize a newly created locator to locate an [AstNode] by locating the |
| /// node within an AST structure that corresponds to the given range of |
| /// characters (between the [startOffset] and [endOffset] in the source. |
| NodeLocator(int startOffset, [int? endOffset]) |
| : _startOffset = startOffset, |
| _endOffset = endOffset ?? startOffset; |
| |
| /// Return the node that was found that corresponds to the given source range |
| /// or `null` if there is no such node. |
| AstNode? get foundNode => _foundNode; |
| |
| /// Search within the given AST [node] for an identifier representing an |
| /// element in the specified source range. Return the element that was found, |
| /// or `null` if no element was found. |
| AstNode? searchWithin(AstNode? node) { |
| if (node == null) { |
| return null; |
| } |
| try { |
| node.accept(this); |
| } catch (exception, stackTrace) { |
| // TODO(39284): should this exception be silent? |
| AnalysisEngine.instance.instrumentationService.logException( |
| SilentException( |
| "Unable to locate element at offset ($_startOffset - $_endOffset)", |
| exception, |
| stackTrace)); |
| return null; |
| } |
| |
| return _foundNode; |
| } |
| |
| @override |
| void visitConstructorDeclaration(ConstructorDeclaration node) { |
| // Names do not have AstNodes but offsets at the end should be treated as |
| // part of the decleration (not parameter list). |
| if (_startOffset == _endOffset && |
| _startOffset == (node.name ?? node.returnType).end) { |
| _foundNode = node; |
| return; |
| } |
| |
| super.visitConstructorDeclaration(node); |
| } |
| |
| @override |
| void visitFunctionDeclaration(FunctionDeclaration node) { |
| // Names do not have AstNodes but offsets at the end should be treated as |
| // part of the decleration (not parameter list). |
| if (_startOffset == _endOffset && _startOffset == node.name.end) { |
| _foundNode = node; |
| return; |
| } |
| |
| super.visitFunctionDeclaration(node); |
| } |
| |
| @override |
| void visitMethodDeclaration(MethodDeclaration node) { |
| // Names do not have AstNodes but offsets at the end should be treated as |
| // part of the decleration (not parameter list). |
| if (_startOffset == _endOffset && _startOffset == node.name.end) { |
| _foundNode = node; |
| return; |
| } |
| |
| super.visitMethodDeclaration(node); |
| } |
| |
| @override |
| void visitNode(AstNode node) { |
| // Don't visit a new tree if the result has been already found. |
| if (_foundNode != null) { |
| return; |
| } |
| // Check whether the current node covers the selection. |
| Token beginToken = node.beginToken; |
| Token endToken = node.endToken; |
| // Don't include synthetic tokens. |
| while (endToken != beginToken) { |
| // Fasta scanner reports unterminated string literal errors |
| // and generates a synthetic string token with non-zero length. |
| // Because of this, check for length > 0 rather than !isSynthetic. |
| if (endToken.isEof || endToken.length > 0) { |
| break; |
| } |
| endToken = endToken.previous!; |
| } |
| int end = endToken.end; |
| int start = node.offset; |
| if (end < _startOffset || start > _endOffset) { |
| return; |
| } |
| // Check children. |
| try { |
| node.visitChildren(this); |
| } catch (exception, stackTrace) { |
| // Ignore the exception and proceed in order to visit the rest of the |
| // structure. |
| // TODO(39284): should this exception be silent? |
| AnalysisEngine.instance.instrumentationService.logException( |
| SilentException("Exception caught while traversing an AST structure.", |
| exception, stackTrace)); |
| } |
| // Found a child. |
| if (_foundNode != null) { |
| return; |
| } |
| // Check this node. |
| if (start <= _startOffset && _endOffset <= end) { |
| _foundNode = node; |
| } |
| } |
| } |
| |
| /// An object used to locate the [AstNode] associated with a source range. |
| /// More specifically, they will return the deepest [AstNode] which completely |
| /// encompasses the specified range with some exceptions: |
| /// |
| /// - Offsets that fall between the name and type/formal parameter list of a |
| /// declaration will return the declaration node and not the parameter list |
| /// node. |
| class NodeLocator2 extends UnifyingAstVisitor<void> { |
| /// The inclusive start offset of the range used to identify the node. |
| final int _startOffset; |
| |
| /// The inclusive end offset of the range used to identify the node. |
| final int _endOffset; |
| |
| /// The found node or `null` if there is no such node. |
| AstNode? _foundNode; |
| |
| /// Initialize a newly created locator to locate the deepest [AstNode] for |
| /// which `node.offset <= [startOffset]` and `[endOffset] < node.end`. |
| /// |
| /// If [endOffset] is not provided, then it is considered the same as the |
| /// given [startOffset]. |
| NodeLocator2(int startOffset, [int? endOffset]) |
| : _startOffset = startOffset, |
| _endOffset = endOffset ?? startOffset; |
| |
| /// Search within the given AST [node] and return the node that was found, |
| /// or `null` if no node was found. |
| AstNode? searchWithin(AstNode? node) { |
| if (node == null) { |
| return null; |
| } |
| try { |
| node.accept(this); |
| } catch (exception, stackTrace) { |
| // TODO(39284): should this exception be silent? |
| AnalysisEngine.instance.instrumentationService |
| .logException(SilentException( |
| 'Unable to locate element at offset ' |
| '($_startOffset - $_endOffset)', |
| exception, |
| stackTrace)); |
| return null; |
| } |
| return _foundNode; |
| } |
| |
| @override |
| void visitConstructorDeclaration(ConstructorDeclaration node) { |
| // Names do not have AstNodes but offsets at the end should be treated as |
| // part of the decleration (not parameter list). |
| if (_startOffset == _endOffset && |
| _startOffset == (node.name ?? node.returnType).end) { |
| _foundNode = node; |
| return; |
| } |
| |
| super.visitConstructorDeclaration(node); |
| } |
| |
| @override |
| void visitFunctionDeclaration(FunctionDeclaration node) { |
| // Names do not have AstNodes but offsets at the end should be treated as |
| // part of the decleration (not parameter list). |
| if (_startOffset == _endOffset && _startOffset == node.name.end) { |
| _foundNode = node; |
| return; |
| } |
| |
| super.visitFunctionDeclaration(node); |
| } |
| |
| @override |
| void visitMethodDeclaration(MethodDeclaration node) { |
| // Names do not have AstNodes but offsets at the end should be treated as |
| // part of the decleration (not parameter list). |
| if (_startOffset == _endOffset && _startOffset == node.name.end) { |
| _foundNode = node; |
| return; |
| } |
| |
| super.visitMethodDeclaration(node); |
| } |
| |
| @override |
| void visitNode(AstNode node) { |
| // Don't visit a new tree if the result has been already found. |
| if (_foundNode != null) { |
| return; |
| } |
| // Check whether the current node covers the selection. |
| Token beginToken = node.beginToken; |
| Token endToken = node.endToken; |
| // Don't include synthetic tokens. |
| while (endToken != beginToken) { |
| // Fasta scanner reports unterminated string literal errors |
| // and generates a synthetic string token with non-zero length. |
| // Because of this, check for length > 0 rather than !isSynthetic. |
| if (endToken.isEof || endToken.length > 0) { |
| break; |
| } |
| endToken = endToken.previous!; |
| } |
| int end = endToken.end; |
| int start = node.offset; |
| if (end <= _startOffset || start > _endOffset) { |
| return; |
| } |
| // Check children. |
| try { |
| node.visitChildren(this); |
| } catch (exception, stackTrace) { |
| // Ignore the exception and proceed in order to visit the rest of the |
| // structure. |
| // TODO(39284): should this exception be silent? |
| AnalysisEngine.instance.instrumentationService.logException( |
| SilentException("Exception caught while traversing an AST structure.", |
| exception, stackTrace)); |
| } |
| // Found a child. |
| if (_foundNode != null) { |
| return; |
| } |
| // Check this node. |
| if (start <= _startOffset && _endOffset < end) { |
| _foundNode = node; |
| } |
| } |
| } |
| |
| /// An object that will replace one child node in an AST node with another node. |
| class NodeReplacer extends ThrowingAstVisitor<bool> { |
| /// The node being replaced. |
| final AstNode _oldNode; |
| |
| /// The node that is replacing the old node. |
| final AstNode _newNode; |
| |
| /// Initialize a newly created node locator to replace the [_oldNode] with the |
| /// [_newNode]. |
| NodeReplacer._(this._oldNode, this._newNode); |
| |
| @override |
| bool visitAdjacentStrings(covariant AdjacentStringsImpl node) { |
| if (_replaceInList(node.strings)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| bool visitAnnotatedNode(covariant AnnotatedNodeImpl node) { |
| if (identical(node.documentationComment, _oldNode)) { |
| node.documentationComment = _newNode as Comment; |
| return true; |
| } else if (_replaceInList(node.metadata)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitAnnotation(covariant AnnotationImpl node) { |
| if (identical(node.arguments, _oldNode)) { |
| node.arguments = _newNode as ArgumentList; |
| return true; |
| } else if (identical(node.typeArguments, _oldNode)) { |
| node.typeArguments = _newNode as TypeArgumentList?; |
| return true; |
| } else if (identical(node.constructorName, _oldNode)) { |
| node.constructorName = _newNode as SimpleIdentifier; |
| return true; |
| } else if (identical(node.name, _oldNode)) { |
| node.name = _newNode as Identifier; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitArgumentList(covariant ArgumentListImpl node) { |
| if (_replaceInList(node.arguments)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitAsExpression(covariant AsExpressionImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } else if (identical(node.type, _oldNode)) { |
| node.type = _newNode as TypeAnnotation; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitAssertInitializer(covariant AssertInitializerImpl node) { |
| if (identical(node.condition, _oldNode)) { |
| node.condition = _newNode as Expression; |
| return true; |
| } |
| if (identical(node.message, _oldNode)) { |
| node.message = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitAssertStatement(covariant AssertStatementImpl node) { |
| if (identical(node.condition, _oldNode)) { |
| node.condition = _newNode as Expression; |
| return true; |
| } |
| if (identical(node.message, _oldNode)) { |
| node.message = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitAssignmentExpression(covariant AssignmentExpressionImpl node) { |
| if (identical(node.leftHandSide, _oldNode)) { |
| node.leftHandSide = _newNode as Expression; |
| return true; |
| } else if (identical(node.rightHandSide, _oldNode)) { |
| node.rightHandSide = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitAugmentationImportDirective( |
| covariant AugmentationImportDirectiveImpl node, |
| ) { |
| return visitUriBasedDirective(node); |
| } |
| |
| @override |
| bool visitAwaitExpression(covariant AwaitExpressionImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitBinaryExpression(covariant BinaryExpressionImpl node) { |
| if (identical(node.leftOperand, _oldNode)) { |
| node.leftOperand = _newNode as ExpressionImpl; |
| return true; |
| } else if (identical(node.rightOperand, _oldNode)) { |
| node.rightOperand = _newNode as ExpressionImpl; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitBlock(covariant BlockImpl node) { |
| if (_replaceInList(node.statements)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitBlockFunctionBody(covariant BlockFunctionBodyImpl node) { |
| if (identical(node.block, _oldNode)) { |
| node.block = _newNode as Block; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitBooleanLiteral(BooleanLiteral node) => visitNode(node); |
| |
| @override |
| bool visitBreakStatement(covariant BreakStatementImpl node) { |
| if (identical(node.label, _oldNode)) { |
| node.label = _newNode as SimpleIdentifier; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitCascadeExpression(covariant CascadeExpressionImpl node) { |
| if (identical(node.target, _oldNode)) { |
| node.target = _newNode as Expression; |
| return true; |
| } else if (_replaceInList(node.cascadeSections)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitCatchClause(covariant CatchClauseImpl node) { |
| if (identical(node.exceptionType, _oldNode)) { |
| node.exceptionType = _newNode as TypeAnnotation; |
| return true; |
| } else if (identical(node.exceptionParameter, _oldNode)) { |
| node.exceptionParameter = _newNode as CatchClauseParameterImpl; |
| return true; |
| } else if (identical(node.stackTraceParameter, _oldNode)) { |
| node.stackTraceParameter = _newNode as CatchClauseParameterImpl; |
| return true; |
| } else if (identical(node.body, _oldNode)) { |
| node.body = _newNode as Block; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool? visitCatchClauseParameter(CatchClauseParameter node) { |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitClassDeclaration(covariant ClassDeclarationImpl node) { |
| if (identical(node.typeParameters, _oldNode)) { |
| node.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } else if (identical(node.extendsClause, _oldNode)) { |
| node.extendsClause = _newNode as ExtendsClause; |
| return true; |
| } else if (identical(node.withClause, _oldNode)) { |
| node.withClause = _newNode as WithClause; |
| return true; |
| } else if (identical(node.implementsClause, _oldNode)) { |
| node.implementsClause = _newNode as ImplementsClause; |
| return true; |
| } else if (identical(node.nativeClause, _oldNode)) { |
| node.nativeClause = _newNode as NativeClause; |
| return true; |
| } else if (_replaceInList(node.members)) { |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitClassTypeAlias(covariant ClassTypeAliasImpl node) { |
| if (identical(node.typeParameters, _oldNode)) { |
| node.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } else if (identical(node.superclass, _oldNode)) { |
| node.superclass = _newNode as NamedType; |
| return true; |
| } else if (identical(node.withClause, _oldNode)) { |
| node.withClause = _newNode as WithClause; |
| return true; |
| } else if (identical(node.implementsClause, _oldNode)) { |
| node.implementsClause = _newNode as ImplementsClause; |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitComment(covariant CommentImpl node) { |
| if (_replaceInList(node.references)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitCommentReference(covariant CommentReferenceImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Identifier; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitCompilationUnit(covariant CompilationUnitImpl node) { |
| if (identical(node.scriptTag, _oldNode)) { |
| node.scriptTag = _newNode as ScriptTag; |
| return true; |
| } else if (_replaceInList(node.directives)) { |
| return true; |
| } else if (_replaceInList(node.declarations)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitConditionalExpression(covariant ConditionalExpressionImpl node) { |
| if (identical(node.condition, _oldNode)) { |
| node.condition = _newNode as Expression; |
| return true; |
| } else if (identical(node.thenExpression, _oldNode)) { |
| node.thenExpression = _newNode as Expression; |
| return true; |
| } else if (identical(node.elseExpression, _oldNode)) { |
| node.elseExpression = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitConfiguration(covariant ConfigurationImpl node) { |
| if (identical(node.name, _oldNode)) { |
| node.name = _newNode as DottedName; |
| return true; |
| } else if (identical(node.value, _oldNode)) { |
| node.value = _newNode as StringLiteral; |
| return true; |
| } else if (identical(node.uri, _oldNode)) { |
| node.uri = _newNode as StringLiteral; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitConstantPattern(covariant ConstantPatternImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as ExpressionImpl; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitConstructorDeclaration(covariant ConstructorDeclarationImpl node) { |
| if (identical(node.returnType, _oldNode)) { |
| node.returnType = _newNode as Identifier; |
| return true; |
| } else if (identical(node.parameters, _oldNode)) { |
| node.parameters = _newNode as FormalParameterList; |
| return true; |
| } else if (identical(node.redirectedConstructor, _oldNode)) { |
| node.redirectedConstructor = _newNode as ConstructorName; |
| return true; |
| } else if (identical(node.body, _oldNode)) { |
| node.body = _newNode as FunctionBody; |
| return true; |
| } else if (_replaceInList(node.initializers)) { |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitConstructorFieldInitializer( |
| covariant ConstructorFieldInitializerImpl node) { |
| if (identical(node.fieldName, _oldNode)) { |
| node.fieldName = _newNode as SimpleIdentifier; |
| return true; |
| } else if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitConstructorName(covariant ConstructorNameImpl node) { |
| if (identical(node.type, _oldNode)) { |
| node.type = _newNode as NamedType; |
| return true; |
| } else if (identical(node.name, _oldNode)) { |
| node.name = _newNode as SimpleIdentifier; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitConstructorReference(covariant ConstructorReferenceImpl node) { |
| if (identical(node.constructorName, _oldNode)) { |
| node.constructorName = _newNode as ConstructorNameImpl; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitConstructorSelector(ConstructorSelector node) { |
| throw UnimplementedError(); |
| } |
| |
| @override |
| bool visitContinueStatement(covariant ContinueStatementImpl node) { |
| if (identical(node.label, _oldNode)) { |
| node.label = _newNode as SimpleIdentifier; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitDeclaredIdentifier(covariant DeclaredIdentifierImpl node) { |
| if (identical(node.type, _oldNode)) { |
| node.type = _newNode as TypeAnnotation; |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitDefaultFormalParameter(covariant DefaultFormalParameterImpl node) { |
| if (identical(node.parameter, _oldNode)) { |
| node.parameter = _newNode as NormalFormalParameter; |
| return true; |
| } else if (identical(node.defaultValue, _oldNode)) { |
| node.defaultValue = _newNode as Expression; |
| var parameterElement = node.declaredElement; |
| if (parameterElement is DefaultParameterElementImpl) { |
| parameterElement.constantInitializer = _newNode as Expression; |
| } else if (parameterElement is DefaultFieldFormalParameterElementImpl) { |
| parameterElement.constantInitializer = _newNode as Expression; |
| } |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitDoStatement(covariant DoStatementImpl node) { |
| if (identical(node.body, _oldNode)) { |
| node.body = _newNode as Statement; |
| return true; |
| } else if (identical(node.condition, _oldNode)) { |
| node.condition = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitDottedName(covariant DottedNameImpl node) { |
| if (_replaceInList(node.components)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitDoubleLiteral(DoubleLiteral node) => visitNode(node); |
| |
| @override |
| bool visitEmptyFunctionBody(EmptyFunctionBody node) => visitNode(node); |
| |
| @override |
| bool visitEmptyStatement(EmptyStatement node) => visitNode(node); |
| |
| @override |
| bool visitEnumConstantArguments(EnumConstantArguments node) { |
| throw UnimplementedError(); |
| } |
| |
| @override |
| bool visitEnumConstantDeclaration( |
| covariant EnumConstantDeclarationImpl node) { |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitEnumDeclaration(covariant EnumDeclarationImpl node) { |
| if (identical(node.typeParameters, _oldNode)) { |
| node.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } else if (identical(node.withClause, _oldNode)) { |
| node.withClause = _newNode as WithClause; |
| return true; |
| } else if (identical(node.implementsClause, _oldNode)) { |
| node.implementsClause = _newNode as ImplementsClause; |
| return true; |
| } else if (_replaceInList(node.constants)) { |
| return true; |
| } else if (_replaceInList(node.members)) { |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitExportDirective(covariant ExportDirectiveImpl node) => |
| visitNamespaceDirective(node); |
| |
| @override |
| bool visitExpressionFunctionBody(covariant ExpressionFunctionBodyImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitExpressionStatement(covariant ExpressionStatementImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitExtendsClause(covariant ExtendsClauseImpl node) { |
| if (identical(node.superclass, _oldNode)) { |
| node.superclass = _newNode as NamedType; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitExtensionDeclaration(covariant ExtensionDeclarationImpl node) { |
| if (identical(node.documentationComment, _oldNode)) { |
| node.documentationComment = _newNode as Comment; |
| return true; |
| } else if (_replaceInList(node.metadata)) { |
| return true; |
| } else if (identical(node.typeParameters, _oldNode)) { |
| node.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } else if (identical(node.extendedType, _oldNode)) { |
| node.extendedType = _newNode as TypeAnnotation; |
| return true; |
| } else if (_replaceInList(node.members)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitExtensionOverride(ExtensionOverride node) { |
| if (identical(node.extensionName, _oldNode)) { |
| (node as ExtensionOverrideImpl).extensionName = _newNode as Identifier; |
| return true; |
| } else if (identical(node.typeArguments, _oldNode)) { |
| (node as ExtensionOverrideImpl).typeArguments = |
| _newNode as TypeArgumentList; |
| return true; |
| } else if (identical(node.argumentList, _oldNode)) { |
| (node as ExtensionOverrideImpl).argumentList = _newNode as ArgumentList; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitFieldDeclaration(covariant FieldDeclarationImpl node) { |
| if (identical(node.fields, _oldNode)) { |
| node.fields = _newNode as VariableDeclarationList; |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitFieldFormalParameter(covariant FieldFormalParameterImpl node) { |
| if (identical(node.type, _oldNode)) { |
| node.type = _newNode as TypeAnnotation; |
| return true; |
| } else if (identical(node.typeParameters, _oldNode)) { |
| node.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } else if (identical(node.parameters, _oldNode)) { |
| node.parameters = _newNode as FormalParameterList; |
| return true; |
| } |
| return visitNormalFormalParameter(node); |
| } |
| |
| @override |
| bool visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) { |
| if (identical(node.loopVariable, _oldNode)) { |
| (node as ForEachPartsWithDeclarationImpl).loopVariable = |
| _newNode as DeclaredIdentifier; |
| return true; |
| } else if (identical(node.iterable, _oldNode)) { |
| (node as ForEachPartsWithDeclarationImpl).iterable = |
| _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) { |
| if (identical(node.identifier, _oldNode)) { |
| (node as ForEachPartsWithIdentifierImpl).identifier = |
| _newNode as SimpleIdentifier; |
| return true; |
| } else if (identical(node.iterable, _oldNode)) { |
| (node as ForEachPartsWithIdentifierImpl).iterable = |
| _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitForElement(ForElement node) { |
| if (identical(node.forLoopParts, _oldNode)) { |
| (node as ForElementImpl).forLoopParts = _newNode as ForLoopParts; |
| return true; |
| } else if (identical(node.body, _oldNode)) { |
| (node as ForElementImpl).body = _newNode as CollectionElement; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitFormalParameterList(covariant FormalParameterListImpl node) { |
| if (_replaceInList(node.parameters)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitForPartsWithDeclarations( |
| covariant ForPartsWithDeclarationsImpl node) { |
| if (identical(node.variables, _oldNode)) { |
| node.variables = _newNode as VariableDeclarationList; |
| return true; |
| } else if (identical(node.condition, _oldNode)) { |
| node.condition = _newNode as Expression; |
| return true; |
| } else if (_replaceInList(node.updaters)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitForPartsWithExpression(covariant ForPartsWithExpressionImpl node) { |
| if (identical(node.initialization, _oldNode)) { |
| node.initialization = _newNode as Expression; |
| return true; |
| } else if (identical(node.condition, _oldNode)) { |
| node.condition = _newNode as Expression; |
| return true; |
| } else if (_replaceInList(node.updaters)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitForStatement(ForStatement node) { |
| if (identical(node.forLoopParts, _oldNode)) { |
| (node as ForStatementImpl).forLoopParts = _newNode as ForLoopParts; |
| return true; |
| } else if (identical(node.body, _oldNode)) { |
| (node as ForStatementImpl).body = _newNode as Statement; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitFunctionDeclaration(covariant FunctionDeclarationImpl node) { |
| if (identical(node.returnType, _oldNode)) { |
| node.returnType = _newNode as TypeAnnotation; |
| return true; |
| } else if (identical(node.functionExpression, _oldNode)) { |
| node.functionExpression = _newNode as FunctionExpression; |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitFunctionDeclarationStatement( |
| covariant FunctionDeclarationStatementImpl node) { |
| if (identical(node.functionDeclaration, _oldNode)) { |
| node.functionDeclaration = _newNode as FunctionDeclaration; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitFunctionExpression(covariant FunctionExpressionImpl node) { |
| if (identical(node.parameters, _oldNode)) { |
| node.parameters = _newNode as FormalParameterList; |
| return true; |
| } else if (identical(node.typeParameters, _oldNode)) { |
| node.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } else if (identical(node.body, _oldNode)) { |
| node.body = _newNode as FunctionBody; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitFunctionExpressionInvocation( |
| covariant FunctionExpressionInvocationImpl node) { |
| if (identical(node.function, _oldNode)) { |
| node.function = _newNode as Expression; |
| return true; |
| } else if (identical(node.argumentList, _oldNode)) { |
| node.argumentList = _newNode as ArgumentList; |
| return true; |
| } else if (identical(node.typeArguments, _oldNode)) { |
| node.typeArguments = _newNode as TypeArgumentList; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitFunctionReference(covariant FunctionReferenceImpl node) { |
| if (identical(node.function, _oldNode)) { |
| node.function = _newNode as ExpressionImpl; |
| return true; |
| } else if (identical(node.typeArguments, _oldNode)) { |
| node.typeArguments = _newNode as TypeArgumentListImpl; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitFunctionTypeAlias(covariant FunctionTypeAliasImpl node) { |
| if (identical(node.returnType, _oldNode)) { |
| node.returnType = _newNode as TypeAnnotation; |
| return true; |
| } else if (identical(node.typeParameters, _oldNode)) { |
| node.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } else if (identical(node.parameters, _oldNode)) { |
| node.parameters = _newNode as FormalParameterList; |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitFunctionTypedFormalParameter( |
| covariant FunctionTypedFormalParameterImpl node) { |
| if (identical(node.returnType, _oldNode)) { |
| node.returnType = _newNode as TypeAnnotation; |
| return true; |
| } else if (identical(node.parameters, _oldNode)) { |
| node.parameters = _newNode as FormalParameterList; |
| return true; |
| } else if (identical(node.typeParameters, _oldNode)) { |
| node.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } |
| return visitNormalFormalParameter(node); |
| } |
| |
| @override |
| bool? visitGenericFunctionType(covariant GenericFunctionTypeImpl node) { |
| if (identical(node.returnType, _oldNode)) { |
| node.returnType = _newNode as TypeAnnotation; |
| return true; |
| } else if (identical(node.typeParameters, _oldNode)) { |
| node.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } else if (identical(node.parameters, _oldNode)) { |
| node.parameters = _newNode as FormalParameterList; |
| return true; |
| } |
| return null; |
| } |
| |
| @override |
| bool visitGenericTypeAlias(GenericTypeAlias node) { |
| var nodeImpl = node as GenericTypeAliasImpl; |
| if (identical(node.typeParameters, _oldNode)) { |
| nodeImpl.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } else if (identical(node.type, _oldNode)) { |
| nodeImpl.type = _newNode as TypeAnnotation; |
| return true; |
| } else if (_replaceInList(node.metadata)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitHideClause(covariant HideClauseImpl node) { |
| if (_replaceInList(node.elements)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitHideCombinator(covariant HideCombinatorImpl node) { |
| if (_replaceInList(node.hiddenNames)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitIfElement(IfElement node) { |
| if (identical(node.condition, _oldNode)) { |
| (node as IfElementImpl).condition = _newNode as Expression; |
| return true; |
| } else if (identical(node.thenElement, _oldNode)) { |
| (node as IfElementImpl).thenElement = _newNode as CollectionElement; |
| return true; |
| } else if (identical(node.elseElement, _oldNode)) { |
| (node as IfElementImpl).elseElement = _newNode as CollectionElement; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitIfStatement(covariant IfStatementImpl node) { |
| if (identical(node.condition, _oldNode)) { |
| node.condition = _newNode as Expression; |
| return true; |
| } else if (identical(node.thenStatement, _oldNode)) { |
| node.thenStatement = _newNode as Statement; |
| return true; |
| } else if (identical(node.elseStatement, _oldNode)) { |
| node.elseStatement = _newNode as Statement; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitImplementsClause(covariant ImplementsClauseImpl node) { |
| if (_replaceInList(node.interfaces)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitImplicitCallReference(covariant ImplicitCallReferenceImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as ExpressionImpl; |
| return true; |
| } else if (identical(node.typeArguments, _oldNode)) { |
| node.typeArguments = _newNode as TypeArgumentListImpl; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitImportDirective(covariant ImportDirectiveImpl node) { |
| if (identical(node.prefix, _oldNode)) { |
| node.prefix = _newNode as SimpleIdentifier; |
| return true; |
| } |
| return visitNamespaceDirective(node); |
| } |
| |
| @override |
| bool visitIndexExpression(covariant IndexExpressionImpl node) { |
| if (identical(node.target, _oldNode)) { |
| node.target = _newNode as Expression; |
| return true; |
| } else if (identical(node.index, _oldNode)) { |
| node.index = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitInstanceCreationExpression( |
| covariant InstanceCreationExpressionImpl node) { |
| if (identical(node.constructorName, _oldNode)) { |
| node.constructorName = _newNode as ConstructorName; |
| return true; |
| } else if (identical(node.argumentList, _oldNode)) { |
| node.argumentList = _newNode as ArgumentList; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitIntegerLiteral(IntegerLiteral node) => visitNode(node); |
| |
| @override |
| bool visitInterpolationExpression( |
| covariant InterpolationExpressionImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitInterpolationString(InterpolationString node) => visitNode(node); |
| |
| @override |
| bool visitIsExpression(covariant IsExpressionImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } else if (identical(node.type, _oldNode)) { |
| node.type = _newNode as TypeAnnotation; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitLabel(covariant LabelImpl node) { |
| if (identical(node.label, _oldNode)) { |
| node.label = _newNode as SimpleIdentifier; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitLabeledStatement(covariant LabeledStatementImpl node) { |
| if (identical(node.statement, _oldNode)) { |
| node.statement = _newNode as Statement; |
| return true; |
| } else if (_replaceInList(node.labels)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool? visitLibraryAugmentationDirective( |
| covariant LibraryAugmentationDirectiveImpl node, |
| ) { |
| return visitUriBasedDirective(node); |
| } |
| |
| @override |
| bool visitLibraryDirective(covariant LibraryDirectiveImpl node) { |
| if (identical(node.name2, _oldNode)) { |
| node.name = _newNode as LibraryIdentifier; |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitLibraryIdentifier(covariant LibraryIdentifierImpl node) { |
| if (_replaceInList(node.components)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitListLiteral(covariant ListLiteralImpl node) { |
| if (_replaceInList(node.elements)) { |
| return true; |
| } |
| return visitTypedLiteral(node); |
| } |
| |
| @override |
| bool visitMapLiteralEntry(covariant MapLiteralEntryImpl node) { |
| if (identical(node.key, _oldNode)) { |
| node.key = _newNode as Expression; |
| return true; |
| } else if (identical(node.value, _oldNode)) { |
| node.value = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitMethodDeclaration(covariant MethodDeclarationImpl node) { |
| if (identical(node.returnType, _oldNode)) { |
| node.returnType = _newNode as TypeAnnotation; |
| return true; |
| } else if (identical(node.parameters, _oldNode)) { |
| node.parameters = _newNode as FormalParameterList; |
| return true; |
| } else if (identical(node.typeParameters, _oldNode)) { |
| node.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } else if (identical(node.body, _oldNode)) { |
| node.body = _newNode as FunctionBody; |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitMethodInvocation(covariant MethodInvocationImpl node) { |
| if (identical(node.target, _oldNode)) { |
| node.target = _newNode as Expression; |
| return true; |
| } else if (identical(node.methodName, _oldNode)) { |
| node.methodName = _newNode as SimpleIdentifier; |
| return true; |
| } else if (identical(node.argumentList, _oldNode)) { |
| node.argumentList = _newNode as ArgumentList; |
| return true; |
| } else if (identical(node.typeArguments, _oldNode)) { |
| node.typeArguments = _newNode as TypeArgumentList; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitMixinDeclaration(covariant MixinDeclarationImpl node) { |
| if (identical(node.documentationComment, _oldNode)) { |
| node.documentationComment = _newNode as Comment; |
| return true; |
| } else if (_replaceInList(node.metadata)) { |
| return true; |
| } else if (identical(node.typeParameters, _oldNode)) { |
| node.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } else if (identical(node.onClause, _oldNode)) { |
| node.onClause = _newNode as OnClause; |
| return true; |
| } else if (identical(node.implementsClause, _oldNode)) { |
| node.implementsClause = _newNode as ImplementsClause; |
| return true; |
| } else if (_replaceInList(node.members)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitNamedExpression(covariant NamedExpressionImpl node) { |
| if (identical(node.name, _oldNode)) { |
| node.name = _newNode as Label; |
| return true; |
| } else if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool? visitNamedType(covariant NamedTypeImpl node) { |
| if (identical(node.name, _oldNode)) { |
| node.name = _newNode as Identifier; |
| return true; |
| } else if (identical(node.typeArguments, _oldNode)) { |
| node.typeArguments = _newNode as TypeArgumentList; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| bool visitNamespaceDirective(covariant NamespaceDirectiveImpl node) { |
| if (_replaceInList(node.combinators)) { |
| return true; |
| } |
| return visitUriBasedDirective(node); |
| } |
| |
| @override |
| bool visitNativeFunctionBody(covariant NativeFunctionBodyImpl node) { |
| if (identical(node.stringLiteral, _oldNode)) { |
| node.stringLiteral = _newNode as StringLiteral; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| bool visitNode(AstNode node) { |
| throw ArgumentError("The old node is not a child of it's parent"); |
| } |
| |
| bool visitNormalFormalParameter(covariant NormalFormalParameterImpl node) { |
| if (identical(node.documentationComment, _oldNode)) { |
| node.documentationComment = _newNode as Comment; |
| return true; |
| } else if (_replaceInList(node.metadata)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitNullLiteral(NullLiteral node) => visitNode(node); |
| |
| @override |
| bool visitOnClause(covariant OnClauseImpl node) { |
| if (_replaceInList(node.superclassConstraints)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitParenthesizedExpression( |
| covariant ParenthesizedExpressionImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitPartDirective(covariant PartDirectiveImpl node) => |
| visitUriBasedDirective(node); |
| |
| @override |
| bool visitPartOfDirective(covariant PartOfDirectiveImpl node) { |
| if (identical(node.libraryName, _oldNode)) { |
| node.libraryName = _newNode as LibraryIdentifier; |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitPostfixExpression(covariant PostfixExpressionImpl node) { |
| if (identical(node.operand, _oldNode)) { |
| node.operand = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitPrefixedIdentifier(covariant PrefixedIdentifierImpl node) { |
| if (identical(node.prefix, _oldNode)) { |
| node.prefix = _newNode as SimpleIdentifier; |
| return true; |
| } else if (identical(node.identifier, _oldNode)) { |
| node.identifier = _newNode as SimpleIdentifier; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitPrefixExpression(covariant PrefixExpressionImpl node) { |
| if (identical(node.operand, _oldNode)) { |
| node.operand = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitPropertyAccess(covariant PropertyAccessImpl node) { |
| if (identical(node.target, _oldNode)) { |
| node.target = _newNode as Expression; |
| return true; |
| } else if (identical(node.propertyName, _oldNode)) { |
| node.propertyName = _newNode as SimpleIdentifier; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitRecordLiteral(covariant RecordLiteralImpl node) { |
| if (_replaceInList(node.fields)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitRecordTypeAnnotation(RecordTypeAnnotation node) { |
| if (_replaceInList(node.positionalFields)) { |
| return true; |
| } else if (identical(node.namedFields, _oldNode)) { |
| // node.namedFields = _newNode as RecordTypeAnnotationNamedFields; |
| throw UnimplementedError(); |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitRecordTypeAnnotationNamedField( |
| RecordTypeAnnotationNamedField node) { |
| if (_replaceInList(node.metadata)) { |
| return true; |
| } else if (identical(node.type, _oldNode)) { |
| // node.type = _newNode as TypeAnnotation; |
| throw UnimplementedError(); |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitRecordTypeAnnotationNamedFields( |
| RecordTypeAnnotationNamedFields node) { |
| if (_replaceInList(node.fields)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitRecordTypeAnnotationPositionalField( |
| RecordTypeAnnotationPositionalField node) { |
| if (_replaceInList(node.metadata)) { |
| return true; |
| } else if (identical(node.type, _oldNode)) { |
| // node.type = _newNode as TypeAnnotation; |
| throw UnimplementedError(); |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitRedirectingConstructorInvocation( |
| covariant RedirectingConstructorInvocationImpl node) { |
| if (identical(node.constructorName, _oldNode)) { |
| node.constructorName = _newNode as SimpleIdentifier; |
| return true; |
| } else if (identical(node.argumentList, _oldNode)) { |
| node.argumentList = _newNode as ArgumentList; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool? visitRelationalPattern(covariant RelationalPatternImpl node) { |
| if (identical(node.operand, _oldNode)) { |
| node.operand = _newNode as ExpressionImpl; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitRethrowExpression(RethrowExpression node) => visitNode(node); |
| |
| @override |
| bool visitReturnStatement(covariant ReturnStatementImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitScriptTag(ScriptTag scriptTag) => visitNode(scriptTag); |
| |
| @override |
| bool visitSetOrMapLiteral(covariant SetOrMapLiteralImpl node) { |
| if (_replaceInList(node.elements)) { |
| return true; |
| } |
| return visitTypedLiteral(node); |
| } |
| |
| @override |
| bool visitShowClause(covariant ShowClauseImpl node) { |
| if (_replaceInList(node.elements)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitShowCombinator(covariant ShowCombinatorImpl node) { |
| if (_replaceInList(node.shownNames)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitShowHideElement(covariant ShowHideElementImpl node) { |
| if (identical(node.name, _oldNode)) { |
| node.name = _newNode as SimpleIdentifier; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitSimpleFormalParameter(covariant SimpleFormalParameterImpl node) { |
| if (identical(node.type, _oldNode)) { |
| node.type = _newNode as TypeAnnotation; |
| return true; |
| } |
| return visitNormalFormalParameter(node); |
| } |
| |
| @override |
| bool visitSimpleIdentifier(SimpleIdentifier node) => visitNode(node); |
| |
| @override |
| bool visitSimpleStringLiteral(SimpleStringLiteral node) => visitNode(node); |
| |
| @override |
| bool visitSpreadElement(SpreadElement node) { |
| if (identical(node.expression, _oldNode)) { |
| (node as SpreadElementImpl).expression = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitStringInterpolation(covariant StringInterpolationImpl node) { |
| if (_replaceInList(node.elements)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitSuperConstructorInvocation( |
| covariant SuperConstructorInvocationImpl node) { |
| if (identical(node.constructorName, _oldNode)) { |
| node.constructorName = _newNode as SimpleIdentifier; |
| return true; |
| } else if (identical(node.argumentList, _oldNode)) { |
| node.argumentList = _newNode as ArgumentList; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitSuperExpression(covariant SuperExpressionImpl node) => |
| visitNode(node); |
| |
| @override |
| bool visitSuperFormalParameter(covariant SuperFormalParameterImpl node) { |
| if (identical(node.type, _oldNode)) { |
| node.type = _newNode as TypeAnnotation; |
| return true; |
| } else if (identical(node.typeParameters, _oldNode)) { |
| node.typeParameters = _newNode as TypeParameterList; |
| return true; |
| } else if (identical(node.parameters, _oldNode)) { |
| node.parameters = _newNode as FormalParameterList; |
| return true; |
| } |
| return visitNormalFormalParameter(node); |
| } |
| |
| @override |
| bool visitSwitchCase(covariant SwitchCaseImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } |
| return visitSwitchMember(node); |
| } |
| |
| @override |
| bool visitSwitchDefault(covariant SwitchDefaultImpl node) => |
| visitSwitchMember(node); |
| |
| bool visitSwitchMember(covariant SwitchMemberImpl node) { |
| if (_replaceInList(node.labels)) { |
| return true; |
| } else if (_replaceInList(node.statements)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitSwitchStatement(covariant SwitchStatementImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } else if (_replaceInList(node.members)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitSymbolLiteral(SymbolLiteral node) => visitNode(node); |
| |
| @override |
| bool visitThisExpression(ThisExpression node) => visitNode(node); |
| |
| @override |
| bool visitThrowExpression(covariant ThrowExpressionImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitTopLevelVariableDeclaration( |
| covariant TopLevelVariableDeclarationImpl node) { |
| if (identical(node.variables, _oldNode)) { |
| node.variables = _newNode as VariableDeclarationList; |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitTryStatement(covariant TryStatementImpl node) { |
| if (identical(node.body, _oldNode)) { |
| node.body = _newNode as Block; |
| return true; |
| } else if (identical(node.finallyBlock, _oldNode)) { |
| node.finallyBlock = _newNode as Block; |
| return true; |
| } else if (_replaceInList(node.catchClauses)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitTypeArgumentList(covariant TypeArgumentListImpl node) { |
| if (_replaceInList(node.arguments)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| bool visitTypedLiteral(covariant TypedLiteralImpl node) { |
| if (identical(node.typeArguments, _oldNode)) { |
| node.typeArguments = _newNode as TypeArgumentList; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitTypeLiteral(covariant TypeLiteralImpl node) { |
| if (identical(node.type, _oldNode)) { |
| node.typeName = _newNode as NamedTypeImpl; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitTypeParameter(covariant TypeParameterImpl node) { |
| if (identical(node.bound, _oldNode)) { |
| node.bound = _newNode as TypeAnnotation; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitTypeParameterList(covariant TypeParameterListImpl node) { |
| if (_replaceInList(node.typeParameters)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| bool visitUriBasedDirective(covariant UriBasedDirectiveImpl node) { |
| if (identical(node.uri, _oldNode)) { |
| node.uri = _newNode as StringLiteral; |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitVariableDeclaration(covariant VariableDeclarationImpl node) { |
| if (identical(node.initializer, _oldNode)) { |
| node.initializer = _newNode as Expression; |
| return true; |
| // TODO(srawlins) also replace node's declared element's |
| // `constantInitializer`, if the element is [ConstFieldElementImpl], |
| // [ConstLocalVariableElementImpl], or [ConstTopLevelVariableElementImpl]. |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitVariableDeclarationList( |
| covariant VariableDeclarationListImpl node) { |
| if (identical(node.type, _oldNode)) { |
| node.type = _newNode as TypeAnnotation; |
| return true; |
| } else if (_replaceInList(node.variables)) { |
| return true; |
| } |
| return visitAnnotatedNode(node); |
| } |
| |
| @override |
| bool visitVariableDeclarationStatement( |
| covariant VariableDeclarationStatementImpl node) { |
| if (identical(node.variables, _oldNode)) { |
| node.variables = _newNode as VariableDeclarationList; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitWhileStatement(covariant WhileStatementImpl node) { |
| if (identical(node.condition, _oldNode)) { |
| node.condition = _newNode as Expression; |
| return true; |
| } else if (identical(node.body, _oldNode)) { |
| node.body = _newNode as Statement; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitWithClause(covariant WithClauseImpl node) { |
| if (_replaceInList(node.mixinTypes)) { |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| @override |
| bool visitYieldStatement(covariant YieldStatementImpl node) { |
| if (identical(node.expression, _oldNode)) { |
| node.expression = _newNode as Expression; |
| return true; |
| } |
| return visitNode(node); |
| } |
| |
| bool _replaceInList(NodeList list) { |
| int count = list.length; |
| for (int i = 0; i < count; i++) { |
| if (identical(_oldNode, list[i])) { |
| list[i] = _newNode; |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /// Replace the [oldNode] with the [newNode] in the AST structure containing |
| /// the old node. Return `true` if the replacement was successful. |
| /// |
| /// Throws an [ArgumentError] if either node is `null`, if the old node does |
| /// not have a parent node, or if the AST structure has been corrupted. |
| /// |
| /// If [newNode] is the parent of [oldNode] already (because [newNode] became |
| /// the parent of [oldNode] in its constructor), this action will loop |
| /// infinitely; pass [oldNode]'s previous parent as [parent] to avoid this. |
| static bool replace(AstNode oldNode, AstNode newNode, {AstNode? parent}) { |
| if (identical(oldNode, newNode)) { |
| return true; |
| } |
| parent ??= oldNode.parent; |
| if (parent == null) { |
| throw ArgumentError("The old node is not a child of another node"); |
| } |
| NodeReplacer replacer = NodeReplacer._(oldNode, newNode); |
| return parent.accept(replacer)!; |
| } |
| } |
| |
| /// Traverse the AST from initial child node to successive parents, building a |
| /// collection of local variable and parameter names visible to the initial |
| /// child node. In case of name shadowing, the first name seen is the most |
| /// specific one so names are not redefined. |
| /// |
| /// Completion test code coverage is 95%. The two basic blocks that are not |
| /// executed cannot be executed. They are included for future reference. |
| class ScopedNameFinder extends GeneralizingAstVisitor<void> { |
| Declaration? _declarationNode; |
| |
| AstNode? _immediateChild; |
| |
| final Set<String> _locals = {}; |
| |
| final int _position; |
| |
| bool _referenceIsWithinLocalFunction = false; |
| |
| ScopedNameFinder(this._position); |
| |
| Declaration? get declaration => _declarationNode; |
| |
| Set<String> get locals => _locals; |
| |
| @override |
| void visitBlock(Block node) { |
| _checkStatements(node.statements); |
| super.visitBlock(node); |
| } |
| |
| @override |
| void visitCatchClause(CatchClause node) { |
| _addToScope(node.exceptionParameter?.name); |
| _addToScope(node.stackTraceParameter?.name); |
| super.visitCatchClause(node); |
| } |
| |
| @override |
| void visitConstructorDeclaration(ConstructorDeclaration node) { |
| if (!identical(_immediateChild, node.parameters)) { |
| _addParameters(node.parameters.parameters); |
| } |
| _declarationNode = node; |
| } |
| |
| @override |
| void visitFieldDeclaration(FieldDeclaration node) { |
| _declarationNode = node; |
| } |
| |
| @override |
| void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) { |
| _addToScope(node.loopVariable.name); |
| super.visitForEachPartsWithDeclaration(node); |
| } |
| |
| @override |
| void visitForPartsWithDeclarations(ForPartsWithDeclarations node) { |
| _addVariables(node.variables.variables); |
| super.visitForPartsWithDeclarations(node); |
| } |
| |
| @override |
| void visitFunctionDeclaration(FunctionDeclaration node) { |
| if (node.parent is! FunctionDeclarationStatement) { |
| _declarationNode = node; |
| } else { |
| super.visitFunctionDeclaration(node); |
| } |
| } |
| |
| @override |
| void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) { |
| _referenceIsWithinLocalFunction = true; |
| super.visitFunctionDeclarationStatement(node); |
| } |
| |
| @override |
| void visitFunctionExpression(FunctionExpression node) { |
| var parameters = node.parameters; |
| if (parameters != null && !identical(_immediateChild, parameters)) { |
| _addParameters(parameters.parameters); |
| } |
| super.visitFunctionExpression(node); |
| } |
| |
| @override |
| void visitMethodDeclaration(MethodDeclaration node) { |
| _declarationNode = node; |
| var parameters = node.parameters; |
| if (parameters != null && !identical(_immediateChild, parameters)) { |
| _addParameters(parameters.parameters); |
| } |
| } |
| |
| @override |
| void visitNode(AstNode node) { |
| _immediateChild = node; |
| node.parent?.accept(this); |
| } |
| |
| @override |
| void visitSwitchMember(SwitchMember node) { |
| _checkStatements(node.statements); |
| super.visitSwitchMember(node); |
| } |
| |
| @override |
| void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { |
| _declarationNode = node; |
| } |
| |
| @override |
| void visitTypeAlias(TypeAlias node) { |
| _declarationNode = node; |
| } |
| |
| void _addParameters(NodeList<FormalParameter> vars) { |
| for (FormalParameter var2 in vars) { |
| _addToScope(var2.name); |
| } |
| } |
| |
| void _addToScope(Token? identifier) { |
| if (identifier != null && _isInRange(identifier)) { |
| _locals.add(identifier.lexeme); |
| } |
| } |
| |
| void _addVariables(NodeList<VariableDeclaration> variables) { |
| for (VariableDeclaration variable in variables) { |
| _addToScope(variable.name); |
| } |
| } |
| |
| /// Check the given list of [statements] for any that come before the |
| /// immediate child and that define a name that would be visible to the |
| /// immediate child. |
| void _checkStatements(List<Statement> statements) { |
| for (Statement statement in statements) { |
| if (identical(statement, _immediateChild)) { |
| return; |
| } |
| if (statement is VariableDeclarationStatement) { |
| _addVariables(statement.variables.variables); |
| } else if (statement is FunctionDeclarationStatement && |
| !_referenceIsWithinLocalFunction) { |
| _addToScope(statement.functionDeclaration.name); |
| } |
| } |
| } |
| |
| bool _isInRange(Token token) { |
| if (_position < 0) { |
| // if source position is not set then all nodes are in range |
| return true; |
| // not reached |
| } |
| return token.end < _position; |
| } |
| } |