Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Unified Diff: pkg/compiler/lib/src/serialization/equivalence.dart

Issue 1884583002: Add structural equivalence test for AST nodes. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/serialization/equivalence.dart
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
index be28121447478a00f77bd9d59506b7b5bb9cae63..6e7fc9c0a717f1a71b19e870d5fa8485679c1e82 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -17,6 +17,7 @@ import '../tokens/token.dart';
import '../tree/nodes.dart';
import '../universe/selector.dart';
import '../universe/use.dart';
+import '../util/util.dart';
import 'resolved_ast_serialization.dart';
/// Equality based equivalence function.
@@ -637,13 +638,8 @@ bool testResolvedAstEquivalence(
[TestStrategy strategy = const TestStrategy()]) {
return strategy.testElements(resolvedAst1, resolvedAst2, 'element',
resolvedAst1.element, resolvedAst2.element) &&
- // Compute AST equivalence by structural comparison.
- strategy.test(
- resolvedAst1,
- resolvedAst2,
- 'node',
- resolvedAst1.node.toDebugString(),
- resolvedAst2.node.toDebugString()) &&
+ new NodeEquivalenceVisitor(strategy).testNodes(resolvedAst1, resolvedAst2,
+ 'node', resolvedAst1.node, resolvedAst2.node) &&
testTreeElementsEquivalence(resolvedAst1, resolvedAst2, strategy);
}
@@ -805,3 +801,709 @@ class TreeElementsEquivalenceVisitor extends Visitor {
elements2.getRedirectingTargetConstructor(node2));
}
}
+
+class NodeEquivalenceVisitor implements Visitor1<bool, Node> {
+ final TestStrategy strategy;
+
+ const NodeEquivalenceVisitor([this.strategy = const TestStrategy()]);
+
+ bool testNodes(
+ var object1, var object2, String property, Node node1, Node node2) {
Siggi Cherem (dart-lang) 2016/04/12 17:36:06 do you need `property`? seems unused in all test*
Johnni Winther 2016/04/13 07:34:02 These were meant for the CheckStrategy. I'll leave
+ if (node1 == node2) return true;
+ if (node1 == null || node2 == null) return false;
+ return node1.accept1(this, node2);
+ }
+
+ bool testNodeLists(var object1, var object2, String property,
+ Link<Node> list1, Link<Node> list2) {
+ if (list1 == list2) return true;
+ if (list1 == null || list2 == null) return false;
+ while (list1.isNotEmpty && list2.isNotEmpty) {
+ if (!list1.head.accept1(this, list2.head)) {
+ return false;
+ }
+ list1 = list1.tail;
+ list2 = list2.tail;
+ }
+ return list1.isEmpty && list2.isEmpty;
+ }
+
+ bool testTokens(
+ var object1, var object2, String property, Token token1, Token token2) {
+ if (token1 == token2) return true;
+ if (token1 == null || token2 == null) return false;
+ return token1.hashCode == token2.hashCode;
+ }
+
+ @override
+ bool visitAssert(Assert node1, Assert node2) {
+ return testTokens(node1, node2, 'assertToken', node1.assertToken,
+ node2.assertToken) &&
+ testNodes(
+ node1, node2, 'condition', node1.condition, node2.condition) &&
+ testNodes(node1, node2, 'message', node1.message, node2.message);
+ }
+
+ @override
+ bool visitAsyncForIn(AsyncForIn node1, AsyncForIn node2) {
+ return visitForIn(node1, node2) &&
+ testTokens(
+ node1, node2, 'awaitToken', node1.awaitToken, node2.awaitToken);
+ }
+
+ @override
+ bool visitAsyncModifier(AsyncModifier node1, AsyncModifier node2) {
+ return testTokens(
+ node1, node2, 'asyncToken', node1.asyncToken, node2.asyncToken) &&
+ testTokens(node1, node2, 'starToken', node1.starToken, node2.starToken);
+ }
+
+ @override
+ bool visitAwait(Await node1, Await node2) {
+ return testTokens(
+ node1, node2, 'awaitToken', node1.awaitToken, node2.awaitToken) &&
+ testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression);
+ }
+
+ @override
+ bool visitBlock(Block node1, Block node2) {
+ return testNodes(
+ node1, node2, 'statements', node1.statements, node2.statements);
+ }
+
+ @override
+ bool visitBreakStatement(BreakStatement node1, BreakStatement node2) {
+ return testTokens(node1, node2, 'keywordToken', node1.keywordToken,
+ node2.keywordToken) &&
+ testNodes(node1, node2, 'target', node1.target, node2.target);
+ }
+
+ @override
+ bool visitCascade(Cascade node1, Cascade node2) {
+ return testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression);
+ }
+
+ @override
+ bool visitCascadeReceiver(CascadeReceiver node1, CascadeReceiver node2) {
+ return testTokens(node1, node2, 'cascadeOperator', node1.cascadeOperator,
+ node2.cascadeOperator) &&
+ testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression);
+ }
+
+ @override
+ bool visitCaseMatch(CaseMatch node1, CaseMatch node2) {
+ return testTokens(node1, node2, 'caseKeyword', node1.caseKeyword,
+ node2.caseKeyword) &&
+ testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression);
+ }
+
+ @override
+ bool visitCatchBlock(CatchBlock node1, CatchBlock node2) {
+ return testTokens(node1, node2, 'catchKeyword', node1.catchKeyword,
+ node2.catchKeyword) &&
+ testTokens(
+ node1, node2, 'onKeyword', node1.onKeyword, node2.onKeyword) &&
+ testNodes(node1, node2, 'type', node1.type, node2.type) &&
+ testNodes(node1, node2, 'formals', node1.formals, node2.formals) &&
+ testNodes(node1, node2, 'block', node1.block, node2.block);
+ }
+
+ @override
+ bool visitClassNode(ClassNode node1, ClassNode node2) {
+ return testTokens(
+ node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
+ testTokens(node1, node2, 'extendsKeyword', node1.extendsKeyword,
+ node2.extendsKeyword) &&
+ testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
+ testNodes(
+ node1, node2, 'modifiers', node1.modifiers, node2.modifiers) &&
+ testNodes(node1, node2, 'name', node1.name, node2.name) &&
+ testNodes(
+ node1, node2, 'superclass', node1.superclass, node2.superclass) &&
+ testNodes(
+ node1, node2, 'interfaces', node1.interfaces, node2.interfaces) &&
+ testNodes(node1, node2, 'typeParameters', node1.typeParameters,
+ node2.typeParameters) &&
+ testNodes(node1, node2, 'body', node1.body, node2.body);
+ }
+
+ @override
+ bool visitCombinator(Combinator node1, Combinator node2) {
+ return testTokens(node1, node2, 'keywordToken', node1.keywordToken,
+ node2.keywordToken) &&
+ testNodes(
+ node1, node2, 'identifiers', node1.identifiers, node2.identifiers);
+ }
+
+ @override
+ bool visitConditional(Conditional node1, Conditional node2) {
+ return testTokens(node1, node2, 'questionToken', node1.questionToken,
+ node2.questionToken) &&
+ testTokens(
+ node1, node2, 'colonToken', node1.colonToken, node2.colonToken) &&
+ testNodes(
+ node1, node2, 'condition', node1.condition, node2.condition) &&
+ testNodes(node1, node2, 'thenExpression', node1.thenExpression,
+ node2.thenExpression) &&
+ testNodes(node1, node2, 'elseExpression', node1.elseExpression,
+ node2.elseExpression);
+ }
+
+ @override
+ bool visitConditionalUri(ConditionalUri node1, ConditionalUri node2) {
+ return testTokens(node1, node2, 'ifToken', node1.ifToken, node2.ifToken) &&
+ testNodes(node1, node2, 'key', node1.key, node2.key) &&
+ testNodes(node1, node2, 'value', node1.value, node2.value) &&
+ testNodes(node1, node2, 'uri', node1.uri, node2.uri);
+ }
+
+ @override
+ bool visitContinueStatement(
+ ContinueStatement node1, ContinueStatement node2) {
+ return testTokens(node1, node2, 'keywordToken', node1.keywordToken,
+ node2.keywordToken) &&
+ testNodes(node1, node2, 'target', node1.target, node2.target);
+ }
+
+ @override
+ bool visitDoWhile(DoWhile node1, DoWhile node2) {
+ return testTokens(
+ node1, node2, 'doKeyword', node1.doKeyword, node2.doKeyword) &&
+ testTokens(node1, node2, 'whileKeyword', node1.whileKeyword,
+ node2.whileKeyword) &&
+ testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
+ testNodes(
+ node1, node2, 'condition', node1.condition, node2.condition) &&
+ testNodes(node1, node2, 'body', node1.body, node2.body);
+ }
+
+ @override
+ bool visitDottedName(DottedName node1, DottedName node2) {
+ return testTokens(node1, node2, 'token', node1.token, node2.token) &&
+ testNodes(
+ node1, node2, 'identifiers', node1.identifiers, node2.identifiers);
+ }
+
+ @override
+ bool visitEmptyStatement(EmptyStatement node1, EmptyStatement node2) {
+ return testTokens(node1, node2, 'semicolonToken', node1.semicolonToken,
+ node2.semicolonToken);
+ }
+
+ @override
+ bool visitEnum(Enum node1, Enum node2) {
+ return testTokens(
+ node1, node2, 'enumToken', node1.enumToken, node2.enumToken) &&
+ testNodes(node1, node2, 'name', node1.name, node2.name) &&
+ testNodes(node1, node2, 'names', node1.names, node2.names);
+ }
+
+ @override
+ bool visitExport(Export node1, Export node2) {
+ return visitLibraryDependency(node1, node2) &&
+ testTokens(node1, node2, 'exportKeyword', node1.exportKeyword,
+ node2.exportKeyword);
+ }
+
+ @override
+ bool visitExpressionStatement(
+ ExpressionStatement node1, ExpressionStatement node2) {
+ return testTokens(
+ node1, node2, 'endToken', node1.endToken, node2.endToken) &&
+ testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression);
+ }
+
+ @override
+ bool visitFor(For node1, For node2) {
+ return testTokens(
+ node1, node2, 'forToken', node1.forToken, node2.forToken) &&
+ testNodes(node1, node2, 'initializer', node1.initializer,
+ node2.initializer) &&
+ testNodes(node1, node2, 'conditionStatement', node1.conditionStatement,
+ node2.conditionStatement) &&
+ testNodes(node1, node2, 'update', node1.update, node2.update) &&
+ testNodes(node1, node2, 'body', node1.body, node2.body);
+ }
+
+ @override
+ bool visitForIn(ForIn node1, ForIn node2) {
+ return testNodes(
+ node1, node2, 'condition', node1.condition, node2.condition) &&
+ testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression) &&
+ testNodes(node1, node2, 'body', node1.expression, node2.body) &&
+ testNodes(node1, node2, 'declaredIdentifier', node1.declaredIdentifier,
+ node2.declaredIdentifier);
+ }
+
+ @override
+ bool visitFunctionDeclaration(
+ FunctionDeclaration node1, FunctionDeclaration node2) {
+ return testNodes(node1, node2, 'function', node1.function, node2.function);
+ }
+
+ @override
+ bool visitFunctionExpression(
+ FunctionExpression node1, FunctionExpression node2) {
+ return testTokens(
+ node1, node2, 'getOrSet', node1.getOrSet, node2.getOrSet) &&
+ testNodes(node1, node2, 'name', node1.name, node2.name) &&
+ testNodes(
+ node1, node2, 'parameters', node1.parameters, node2.parameters) &&
+ testNodes(node1, node2, 'body', node1.body, node2.body) &&
+ testNodes(
+ node1, node2, 'returnType', node1.returnType, node2.returnType) &&
+ testNodes(
+ node1, node2, 'modifiers', node1.modifiers, node2.modifiers) &&
+ testNodes(node1, node2, 'initializers', node1.initializers,
+ node2.initializers) &&
+ testNodes(node1, node2, 'asyncModifier', node1.asyncModifier,
+ node2.asyncModifier);
+ }
+
+ @override
+ bool visitGotoStatement(GotoStatement node1, GotoStatement node2) {
+ return testTokens(node1, node2, 'keywordToken', node1.keywordToken,
+ node2.keywordToken) &&
+ testTokens(node1, node2, 'semicolonToken', node1.semicolonToken,
+ node2.semicolonToken) &&
+ testNodes(node1, node2, 'target', node1.target, node2.target);
+ }
+
+ @override
+ bool visitIdentifier(Identifier node1, Identifier node2) {
+ return testTokens(node1, node2, 'token', node1.token, node2.token);
+ }
+
+ @override
+ bool visitIf(If node1, If node2) {
+ return testTokens(node1, node2, 'ifToken', node1.ifToken, node2.ifToken) &&
+ testTokens(
+ node1, node2, 'elseToken', node1.elseToken, node2.elseToken) &&
+ testNodes(
+ node1, node2, 'condition', node1.condition, node2.condition) &&
+ testNodes(node1, node2, 'thenPart', node1.thenPart, node2.thenPart) &&
+ testNodes(node1, node2, 'elsePart', node1.elsePart, node2.elsePart);
+ }
+
+ @override
+ bool visitImport(Import node1, Import node2) {
+ return visitLibraryDependency(node1, node2) &&
+ testTokens(node1, node2, 'importKeyword', node1.importKeyword,
+ node2.importKeyword) &&
+ testNodes(node1, node2, 'prefix', node1.prefix, node2.prefix) &&
+ strategy.test(
+ node1, node2, 'isDeferred', node1.isDeferred, node2.isDeferred);
+ }
+
+ @override
+ bool visitLabel(Label node1, Label node2) {
+ return testTokens(
+ node1, node2, 'colonToken', node1.colonToken, node2.colonToken) &&
+ testNodes(
+ node1, node2, 'identifier', node1.identifier, node2.identifier);
+ }
+
+ @override
+ bool visitLabeledStatement(LabeledStatement node1, LabeledStatement node2) {
+ return testNodes(node1, node2, 'labels', node1.labels, node2.labels) &&
+ testNodes(node1, node2, 'statement', node1.statement, node2.statement);
+ }
+
+ @override
+ bool visitLibraryDependency(
+ LibraryDependency node1, LibraryDependency node2) {
+ return visitLibraryTag(node1, node2) &&
+ testNodes(node1, node2, 'uri', node1.uri, node2.uri) &&
+ testNodes(node1, node2, 'conditionalUris', node1.conditionalUris,
+ node2.conditionalUris) &&
+ testNodes(
+ node1, node2, 'combinators', node1.combinators, node2.combinators);
+ }
+
+ @override
+ bool visitLibraryName(LibraryName node1, LibraryName node2) {
+ return visitLibraryTag(node1, node2) &&
+ testTokens(node1, node2, 'libraryKeyword', node1.libraryKeyword,
+ node2.libraryKeyword) &&
+ testNodes(node1, node2, 'name', node1.name, node2.name);
+ }
+
+ @override
+ bool visitLibraryTag(LibraryTag node1, LibraryTag node2) {
+ // TODO(johnniwinther): Check metadata?
+ return true;
+ }
+
+ @override
+ bool visitLiteral(Literal node1, Literal node2) {
+ return testTokens(node1, node2, 'token', node1.token, node2.token);
+ }
+
+ @override
+ bool visitLiteralBool(LiteralBool node1, LiteralBool node2) {
+ return visitLiteral(node1, node2);
+ }
+
+ @override
+ bool visitLiteralDouble(LiteralDouble node1, LiteralDouble node2) {
+ return visitLiteral(node1, node2);
+ }
+
+ @override
+ bool visitLiteralInt(LiteralInt node1, LiteralInt node2) {
+ return visitLiteral(node1, node2);
+ }
+
+ @override
+ bool visitLiteralList(LiteralList node1, LiteralList node2) {
+ return testTokens(node1, node2, 'constKeyword', node1.constKeyword,
+ node2.constKeyword) &&
+ testNodes(node1, node2, 'typeArguments', node1.typeArguments,
+ node2.typeArguments) &&
+ testNodes(node1, node2, 'elements', node1.elements, node2.elements);
+ }
+
+ @override
+ bool visitLiteralMap(LiteralMap node1, LiteralMap node2) {
+ return testTokens(node1, node2, 'constKeyword', node1.constKeyword,
+ node2.constKeyword) &&
+ testNodes(node1, node2, 'typeArguments', node1.typeArguments,
+ node2.typeArguments) &&
+ testNodes(node1, node2, 'entries', node1.entries, node2.entries);
+ }
+
+ @override
+ bool visitLiteralMapEntry(LiteralMapEntry node1, LiteralMapEntry node2) {
+ return testTokens(
+ node1, node2, 'colonToken', node1.colonToken, node2.colonToken) &&
+ testNodes(node1, node2, 'key', node1.key, node2.key) &&
+ testNodes(node1, node2, 'value', node1.value, node2.value);
+ }
+
+ @override
+ bool visitLiteralNull(LiteralNull node1, LiteralNull node2) {
+ return visitLiteral(node1, node2);
+ }
+
+ @override
+ bool visitLiteralString(LiteralString node1, LiteralString node2) {
+ return testTokens(node1, node2, 'token', node1.token, node2.token) &&
+ strategy.test(
+ node1, node2, 'dartString', node1.dartString, node2.dartString);
+ }
+
+ @override
+ bool visitLiteralSymbol(LiteralSymbol node1, LiteralSymbol node2) {
+ return testTokens(
+ node1, node2, 'hashToken', node1.hashToken, node2.hashToken) &&
+ testNodes(
+ node1, node2, 'identifiers', node1.identifiers, node2.identifiers);
+ }
+
+ @override
+ bool visitLoop(Loop node1, Loop node2) {
+ return testNodes(
+ node1, node2, 'condition', node1.condition, node2.condition) &&
+ testNodes(node1, node2, 'body', node1.body, node2.body);
+ }
+
+ @override
+ bool visitMetadata(Metadata node1, Metadata node2) {
+ return testTokens(node1, node2, 'token', node1.token, node2.token) &&
+ testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression);
+ }
+
+ @override
+ bool visitMixinApplication(MixinApplication node1, MixinApplication node2) {
+ return testNodes(
+ node1, node2, 'superclass', node1.superclass, node2.superclass) &&
+ testNodes(node1, node2, 'mixins', node1.mixins, node2.mixins);
+ }
+
+ @override
+ bool visitModifiers(Modifiers node1, Modifiers node2) {
+ return strategy.test(node1, node2, 'flags', node1.flags, node2.flags) &&
+ testNodes(node1, node2, 'nodes', node1.nodes, node2.nodes);
+ }
+
+ @override
+ bool visitNamedArgument(NamedArgument node1, NamedArgument node2) {
+ return testTokens(
+ node1, node2, 'colonToken', node1.colonToken, node2.colonToken) &&
+ testNodes(node1, node2, 'name', node1.name, node2.name) &&
+ testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression);
+ }
+
+ @override
+ bool visitNamedMixinApplication(
+ NamedMixinApplication node1, NamedMixinApplication node2) {
+ return testTokens(node1, node2, 'classKeyword', node1.classKeyword,
+ node2.classKeyword) &&
+ testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
+ testNodes(node1, node2, 'name', node1.name, node2.name) &&
+ testNodes(node1, node2, 'typeParameters', node1.typeParameters,
+ node2.typeParameters) &&
+ testNodes(
+ node1, node2, 'modifiers', node1.modifiers, node2.modifiers) &&
+ testNodes(node1, node2, 'mixinApplication', node1.mixinApplication,
+ node2.mixinApplication) &&
+ testNodes(
+ node1, node2, 'interfaces', node1.interfaces, node2.interfaces);
+ }
+
+ @override
+ bool visitNewExpression(NewExpression node1, NewExpression node2) {
+ return testTokens(
+ node1, node2, 'newToken', node1.newToken, node2.newToken) &&
+ testNodes(node1, node2, 'send', node1.send, node2.send);
+ }
+
+ @override
+ bool visitNodeList(NodeList node1, NodeList node2) {
+ return testTokens(
+ node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
+ testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
+ strategy.test(
+ node1, node2, 'delimiter', node1.delimiter, node2.delimiter) &&
+ testNodeLists(node1, node2, 'nodes', node1.nodes, node2.nodes);
+ }
+
+ @override
+ bool visitOperator(Operator node1, Operator node2) {
+ return visitIdentifier(node1, node2);
+ }
+
+ @override
+ bool visitParenthesizedExpression(
+ ParenthesizedExpression node1, ParenthesizedExpression node2) {
+ return testTokens(
+ node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
+ testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression);
+ }
+
+ @override
+ bool visitPart(Part node1, Part node2) {
+ return visitLibraryTag(node1, node2) &&
+ testTokens(node1, node2, 'partKeyword', node1.partKeyword,
+ node2.partKeyword) &&
+ testNodes(node1, node2, 'uri', node1.uri, node2.uri);
+ }
+
+ @override
+ bool visitPartOf(PartOf node1, PartOf node2) {
+ // TODO(johnniwinther): Check metadata?
+ return testTokens(node1, node2, 'partKeyword', node1.partKeyword,
+ node2.partKeyword) &&
+ testNodes(node1, node2, 'name', node1.name, node2.name);
+ }
+
+ @override
+ bool visitPostfix(Postfix node1, Postfix node2) {
+ return visitNodeList(node1, node2);
+ }
+
+ @override
+ bool visitPrefix(Prefix node1, Prefix node2) {
+ return visitNodeList(node1, node2);
+ }
+
+ @override
+ bool visitRedirectingFactoryBody(
+ RedirectingFactoryBody node1, RedirectingFactoryBody node2) {
+ return testTokens(
+ node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
+ testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
+ testNodes(node1, node2, 'constructorReference',
+ node1.constructorReference, node2.constructorReference);
+ }
+
+ @override
+ bool visitRethrow(Rethrow node1, Rethrow node2) {
+ return testTokens(
+ node1, node2, 'throwToken', node1.throwToken, node2.throwToken) &&
+ testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken);
+ }
+
+ @override
+ bool visitReturn(Return node1, Return node2) {
+ return testTokens(
+ node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
+ testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
+ testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression);
+ }
+
+ @override
+ bool visitSend(Send node1, Send node2) {
+ return strategy.test(node1, node2, 'isConditional', node1.isConditional,
+ node2.isConditional) &&
+ testNodes(node1, node2, 'receiver', node1.receiver, node2.receiver) &&
+ testNodes(node1, node2, 'selector', node1.selector, node2.selector) &&
+ testNodes(node1, node2, 'argumentsNode', node1.argumentsNode,
+ node2.argumentsNode);
+ }
+
+ @override
+ bool visitSendSet(SendSet node1, SendSet node2) {
+ return visitSend(node1, node2) &&
+ testNodes(node1, node2, 'assignmentOperator', node1.assignmentOperator,
+ node2.assignmentOperator);
+ }
+
+ @override
+ bool visitStringInterpolation(
+ StringInterpolation node1, StringInterpolation node2) {
+ return testNodes(node1, node2, 'string', node1.string, node2.string) &&
+ testNodes(node1, node2, 'parts', node1.parts, node2.parts);
+ }
+
+ @override
+ bool visitStringInterpolationPart(
+ StringInterpolationPart node1, StringInterpolationPart node2) {
+ return testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression);
+ }
+
+ @override
+ bool visitStringJuxtaposition(
+ StringJuxtaposition node1, StringJuxtaposition node2) {
+ return testNodes(node1, node2, 'first', node1.first, node2.first) &&
+ testNodes(node1, node2, 'second', node1.second, node2.second);
+ }
+
+ @override
+ bool visitSwitchCase(SwitchCase node1, SwitchCase node2) {
+ return testTokens(node1, node2, 'defaultKeyword', node1.defaultKeyword,
+ node2.defaultKeyword) &&
+ testTokens(
+ node1, node2, 'startToken', node1.startToken, node2.startToken) &&
+ testNodes(node1, node2, 'labelsAndCases', node1.labelsAndCases,
+ node2.labelsAndCases) &&
+ testNodes(
+ node1, node2, 'statements', node1.statements, node2.statements);
+ }
+
+ @override
+ bool visitSwitchStatement(SwitchStatement node1, SwitchStatement node2) {
+ return testTokens(node1, node2, 'switchKeyword', node1.switchKeyword,
+ node2.switchKeyword) &&
+ testNodes(node1, node2, 'parenthesizedExpression',
+ node1.parenthesizedExpression, node2.parenthesizedExpression) &&
+ testNodes(node1, node2, 'cases', node1.cases, node2.cases);
+ }
+
+ @override
+ bool visitSyncForIn(SyncForIn node1, SyncForIn node2) {
+ return visitForIn(node1, node2);
+ }
+
+ @override
+ bool visitThrow(Throw node1, Throw node2) {
+ return testTokens(
+ node1, node2, 'throwToken', node1.throwToken, node2.throwToken) &&
+ testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
+ testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression);
+ }
+
+ @override
+ bool visitTryStatement(TryStatement node1, TryStatement node2) {
+ return testTokens(
+ node1, node2, 'tryKeyword', node1.tryKeyword, node2.tryKeyword) &&
+ testTokens(node1, node2, 'finallyKeyword', node1.finallyKeyword,
+ node2.finallyKeyword) &&
+ testNodes(node1, node2, 'tryBlock', node1.tryBlock, node2.tryBlock) &&
+ testNodes(node1, node2, 'catchBlocks', node1.catchBlocks,
+ node2.catchBlocks) &&
+ testNodes(node1, node2, 'finallyBlock', node1.finallyBlock,
+ node2.finallyBlock);
+ }
+
+ @override
+ bool visitTypeAnnotation(TypeAnnotation node1, TypeAnnotation node2) {
+ return testNodes(
+ node1, node2, 'typeName', node1.typeName, node2.typeName) &&
+ testNodes(node1, node2, 'typeArguments', node1.typeArguments,
+ node2.typeArguments);
+ }
+
+ @override
+ bool visitTypeVariable(TypeVariable node1, TypeVariable node2) {
+ return testNodes(node1, node2, 'name', node1.name, node2.name) &&
+ testNodes(node1, node2, 'bound', node1.bound, node2.bound);
+ }
+
+ @override
+ bool visitTypedef(Typedef node1, Typedef node2) {
+ return testTokens(node1, node2, 'typedefKeyword', node1.typedefKeyword,
+ node2.typedefKeyword) &&
+ testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
+ testNodes(
+ node1, node2, 'returnType', node1.returnType, node2.returnType) &&
+ testNodes(node1, node2, 'name', node1.name, node2.name) &&
+ testNodes(node1, node2, 'typeParameters', node1.typeParameters,
+ node2.typeParameters) &&
+ testNodes(node1, node2, 'formals', node1.formals, node2.formals);
+ }
+
+ @override
+ bool visitVariableDefinitions(
+ VariableDefinitions node1, VariableDefinitions node2) {
+ return testNodes(
+ node1, node2, 'metadata', node1.metadata, node2.metadata) &&
+ testNodes(node1, node2, 'type', node1.type, node2.type) &&
+ testNodes(
+ node1, node2, 'modifiers', node1.modifiers, node2.modifiers) &&
+ testNodes(
+ node1, node2, 'definitions', node1.definitions, node2.definitions);
+ }
+
+ @override
+ bool visitWhile(While node1, While node2) {
+ return testTokens(node1, node2, 'whileKeyword', node1.whileKeyword,
+ node2.whileKeyword) &&
+ testNodes(
+ node1, node2, 'condition', node1.condition, node2.condition) &&
+ testNodes(node1, node2, 'body', node1.body, node2.body);
+ }
+
+ @override
+ bool visitYield(Yield node1, Yield node2) {
+ return testTokens(
+ node1, node2, 'yieldToken', node1.yieldToken, node2.yieldToken) &&
+ testTokens(
+ node1, node2, 'starToken', node1.starToken, node2.starToken) &&
+ testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
+ testNodes(
+ node1, node2, 'expression', node1.expression, node2.expression);
+ }
+
+ @override
+ bool visitNode(Node node1, Node node2) {
+ throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
+ }
+
+ @override
+ bool visitExpression(Expression node1, Expression node2) {
+ throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
+ }
+
+ @override
+ bool visitStatement(Statement node1, Statement node2) {
+ throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
+ }
+
+ @override
+ bool visitStringNode(StringNode node1, StringNode node2) {
+ throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
+ }
+}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698