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

Side by Side Diff: pkg/analyzer/lib/src/dart/ast/utilities.dart

Issue 1558843002: First step towards a public API for AST nodes (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Add new files Created 4 years, 11 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 unified diff | Download patch
« no previous file with comments | « pkg/analyzer/lib/dart/ast/visitor.dart ('k') | pkg/analyzer/lib/src/generated/ast.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library analyzer.src.generated.ast;
6
7 import 'dart:collection';
8
9 import 'package:analyzer/dart/ast/visitor.dart';
10 import 'package:analyzer/dart/element/element.dart';
11 import 'package:analyzer/src/generated/ast.dart';
12 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
13 import 'package:analyzer/src/generated/java_core.dart';
14 import 'package:analyzer/src/generated/java_engine.dart';
15 import 'package:analyzer/src/generated/scanner.dart';
16 import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
17 import 'package:analyzer/src/generated/utilities_dart.dart';
18
19 /**
20 * An AST visitor that will clone any AST structure that it visits. The cloner
21 * will only clone the structure, it will not preserve any resolution results or
22 * properties associated with the nodes.
23 */
24 class AstCloner implements AstVisitor<AstNode> {
25 /**
26 * A flag indicating whether tokens should be cloned while cloning an AST
27 * structure.
28 */
29 final bool cloneTokens;
30
31 /**
32 * Initialize a newly created AST cloner to optionally clone tokens while
33 * cloning AST nodes if [cloneTokens] is `true`.
34 */
35 AstCloner(
36 [this.cloneTokens =
37 false]); // TODO(brianwilkerson) Change this to be a named parameter.
38
39 /**
40 * Return a clone of the given [node].
41 */
42 AstNode cloneNode(AstNode node) {
43 if (node == null) {
44 return null;
45 }
46 return node.accept(this) as AstNode;
47 }
48
49 /**
50 * Return a list containing cloned versions of the nodes in the given list of
51 * [nodes].
52 */
53 List<AstNode> cloneNodeList(NodeList nodes) {
54 int count = nodes.length;
55 List clonedNodes = new List();
56 for (int i = 0; i < count; i++) {
57 clonedNodes.add((nodes[i]).accept(this) as AstNode);
58 }
59 return clonedNodes;
60 }
61
62 /**
63 * Clone the given [token] if tokens are supposed to be cloned.
64 */
65 Token cloneToken(Token token) {
66 if (cloneTokens) {
67 return (token == null ? null : token.copy());
68 } else {
69 return token;
70 }
71 }
72
73 /**
74 * Clone the given [tokens] if tokens are supposed to be cloned.
75 */
76 List<Token> cloneTokenList(List<Token> tokens) {
77 if (cloneTokens) {
78 return tokens.map((Token token) => token.copy()).toList();
79 }
80 return tokens;
81 }
82
83 @override
84 AdjacentStrings visitAdjacentStrings(AdjacentStrings node) =>
85 new AdjacentStrings(cloneNodeList(node.strings));
86
87 @override
88 Annotation visitAnnotation(Annotation node) => new Annotation(
89 cloneToken(node.atSign),
90 cloneNode(node.name),
91 cloneToken(node.period),
92 cloneNode(node.constructorName),
93 cloneNode(node.arguments));
94
95 @override
96 ArgumentList visitArgumentList(ArgumentList node) => new ArgumentList(
97 cloneToken(node.leftParenthesis),
98 cloneNodeList(node.arguments),
99 cloneToken(node.rightParenthesis));
100
101 @override
102 AsExpression visitAsExpression(AsExpression node) => new AsExpression(
103 cloneNode(node.expression),
104 cloneToken(node.asOperator),
105 cloneNode(node.type));
106
107 @override
108 AstNode visitAssertStatement(AssertStatement node) => new AssertStatement(
109 cloneToken(node.assertKeyword),
110 cloneToken(node.leftParenthesis),
111 cloneNode(node.condition),
112 cloneToken(node.comma),
113 cloneNode(node.message),
114 cloneToken(node.rightParenthesis),
115 cloneToken(node.semicolon));
116
117 @override
118 AssignmentExpression visitAssignmentExpression(AssignmentExpression node) =>
119 new AssignmentExpression(cloneNode(node.leftHandSide),
120 cloneToken(node.operator), cloneNode(node.rightHandSide));
121
122 @override
123 AwaitExpression visitAwaitExpression(AwaitExpression node) =>
124 new AwaitExpression(
125 cloneToken(node.awaitKeyword), cloneNode(node.expression));
126
127 @override
128 BinaryExpression visitBinaryExpression(BinaryExpression node) =>
129 new BinaryExpression(cloneNode(node.leftOperand),
130 cloneToken(node.operator), cloneNode(node.rightOperand));
131
132 @override
133 Block visitBlock(Block node) => new Block(cloneToken(node.leftBracket),
134 cloneNodeList(node.statements), cloneToken(node.rightBracket));
135
136 @override
137 BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) =>
138 new BlockFunctionBody(cloneToken(node.keyword), cloneToken(node.star),
139 cloneNode(node.block));
140
141 @override
142 BooleanLiteral visitBooleanLiteral(BooleanLiteral node) =>
143 new BooleanLiteral(cloneToken(node.literal), node.value);
144
145 @override
146 BreakStatement visitBreakStatement(BreakStatement node) => new BreakStatement(
147 cloneToken(node.breakKeyword),
148 cloneNode(node.label),
149 cloneToken(node.semicolon));
150
151 @override
152 CascadeExpression visitCascadeExpression(CascadeExpression node) =>
153 new CascadeExpression(
154 cloneNode(node.target), cloneNodeList(node.cascadeSections));
155
156 @override
157 CatchClause visitCatchClause(CatchClause node) => new CatchClause(
158 cloneToken(node.onKeyword),
159 cloneNode(node.exceptionType),
160 cloneToken(node.catchKeyword),
161 cloneToken(node.leftParenthesis),
162 cloneNode(node.exceptionParameter),
163 cloneToken(node.comma),
164 cloneNode(node.stackTraceParameter),
165 cloneToken(node.rightParenthesis),
166 cloneNode(node.body));
167
168 @override
169 ClassDeclaration visitClassDeclaration(ClassDeclaration node) {
170 ClassDeclaration copy = new ClassDeclaration(
171 cloneNode(node.documentationComment),
172 cloneNodeList(node.metadata),
173 cloneToken(node.abstractKeyword),
174 cloneToken(node.classKeyword),
175 cloneNode(node.name),
176 cloneNode(node.typeParameters),
177 cloneNode(node.extendsClause),
178 cloneNode(node.withClause),
179 cloneNode(node.implementsClause),
180 cloneToken(node.leftBracket),
181 cloneNodeList(node.members),
182 cloneToken(node.rightBracket));
183 copy.nativeClause = cloneNode(node.nativeClause);
184 return copy;
185 }
186
187 @override
188 ClassTypeAlias visitClassTypeAlias(ClassTypeAlias node) => new ClassTypeAlias(
189 cloneNode(node.documentationComment),
190 cloneNodeList(node.metadata),
191 cloneToken(node.typedefKeyword),
192 cloneNode(node.name),
193 cloneNode(node.typeParameters),
194 cloneToken(node.equals),
195 cloneToken(node.abstractKeyword),
196 cloneNode(node.superclass),
197 cloneNode(node.withClause),
198 cloneNode(node.implementsClause),
199 cloneToken(node.semicolon));
200
201 @override
202 Comment visitComment(Comment node) {
203 if (node.isDocumentation) {
204 return Comment.createDocumentationCommentWithReferences(
205 cloneTokenList(node.tokens), cloneNodeList(node.references));
206 } else if (node.isBlock) {
207 return Comment.createBlockComment(cloneTokenList(node.tokens));
208 }
209 return Comment.createEndOfLineComment(cloneTokenList(node.tokens));
210 }
211
212 @override
213 CommentReference visitCommentReference(CommentReference node) =>
214 new CommentReference(
215 cloneToken(node.newKeyword), cloneNode(node.identifier));
216
217 @override
218 CompilationUnit visitCompilationUnit(CompilationUnit node) {
219 CompilationUnit clone = new CompilationUnit(
220 cloneToken(node.beginToken),
221 cloneNode(node.scriptTag),
222 cloneNodeList(node.directives),
223 cloneNodeList(node.declarations),
224 cloneToken(node.endToken));
225 clone.lineInfo = node.lineInfo;
226 return clone;
227 }
228
229 @override
230 ConditionalExpression visitConditionalExpression(
231 ConditionalExpression node) =>
232 new ConditionalExpression(
233 cloneNode(node.condition),
234 cloneToken(node.question),
235 cloneNode(node.thenExpression),
236 cloneToken(node.colon),
237 cloneNode(node.elseExpression));
238
239 @override
240 Configuration visitConfiguration(Configuration node) => new Configuration(
241 cloneToken(node.ifKeyword),
242 cloneToken(node.leftParenthesis),
243 cloneNode(node.name),
244 cloneToken(node.equalToken),
245 cloneNode(node.value),
246 cloneToken(node.rightParenthesis),
247 cloneNode(node.libraryUri));
248
249 @override
250 ConstructorDeclaration visitConstructorDeclaration(
251 ConstructorDeclaration node) =>
252 new ConstructorDeclaration(
253 cloneNode(node.documentationComment),
254 cloneNodeList(node.metadata),
255 cloneToken(node.externalKeyword),
256 cloneToken(node.constKeyword),
257 cloneToken(node.factoryKeyword),
258 cloneNode(node.returnType),
259 cloneToken(node.period),
260 cloneNode(node.name),
261 cloneNode(node.parameters),
262 cloneToken(node.separator),
263 cloneNodeList(node.initializers),
264 cloneNode(node.redirectedConstructor),
265 cloneNode(node.body));
266
267 @override
268 ConstructorFieldInitializer visitConstructorFieldInitializer(
269 ConstructorFieldInitializer node) =>
270 new ConstructorFieldInitializer(
271 cloneToken(node.thisKeyword),
272 cloneToken(node.period),
273 cloneNode(node.fieldName),
274 cloneToken(node.equals),
275 cloneNode(node.expression));
276
277 @override
278 ConstructorName visitConstructorName(ConstructorName node) =>
279 new ConstructorName(
280 cloneNode(node.type), cloneToken(node.period), cloneNode(node.name));
281
282 @override
283 ContinueStatement visitContinueStatement(ContinueStatement node) =>
284 new ContinueStatement(cloneToken(node.continueKeyword),
285 cloneNode(node.label), cloneToken(node.semicolon));
286
287 @override
288 DeclaredIdentifier visitDeclaredIdentifier(DeclaredIdentifier node) =>
289 new DeclaredIdentifier(
290 cloneNode(node.documentationComment),
291 cloneNodeList(node.metadata),
292 cloneToken(node.keyword),
293 cloneNode(node.type),
294 cloneNode(node.identifier));
295
296 @override
297 DefaultFormalParameter visitDefaultFormalParameter(
298 DefaultFormalParameter node) =>
299 new DefaultFormalParameter(cloneNode(node.parameter), node.kind,
300 cloneToken(node.separator), cloneNode(node.defaultValue));
301
302 @override
303 DoStatement visitDoStatement(DoStatement node) => new DoStatement(
304 cloneToken(node.doKeyword),
305 cloneNode(node.body),
306 cloneToken(node.whileKeyword),
307 cloneToken(node.leftParenthesis),
308 cloneNode(node.condition),
309 cloneToken(node.rightParenthesis),
310 cloneToken(node.semicolon));
311
312 @override
313 DottedName visitDottedName(DottedName node) =>
314 new DottedName(cloneNodeList(node.components));
315
316 @override
317 DoubleLiteral visitDoubleLiteral(DoubleLiteral node) =>
318 new DoubleLiteral(cloneToken(node.literal), node.value);
319
320 @override
321 EmptyFunctionBody visitEmptyFunctionBody(EmptyFunctionBody node) =>
322 new EmptyFunctionBody(cloneToken(node.semicolon));
323
324 @override
325 EmptyStatement visitEmptyStatement(EmptyStatement node) =>
326 new EmptyStatement(cloneToken(node.semicolon));
327
328 @override
329 AstNode visitEnumConstantDeclaration(EnumConstantDeclaration node) =>
330 new EnumConstantDeclaration(cloneNode(node.documentationComment),
331 cloneNodeList(node.metadata), cloneNode(node.name));
332
333 @override
334 EnumDeclaration visitEnumDeclaration(EnumDeclaration node) =>
335 new EnumDeclaration(
336 cloneNode(node.documentationComment),
337 cloneNodeList(node.metadata),
338 cloneToken(node.enumKeyword),
339 cloneNode(node.name),
340 cloneToken(node.leftBracket),
341 cloneNodeList(node.constants),
342 cloneToken(node.rightBracket));
343
344 @override
345 ExportDirective visitExportDirective(ExportDirective node) {
346 ExportDirective directive = new ExportDirective(
347 cloneNode(node.documentationComment),
348 cloneNodeList(node.metadata),
349 cloneToken(node.keyword),
350 cloneNode(node.uri),
351 cloneNodeList(node.configurations),
352 cloneNodeList(node.combinators),
353 cloneToken(node.semicolon));
354 directive.source = node.source;
355 directive.uriContent = node.uriContent;
356 return directive;
357 }
358
359 @override
360 ExpressionFunctionBody visitExpressionFunctionBody(
361 ExpressionFunctionBody node) =>
362 new ExpressionFunctionBody(
363 cloneToken(node.keyword),
364 cloneToken(node.functionDefinition),
365 cloneNode(node.expression),
366 cloneToken(node.semicolon));
367
368 @override
369 ExpressionStatement visitExpressionStatement(ExpressionStatement node) =>
370 new ExpressionStatement(
371 cloneNode(node.expression), cloneToken(node.semicolon));
372
373 @override
374 ExtendsClause visitExtendsClause(ExtendsClause node) => new ExtendsClause(
375 cloneToken(node.extendsKeyword), cloneNode(node.superclass));
376
377 @override
378 FieldDeclaration visitFieldDeclaration(FieldDeclaration node) =>
379 new FieldDeclaration(
380 cloneNode(node.documentationComment),
381 cloneNodeList(node.metadata),
382 cloneToken(node.staticKeyword),
383 cloneNode(node.fields),
384 cloneToken(node.semicolon));
385
386 @override
387 FieldFormalParameter visitFieldFormalParameter(FieldFormalParameter node) =>
388 new FieldFormalParameter(
389 cloneNode(node.documentationComment),
390 cloneNodeList(node.metadata),
391 cloneToken(node.keyword),
392 cloneNode(node.type),
393 cloneToken(node.thisKeyword),
394 cloneToken(node.period),
395 cloneNode(node.identifier),
396 cloneNode(node.typeParameters),
397 cloneNode(node.parameters));
398
399 @override
400 ForEachStatement visitForEachStatement(ForEachStatement node) {
401 DeclaredIdentifier loopVariable = node.loopVariable;
402 if (loopVariable == null) {
403 return new ForEachStatement.withReference(
404 cloneToken(node.awaitKeyword),
405 cloneToken(node.forKeyword),
406 cloneToken(node.leftParenthesis),
407 cloneNode(node.identifier),
408 cloneToken(node.inKeyword),
409 cloneNode(node.iterable),
410 cloneToken(node.rightParenthesis),
411 cloneNode(node.body));
412 }
413 return new ForEachStatement.withDeclaration(
414 cloneToken(node.awaitKeyword),
415 cloneToken(node.forKeyword),
416 cloneToken(node.leftParenthesis),
417 cloneNode(loopVariable),
418 cloneToken(node.inKeyword),
419 cloneNode(node.iterable),
420 cloneToken(node.rightParenthesis),
421 cloneNode(node.body));
422 }
423
424 @override
425 FormalParameterList visitFormalParameterList(FormalParameterList node) =>
426 new FormalParameterList(
427 cloneToken(node.leftParenthesis),
428 cloneNodeList(node.parameters),
429 cloneToken(node.leftDelimiter),
430 cloneToken(node.rightDelimiter),
431 cloneToken(node.rightParenthesis));
432
433 @override
434 ForStatement visitForStatement(ForStatement node) => new ForStatement(
435 cloneToken(node.forKeyword),
436 cloneToken(node.leftParenthesis),
437 cloneNode(node.variables),
438 cloneNode(node.initialization),
439 cloneToken(node.leftSeparator),
440 cloneNode(node.condition),
441 cloneToken(node.rightSeparator),
442 cloneNodeList(node.updaters),
443 cloneToken(node.rightParenthesis),
444 cloneNode(node.body));
445
446 @override
447 FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) =>
448 new FunctionDeclaration(
449 cloneNode(node.documentationComment),
450 cloneNodeList(node.metadata),
451 cloneToken(node.externalKeyword),
452 cloneNode(node.returnType),
453 cloneToken(node.propertyKeyword),
454 cloneNode(node.name),
455 cloneNode(node.functionExpression));
456
457 @override
458 FunctionDeclarationStatement visitFunctionDeclarationStatement(
459 FunctionDeclarationStatement node) =>
460 new FunctionDeclarationStatement(cloneNode(node.functionDeclaration));
461
462 @override
463 FunctionExpression visitFunctionExpression(FunctionExpression node) =>
464 new FunctionExpression(cloneNode(node.typeParameters),
465 cloneNode(node.parameters), cloneNode(node.body));
466
467 @override
468 FunctionExpressionInvocation visitFunctionExpressionInvocation(
469 FunctionExpressionInvocation node) =>
470 new FunctionExpressionInvocation(cloneNode(node.function),
471 cloneNode(node.typeArguments), cloneNode(node.argumentList));
472
473 @override
474 FunctionTypeAlias visitFunctionTypeAlias(FunctionTypeAlias node) =>
475 new FunctionTypeAlias(
476 cloneNode(node.documentationComment),
477 cloneNodeList(node.metadata),
478 cloneToken(node.typedefKeyword),
479 cloneNode(node.returnType),
480 cloneNode(node.name),
481 cloneNode(node.typeParameters),
482 cloneNode(node.parameters),
483 cloneToken(node.semicolon));
484
485 @override
486 FunctionTypedFormalParameter visitFunctionTypedFormalParameter(
487 FunctionTypedFormalParameter node) =>
488 new FunctionTypedFormalParameter(
489 cloneNode(node.documentationComment),
490 cloneNodeList(node.metadata),
491 cloneNode(node.returnType),
492 cloneNode(node.identifier),
493 cloneNode(node.typeParameters),
494 cloneNode(node.parameters));
495
496 @override
497 HideCombinator visitHideCombinator(HideCombinator node) => new HideCombinator(
498 cloneToken(node.keyword), cloneNodeList(node.hiddenNames));
499
500 @override
501 IfStatement visitIfStatement(IfStatement node) => new IfStatement(
502 cloneToken(node.ifKeyword),
503 cloneToken(node.leftParenthesis),
504 cloneNode(node.condition),
505 cloneToken(node.rightParenthesis),
506 cloneNode(node.thenStatement),
507 cloneToken(node.elseKeyword),
508 cloneNode(node.elseStatement));
509
510 @override
511 ImplementsClause visitImplementsClause(ImplementsClause node) =>
512 new ImplementsClause(
513 cloneToken(node.implementsKeyword), cloneNodeList(node.interfaces));
514
515 @override
516 ImportDirective visitImportDirective(ImportDirective node) {
517 ImportDirective directive = new ImportDirective(
518 cloneNode(node.documentationComment),
519 cloneNodeList(node.metadata),
520 cloneToken(node.keyword),
521 cloneNode(node.uri),
522 cloneNodeList(node.configurations),
523 cloneToken(node.deferredKeyword),
524 cloneToken(node.asKeyword),
525 cloneNode(node.prefix),
526 cloneNodeList(node.combinators),
527 cloneToken(node.semicolon));
528 directive.source = node.source;
529 directive.uriContent = node.uriContent;
530 return directive;
531 }
532
533 @override
534 IndexExpression visitIndexExpression(IndexExpression node) {
535 Token period = node.period;
536 if (period == null) {
537 return new IndexExpression.forTarget(
538 cloneNode(node.target),
539 cloneToken(node.leftBracket),
540 cloneNode(node.index),
541 cloneToken(node.rightBracket));
542 } else {
543 return new IndexExpression.forCascade(
544 cloneToken(period),
545 cloneToken(node.leftBracket),
546 cloneNode(node.index),
547 cloneToken(node.rightBracket));
548 }
549 }
550
551 @override
552 InstanceCreationExpression visitInstanceCreationExpression(
553 InstanceCreationExpression node) =>
554 new InstanceCreationExpression(cloneToken(node.keyword),
555 cloneNode(node.constructorName), cloneNode(node.argumentList));
556
557 @override
558 IntegerLiteral visitIntegerLiteral(IntegerLiteral node) =>
559 new IntegerLiteral(cloneToken(node.literal), node.value);
560
561 @override
562 InterpolationExpression visitInterpolationExpression(
563 InterpolationExpression node) =>
564 new InterpolationExpression(cloneToken(node.leftBracket),
565 cloneNode(node.expression), cloneToken(node.rightBracket));
566
567 @override
568 InterpolationString visitInterpolationString(InterpolationString node) =>
569 new InterpolationString(cloneToken(node.contents), node.value);
570
571 @override
572 IsExpression visitIsExpression(IsExpression node) => new IsExpression(
573 cloneNode(node.expression),
574 cloneToken(node.isOperator),
575 cloneToken(node.notOperator),
576 cloneNode(node.type));
577
578 @override
579 Label visitLabel(Label node) =>
580 new Label(cloneNode(node.label), cloneToken(node.colon));
581
582 @override
583 LabeledStatement visitLabeledStatement(LabeledStatement node) =>
584 new LabeledStatement(
585 cloneNodeList(node.labels), cloneNode(node.statement));
586
587 @override
588 LibraryDirective visitLibraryDirective(LibraryDirective node) =>
589 new LibraryDirective(
590 cloneNode(node.documentationComment),
591 cloneNodeList(node.metadata),
592 cloneToken(node.libraryKeyword),
593 cloneNode(node.name),
594 cloneToken(node.semicolon));
595
596 @override
597 LibraryIdentifier visitLibraryIdentifier(LibraryIdentifier node) =>
598 new LibraryIdentifier(cloneNodeList(node.components));
599
600 @override
601 ListLiteral visitListLiteral(ListLiteral node) => new ListLiteral(
602 cloneToken(node.constKeyword),
603 cloneNode(node.typeArguments),
604 cloneToken(node.leftBracket),
605 cloneNodeList(node.elements),
606 cloneToken(node.rightBracket));
607
608 @override
609 MapLiteral visitMapLiteral(MapLiteral node) => new MapLiteral(
610 cloneToken(node.constKeyword),
611 cloneNode(node.typeArguments),
612 cloneToken(node.leftBracket),
613 cloneNodeList(node.entries),
614 cloneToken(node.rightBracket));
615
616 @override
617 MapLiteralEntry visitMapLiteralEntry(MapLiteralEntry node) =>
618 new MapLiteralEntry(cloneNode(node.key), cloneToken(node.separator),
619 cloneNode(node.value));
620
621 @override
622 MethodDeclaration visitMethodDeclaration(MethodDeclaration node) =>
623 new MethodDeclaration(
624 cloneNode(node.documentationComment),
625 cloneNodeList(node.metadata),
626 cloneToken(node.externalKeyword),
627 cloneToken(node.modifierKeyword),
628 cloneNode(node.returnType),
629 cloneToken(node.propertyKeyword),
630 cloneToken(node.operatorKeyword),
631 cloneNode(node.name),
632 cloneNode(node.typeParameters),
633 cloneNode(node.parameters),
634 cloneNode(node.body));
635
636 @override
637 MethodInvocation visitMethodInvocation(MethodInvocation node) =>
638 new MethodInvocation(
639 cloneNode(node.target),
640 cloneToken(node.operator),
641 cloneNode(node.methodName),
642 cloneNode(node.typeArguments),
643 cloneNode(node.argumentList));
644
645 @override
646 NamedExpression visitNamedExpression(NamedExpression node) =>
647 new NamedExpression(cloneNode(node.name), cloneNode(node.expression));
648
649 @override
650 AstNode visitNativeClause(NativeClause node) =>
651 new NativeClause(cloneToken(node.nativeKeyword), cloneNode(node.name));
652
653 @override
654 NativeFunctionBody visitNativeFunctionBody(NativeFunctionBody node) =>
655 new NativeFunctionBody(cloneToken(node.nativeKeyword),
656 cloneNode(node.stringLiteral), cloneToken(node.semicolon));
657
658 @override
659 NullLiteral visitNullLiteral(NullLiteral node) =>
660 new NullLiteral(cloneToken(node.literal));
661
662 @override
663 ParenthesizedExpression visitParenthesizedExpression(
664 ParenthesizedExpression node) =>
665 new ParenthesizedExpression(cloneToken(node.leftParenthesis),
666 cloneNode(node.expression), cloneToken(node.rightParenthesis));
667
668 @override
669 PartDirective visitPartDirective(PartDirective node) {
670 PartDirective directive = new PartDirective(
671 cloneNode(node.documentationComment),
672 cloneNodeList(node.metadata),
673 cloneToken(node.partKeyword),
674 cloneNode(node.uri),
675 cloneToken(node.semicolon));
676 directive.source = node.source;
677 directive.uriContent = node.uriContent;
678 return directive;
679 }
680
681 @override
682 PartOfDirective visitPartOfDirective(PartOfDirective node) =>
683 new PartOfDirective(
684 cloneNode(node.documentationComment),
685 cloneNodeList(node.metadata),
686 cloneToken(node.partKeyword),
687 cloneToken(node.ofKeyword),
688 cloneNode(node.libraryName),
689 cloneToken(node.semicolon));
690
691 @override
692 PostfixExpression visitPostfixExpression(PostfixExpression node) =>
693 new PostfixExpression(cloneNode(node.operand), cloneToken(node.operator));
694
695 @override
696 PrefixedIdentifier visitPrefixedIdentifier(PrefixedIdentifier node) =>
697 new PrefixedIdentifier(cloneNode(node.prefix), cloneToken(node.period),
698 cloneNode(node.identifier));
699
700 @override
701 PrefixExpression visitPrefixExpression(PrefixExpression node) =>
702 new PrefixExpression(cloneToken(node.operator), cloneNode(node.operand));
703
704 @override
705 PropertyAccess visitPropertyAccess(PropertyAccess node) => new PropertyAccess(
706 cloneNode(node.target),
707 cloneToken(node.operator),
708 cloneNode(node.propertyName));
709
710 @override
711 RedirectingConstructorInvocation visitRedirectingConstructorInvocation(
712 RedirectingConstructorInvocation node) =>
713 new RedirectingConstructorInvocation(
714 cloneToken(node.thisKeyword),
715 cloneToken(node.period),
716 cloneNode(node.constructorName),
717 cloneNode(node.argumentList));
718
719 @override
720 RethrowExpression visitRethrowExpression(RethrowExpression node) =>
721 new RethrowExpression(cloneToken(node.rethrowKeyword));
722
723 @override
724 ReturnStatement visitReturnStatement(ReturnStatement node) =>
725 new ReturnStatement(cloneToken(node.returnKeyword),
726 cloneNode(node.expression), cloneToken(node.semicolon));
727
728 @override
729 ScriptTag visitScriptTag(ScriptTag node) =>
730 new ScriptTag(cloneToken(node.scriptTag));
731
732 @override
733 ShowCombinator visitShowCombinator(ShowCombinator node) => new ShowCombinator(
734 cloneToken(node.keyword), cloneNodeList(node.shownNames));
735
736 @override
737 SimpleFormalParameter visitSimpleFormalParameter(
738 SimpleFormalParameter node) =>
739 new SimpleFormalParameter(
740 cloneNode(node.documentationComment),
741 cloneNodeList(node.metadata),
742 cloneToken(node.keyword),
743 cloneNode(node.type),
744 cloneNode(node.identifier));
745
746 @override
747 SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) =>
748 new SimpleIdentifier(cloneToken(node.token));
749
750 @override
751 SimpleStringLiteral visitSimpleStringLiteral(SimpleStringLiteral node) =>
752 new SimpleStringLiteral(cloneToken(node.literal), node.value);
753
754 @override
755 StringInterpolation visitStringInterpolation(StringInterpolation node) =>
756 new StringInterpolation(cloneNodeList(node.elements));
757
758 @override
759 SuperConstructorInvocation visitSuperConstructorInvocation(
760 SuperConstructorInvocation node) =>
761 new SuperConstructorInvocation(
762 cloneToken(node.superKeyword),
763 cloneToken(node.period),
764 cloneNode(node.constructorName),
765 cloneNode(node.argumentList));
766
767 @override
768 SuperExpression visitSuperExpression(SuperExpression node) =>
769 new SuperExpression(cloneToken(node.superKeyword));
770
771 @override
772 SwitchCase visitSwitchCase(SwitchCase node) => new SwitchCase(
773 cloneNodeList(node.labels),
774 cloneToken(node.keyword),
775 cloneNode(node.expression),
776 cloneToken(node.colon),
777 cloneNodeList(node.statements));
778
779 @override
780 SwitchDefault visitSwitchDefault(SwitchDefault node) => new SwitchDefault(
781 cloneNodeList(node.labels),
782 cloneToken(node.keyword),
783 cloneToken(node.colon),
784 cloneNodeList(node.statements));
785
786 @override
787 SwitchStatement visitSwitchStatement(SwitchStatement node) =>
788 new SwitchStatement(
789 cloneToken(node.switchKeyword),
790 cloneToken(node.leftParenthesis),
791 cloneNode(node.expression),
792 cloneToken(node.rightParenthesis),
793 cloneToken(node.leftBracket),
794 cloneNodeList(node.members),
795 cloneToken(node.rightBracket));
796
797 @override
798 SymbolLiteral visitSymbolLiteral(SymbolLiteral node) => new SymbolLiteral(
799 cloneToken(node.poundSign), cloneTokenList(node.components));
800
801 @override
802 ThisExpression visitThisExpression(ThisExpression node) =>
803 new ThisExpression(cloneToken(node.thisKeyword));
804
805 @override
806 ThrowExpression visitThrowExpression(ThrowExpression node) =>
807 new ThrowExpression(
808 cloneToken(node.throwKeyword), cloneNode(node.expression));
809
810 @override
811 TopLevelVariableDeclaration visitTopLevelVariableDeclaration(
812 TopLevelVariableDeclaration node) =>
813 new TopLevelVariableDeclaration(
814 cloneNode(node.documentationComment),
815 cloneNodeList(node.metadata),
816 cloneNode(node.variables),
817 cloneToken(node.semicolon));
818
819 @override
820 TryStatement visitTryStatement(TryStatement node) => new TryStatement(
821 cloneToken(node.tryKeyword),
822 cloneNode(node.body),
823 cloneNodeList(node.catchClauses),
824 cloneToken(node.finallyKeyword),
825 cloneNode(node.finallyBlock));
826
827 @override
828 TypeArgumentList visitTypeArgumentList(TypeArgumentList node) =>
829 new TypeArgumentList(cloneToken(node.leftBracket),
830 cloneNodeList(node.arguments), cloneToken(node.rightBracket));
831
832 @override
833 TypeName visitTypeName(TypeName node) =>
834 new TypeName(cloneNode(node.name), cloneNode(node.typeArguments));
835
836 @override
837 TypeParameter visitTypeParameter(TypeParameter node) => new TypeParameter(
838 cloneNode(node.documentationComment),
839 cloneNodeList(node.metadata),
840 cloneNode(node.name),
841 cloneToken(node.extendsKeyword),
842 cloneNode(node.bound));
843
844 @override
845 TypeParameterList visitTypeParameterList(TypeParameterList node) =>
846 new TypeParameterList(cloneToken(node.leftBracket),
847 cloneNodeList(node.typeParameters), cloneToken(node.rightBracket));
848
849 @override
850 VariableDeclaration visitVariableDeclaration(VariableDeclaration node) =>
851 new VariableDeclaration(cloneNode(node.name), cloneToken(node.equals),
852 cloneNode(node.initializer));
853
854 @override
855 VariableDeclarationList visitVariableDeclarationList(
856 VariableDeclarationList node) =>
857 new VariableDeclarationList(
858 cloneNode(node.documentationComment),
859 cloneNodeList(node.metadata),
860 cloneToken(node.keyword),
861 cloneNode(node.type),
862 cloneNodeList(node.variables));
863
864 @override
865 VariableDeclarationStatement visitVariableDeclarationStatement(
866 VariableDeclarationStatement node) =>
867 new VariableDeclarationStatement(
868 cloneNode(node.variables), cloneToken(node.semicolon));
869
870 @override
871 WhileStatement visitWhileStatement(WhileStatement node) => new WhileStatement(
872 cloneToken(node.whileKeyword),
873 cloneToken(node.leftParenthesis),
874 cloneNode(node.condition),
875 cloneToken(node.rightParenthesis),
876 cloneNode(node.body));
877
878 @override
879 WithClause visitWithClause(WithClause node) => new WithClause(
880 cloneToken(node.withKeyword), cloneNodeList(node.mixinTypes));
881
882 @override
883 YieldStatement visitYieldStatement(YieldStatement node) => new YieldStatement(
884 cloneToken(node.yieldKeyword),
885 cloneToken(node.star),
886 cloneNode(node.expression),
887 cloneToken(node.semicolon));
888
889 /**
890 * Return a clone of the given [node].
891 */
892 static AstNode clone(AstNode node) {
893 return node.accept(new AstCloner());
894 }
895 }
896
897 /**
898 * An AstVisitor that compares the structure of two AstNodes to see whether they
899 * are equal.
900 */
901 class AstComparator implements AstVisitor<bool> {
902 /**
903 * The AST node with which the node being visited is to be compared. This is
904 * only valid at the beginning of each visit method (until [isEqualNodes] is
905 * invoked).
906 */
907 AstNode _other;
908
909 /**
910 * Return `true` if the [first] node and the [second] node have the same
911 * structure.
912 *
913 * *Note:* This method is only visible for testing purposes and should not be
914 * used by clients.
915 */
916 bool isEqualNodes(AstNode first, AstNode second) {
917 if (first == null) {
918 return second == null;
919 } else if (second == null) {
920 return false;
921 } else if (first.runtimeType != second.runtimeType) {
922 return false;
923 }
924 _other = second;
925 return first.accept(this);
926 }
927
928 /**
929 * Return `true` if the [first] token and the [second] token have the same
930 * structure.
931 *
932 * *Note:* This method is only visible for testing purposes and should not be
933 * used by clients.
934 */
935 bool isEqualTokens(Token first, Token second) {
936 if (first == null) {
937 return second == null;
938 } else if (second == null) {
939 return false;
940 } else if (identical(first, second)) {
941 return true;
942 }
943 return first.offset == second.offset &&
944 first.length == second.length &&
945 first.lexeme == second.lexeme;
946 }
947
948 @override
949 bool visitAdjacentStrings(AdjacentStrings node) {
950 AdjacentStrings other = _other as AdjacentStrings;
951 return _isEqualNodeLists(node.strings, other.strings);
952 }
953
954 @override
955 bool visitAnnotation(Annotation node) {
956 Annotation other = _other as Annotation;
957 return isEqualTokens(node.atSign, other.atSign) &&
958 isEqualNodes(node.name, other.name) &&
959 isEqualTokens(node.period, other.period) &&
960 isEqualNodes(node.constructorName, other.constructorName) &&
961 isEqualNodes(node.arguments, other.arguments);
962 }
963
964 @override
965 bool visitArgumentList(ArgumentList node) {
966 ArgumentList other = _other as ArgumentList;
967 return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
968 _isEqualNodeLists(node.arguments, other.arguments) &&
969 isEqualTokens(node.rightParenthesis, other.rightParenthesis);
970 }
971
972 @override
973 bool visitAsExpression(AsExpression node) {
974 AsExpression other = _other as AsExpression;
975 return isEqualNodes(node.expression, other.expression) &&
976 isEqualTokens(node.asOperator, other.asOperator) &&
977 isEqualNodes(node.type, other.type);
978 }
979
980 @override
981 bool visitAssertStatement(AssertStatement node) {
982 AssertStatement other = _other as AssertStatement;
983 return isEqualTokens(node.assertKeyword, other.assertKeyword) &&
984 isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
985 isEqualNodes(node.condition, other.condition) &&
986 isEqualTokens(node.comma, other.comma) &&
987 isEqualNodes(node.message, other.message) &&
988 isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
989 isEqualTokens(node.semicolon, other.semicolon);
990 }
991
992 @override
993 bool visitAssignmentExpression(AssignmentExpression node) {
994 AssignmentExpression other = _other as AssignmentExpression;
995 return isEqualNodes(node.leftHandSide, other.leftHandSide) &&
996 isEqualTokens(node.operator, other.operator) &&
997 isEqualNodes(node.rightHandSide, other.rightHandSide);
998 }
999
1000 @override
1001 bool visitAwaitExpression(AwaitExpression node) {
1002 AwaitExpression other = _other as AwaitExpression;
1003 return isEqualTokens(node.awaitKeyword, other.awaitKeyword) &&
1004 isEqualNodes(node.expression, other.expression);
1005 }
1006
1007 @override
1008 bool visitBinaryExpression(BinaryExpression node) {
1009 BinaryExpression other = _other as BinaryExpression;
1010 return isEqualNodes(node.leftOperand, other.leftOperand) &&
1011 isEqualTokens(node.operator, other.operator) &&
1012 isEqualNodes(node.rightOperand, other.rightOperand);
1013 }
1014
1015 @override
1016 bool visitBlock(Block node) {
1017 Block other = _other as Block;
1018 return isEqualTokens(node.leftBracket, other.leftBracket) &&
1019 _isEqualNodeLists(node.statements, other.statements) &&
1020 isEqualTokens(node.rightBracket, other.rightBracket);
1021 }
1022
1023 @override
1024 bool visitBlockFunctionBody(BlockFunctionBody node) {
1025 BlockFunctionBody other = _other as BlockFunctionBody;
1026 return isEqualNodes(node.block, other.block);
1027 }
1028
1029 @override
1030 bool visitBooleanLiteral(BooleanLiteral node) {
1031 BooleanLiteral other = _other as BooleanLiteral;
1032 return isEqualTokens(node.literal, other.literal) &&
1033 node.value == other.value;
1034 }
1035
1036 @override
1037 bool visitBreakStatement(BreakStatement node) {
1038 BreakStatement other = _other as BreakStatement;
1039 return isEqualTokens(node.breakKeyword, other.breakKeyword) &&
1040 isEqualNodes(node.label, other.label) &&
1041 isEqualTokens(node.semicolon, other.semicolon);
1042 }
1043
1044 @override
1045 bool visitCascadeExpression(CascadeExpression node) {
1046 CascadeExpression other = _other as CascadeExpression;
1047 return isEqualNodes(node.target, other.target) &&
1048 _isEqualNodeLists(node.cascadeSections, other.cascadeSections);
1049 }
1050
1051 @override
1052 bool visitCatchClause(CatchClause node) {
1053 CatchClause other = _other as CatchClause;
1054 return isEqualTokens(node.onKeyword, other.onKeyword) &&
1055 isEqualNodes(node.exceptionType, other.exceptionType) &&
1056 isEqualTokens(node.catchKeyword, other.catchKeyword) &&
1057 isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
1058 isEqualNodes(node.exceptionParameter, other.exceptionParameter) &&
1059 isEqualTokens(node.comma, other.comma) &&
1060 isEqualNodes(node.stackTraceParameter, other.stackTraceParameter) &&
1061 isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
1062 isEqualNodes(node.body, other.body);
1063 }
1064
1065 @override
1066 bool visitClassDeclaration(ClassDeclaration node) {
1067 ClassDeclaration other = _other as ClassDeclaration;
1068 return isEqualNodes(
1069 node.documentationComment, other.documentationComment) &&
1070 _isEqualNodeLists(node.metadata, other.metadata) &&
1071 isEqualTokens(node.abstractKeyword, other.abstractKeyword) &&
1072 isEqualTokens(node.classKeyword, other.classKeyword) &&
1073 isEqualNodes(node.name, other.name) &&
1074 isEqualNodes(node.typeParameters, other.typeParameters) &&
1075 isEqualNodes(node.extendsClause, other.extendsClause) &&
1076 isEqualNodes(node.withClause, other.withClause) &&
1077 isEqualNodes(node.implementsClause, other.implementsClause) &&
1078 isEqualTokens(node.leftBracket, other.leftBracket) &&
1079 _isEqualNodeLists(node.members, other.members) &&
1080 isEqualTokens(node.rightBracket, other.rightBracket);
1081 }
1082
1083 @override
1084 bool visitClassTypeAlias(ClassTypeAlias node) {
1085 ClassTypeAlias other = _other as ClassTypeAlias;
1086 return isEqualNodes(
1087 node.documentationComment, other.documentationComment) &&
1088 _isEqualNodeLists(node.metadata, other.metadata) &&
1089 isEqualTokens(node.typedefKeyword, other.typedefKeyword) &&
1090 isEqualNodes(node.name, other.name) &&
1091 isEqualNodes(node.typeParameters, other.typeParameters) &&
1092 isEqualTokens(node.equals, other.equals) &&
1093 isEqualTokens(node.abstractKeyword, other.abstractKeyword) &&
1094 isEqualNodes(node.superclass, other.superclass) &&
1095 isEqualNodes(node.withClause, other.withClause) &&
1096 isEqualNodes(node.implementsClause, other.implementsClause) &&
1097 isEqualTokens(node.semicolon, other.semicolon);
1098 }
1099
1100 @override
1101 bool visitComment(Comment node) {
1102 Comment other = _other as Comment;
1103 return _isEqualNodeLists(node.references, other.references);
1104 }
1105
1106 @override
1107 bool visitCommentReference(CommentReference node) {
1108 CommentReference other = _other as CommentReference;
1109 return isEqualTokens(node.newKeyword, other.newKeyword) &&
1110 isEqualNodes(node.identifier, other.identifier);
1111 }
1112
1113 @override
1114 bool visitCompilationUnit(CompilationUnit node) {
1115 CompilationUnit other = _other as CompilationUnit;
1116 return isEqualTokens(node.beginToken, other.beginToken) &&
1117 isEqualNodes(node.scriptTag, other.scriptTag) &&
1118 _isEqualNodeLists(node.directives, other.directives) &&
1119 _isEqualNodeLists(node.declarations, other.declarations) &&
1120 isEqualTokens(node.endToken, other.endToken);
1121 }
1122
1123 @override
1124 bool visitConditionalExpression(ConditionalExpression node) {
1125 ConditionalExpression other = _other as ConditionalExpression;
1126 return isEqualNodes(node.condition, other.condition) &&
1127 isEqualTokens(node.question, other.question) &&
1128 isEqualNodes(node.thenExpression, other.thenExpression) &&
1129 isEqualTokens(node.colon, other.colon) &&
1130 isEqualNodes(node.elseExpression, other.elseExpression);
1131 }
1132
1133 @override
1134 bool visitConfiguration(Configuration node) {
1135 Configuration other = _other as Configuration;
1136 return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
1137 isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
1138 isEqualNodes(node.name, other.name) &&
1139 isEqualTokens(node.equalToken, other.equalToken) &&
1140 isEqualNodes(node.value, other.value) &&
1141 isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
1142 isEqualNodes(node.libraryUri, other.libraryUri);
1143 }
1144
1145 @override
1146 bool visitConstructorDeclaration(ConstructorDeclaration node) {
1147 ConstructorDeclaration other = _other as ConstructorDeclaration;
1148 return isEqualNodes(
1149 node.documentationComment, other.documentationComment) &&
1150 _isEqualNodeLists(node.metadata, other.metadata) &&
1151 isEqualTokens(node.externalKeyword, other.externalKeyword) &&
1152 isEqualTokens(node.constKeyword, other.constKeyword) &&
1153 isEqualTokens(node.factoryKeyword, other.factoryKeyword) &&
1154 isEqualNodes(node.returnType, other.returnType) &&
1155 isEqualTokens(node.period, other.period) &&
1156 isEqualNodes(node.name, other.name) &&
1157 isEqualNodes(node.parameters, other.parameters) &&
1158 isEqualTokens(node.separator, other.separator) &&
1159 _isEqualNodeLists(node.initializers, other.initializers) &&
1160 isEqualNodes(node.redirectedConstructor, other.redirectedConstructor) &&
1161 isEqualNodes(node.body, other.body);
1162 }
1163
1164 @override
1165 bool visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
1166 ConstructorFieldInitializer other = _other as ConstructorFieldInitializer;
1167 return isEqualTokens(node.thisKeyword, other.thisKeyword) &&
1168 isEqualTokens(node.period, other.period) &&
1169 isEqualNodes(node.fieldName, other.fieldName) &&
1170 isEqualTokens(node.equals, other.equals) &&
1171 isEqualNodes(node.expression, other.expression);
1172 }
1173
1174 @override
1175 bool visitConstructorName(ConstructorName node) {
1176 ConstructorName other = _other as ConstructorName;
1177 return isEqualNodes(node.type, other.type) &&
1178 isEqualTokens(node.period, other.period) &&
1179 isEqualNodes(node.name, other.name);
1180 }
1181
1182 @override
1183 bool visitContinueStatement(ContinueStatement node) {
1184 ContinueStatement other = _other as ContinueStatement;
1185 return isEqualTokens(node.continueKeyword, other.continueKeyword) &&
1186 isEqualNodes(node.label, other.label) &&
1187 isEqualTokens(node.semicolon, other.semicolon);
1188 }
1189
1190 @override
1191 bool visitDeclaredIdentifier(DeclaredIdentifier node) {
1192 DeclaredIdentifier other = _other as DeclaredIdentifier;
1193 return isEqualNodes(
1194 node.documentationComment, other.documentationComment) &&
1195 _isEqualNodeLists(node.metadata, other.metadata) &&
1196 isEqualTokens(node.keyword, other.keyword) &&
1197 isEqualNodes(node.type, other.type) &&
1198 isEqualNodes(node.identifier, other.identifier);
1199 }
1200
1201 @override
1202 bool visitDefaultFormalParameter(DefaultFormalParameter node) {
1203 DefaultFormalParameter other = _other as DefaultFormalParameter;
1204 return isEqualNodes(node.parameter, other.parameter) &&
1205 node.kind == other.kind &&
1206 isEqualTokens(node.separator, other.separator) &&
1207 isEqualNodes(node.defaultValue, other.defaultValue);
1208 }
1209
1210 @override
1211 bool visitDoStatement(DoStatement node) {
1212 DoStatement other = _other as DoStatement;
1213 return isEqualTokens(node.doKeyword, other.doKeyword) &&
1214 isEqualNodes(node.body, other.body) &&
1215 isEqualTokens(node.whileKeyword, other.whileKeyword) &&
1216 isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
1217 isEqualNodes(node.condition, other.condition) &&
1218 isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
1219 isEqualTokens(node.semicolon, other.semicolon);
1220 }
1221
1222 @override
1223 bool visitDottedName(DottedName node) {
1224 DottedName other = _other as DottedName;
1225 return _isEqualNodeLists(node.components, other.components);
1226 }
1227
1228 @override
1229 bool visitDoubleLiteral(DoubleLiteral node) {
1230 DoubleLiteral other = _other as DoubleLiteral;
1231 return isEqualTokens(node.literal, other.literal) &&
1232 node.value == other.value;
1233 }
1234
1235 @override
1236 bool visitEmptyFunctionBody(EmptyFunctionBody node) {
1237 EmptyFunctionBody other = _other as EmptyFunctionBody;
1238 return isEqualTokens(node.semicolon, other.semicolon);
1239 }
1240
1241 @override
1242 bool visitEmptyStatement(EmptyStatement node) {
1243 EmptyStatement other = _other as EmptyStatement;
1244 return isEqualTokens(node.semicolon, other.semicolon);
1245 }
1246
1247 @override
1248 bool visitEnumConstantDeclaration(EnumConstantDeclaration node) {
1249 EnumConstantDeclaration other = _other as EnumConstantDeclaration;
1250 return isEqualNodes(
1251 node.documentationComment, other.documentationComment) &&
1252 _isEqualNodeLists(node.metadata, other.metadata) &&
1253 isEqualNodes(node.name, other.name);
1254 }
1255
1256 @override
1257 bool visitEnumDeclaration(EnumDeclaration node) {
1258 EnumDeclaration other = _other as EnumDeclaration;
1259 return isEqualNodes(
1260 node.documentationComment, other.documentationComment) &&
1261 _isEqualNodeLists(node.metadata, other.metadata) &&
1262 isEqualTokens(node.enumKeyword, other.enumKeyword) &&
1263 isEqualNodes(node.name, other.name) &&
1264 isEqualTokens(node.leftBracket, other.leftBracket) &&
1265 _isEqualNodeLists(node.constants, other.constants) &&
1266 isEqualTokens(node.rightBracket, other.rightBracket);
1267 }
1268
1269 @override
1270 bool visitExportDirective(ExportDirective node) {
1271 ExportDirective other = _other as ExportDirective;
1272 return isEqualNodes(
1273 node.documentationComment, other.documentationComment) &&
1274 _isEqualNodeLists(node.metadata, other.metadata) &&
1275 isEqualTokens(node.keyword, other.keyword) &&
1276 isEqualNodes(node.uri, other.uri) &&
1277 _isEqualNodeLists(node.combinators, other.combinators) &&
1278 isEqualTokens(node.semicolon, other.semicolon);
1279 }
1280
1281 @override
1282 bool visitExpressionFunctionBody(ExpressionFunctionBody node) {
1283 ExpressionFunctionBody other = _other as ExpressionFunctionBody;
1284 return isEqualTokens(node.functionDefinition, other.functionDefinition) &&
1285 isEqualNodes(node.expression, other.expression) &&
1286 isEqualTokens(node.semicolon, other.semicolon);
1287 }
1288
1289 @override
1290 bool visitExpressionStatement(ExpressionStatement node) {
1291 ExpressionStatement other = _other as ExpressionStatement;
1292 return isEqualNodes(node.expression, other.expression) &&
1293 isEqualTokens(node.semicolon, other.semicolon);
1294 }
1295
1296 @override
1297 bool visitExtendsClause(ExtendsClause node) {
1298 ExtendsClause other = _other as ExtendsClause;
1299 return isEqualTokens(node.extendsKeyword, other.extendsKeyword) &&
1300 isEqualNodes(node.superclass, other.superclass);
1301 }
1302
1303 @override
1304 bool visitFieldDeclaration(FieldDeclaration node) {
1305 FieldDeclaration other = _other as FieldDeclaration;
1306 return isEqualNodes(
1307 node.documentationComment, other.documentationComment) &&
1308 _isEqualNodeLists(node.metadata, other.metadata) &&
1309 isEqualTokens(node.staticKeyword, other.staticKeyword) &&
1310 isEqualNodes(node.fields, other.fields) &&
1311 isEqualTokens(node.semicolon, other.semicolon);
1312 }
1313
1314 @override
1315 bool visitFieldFormalParameter(FieldFormalParameter node) {
1316 FieldFormalParameter other = _other as FieldFormalParameter;
1317 return isEqualNodes(
1318 node.documentationComment, other.documentationComment) &&
1319 _isEqualNodeLists(node.metadata, other.metadata) &&
1320 isEqualTokens(node.keyword, other.keyword) &&
1321 isEqualNodes(node.type, other.type) &&
1322 isEqualTokens(node.thisKeyword, other.thisKeyword) &&
1323 isEqualTokens(node.period, other.period) &&
1324 isEqualNodes(node.identifier, other.identifier);
1325 }
1326
1327 @override
1328 bool visitForEachStatement(ForEachStatement node) {
1329 ForEachStatement other = _other as ForEachStatement;
1330 return isEqualTokens(node.forKeyword, other.forKeyword) &&
1331 isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
1332 isEqualNodes(node.loopVariable, other.loopVariable) &&
1333 isEqualTokens(node.inKeyword, other.inKeyword) &&
1334 isEqualNodes(node.iterable, other.iterable) &&
1335 isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
1336 isEqualNodes(node.body, other.body);
1337 }
1338
1339 @override
1340 bool visitFormalParameterList(FormalParameterList node) {
1341 FormalParameterList other = _other as FormalParameterList;
1342 return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
1343 _isEqualNodeLists(node.parameters, other.parameters) &&
1344 isEqualTokens(node.leftDelimiter, other.leftDelimiter) &&
1345 isEqualTokens(node.rightDelimiter, other.rightDelimiter) &&
1346 isEqualTokens(node.rightParenthesis, other.rightParenthesis);
1347 }
1348
1349 @override
1350 bool visitForStatement(ForStatement node) {
1351 ForStatement other = _other as ForStatement;
1352 return isEqualTokens(node.forKeyword, other.forKeyword) &&
1353 isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
1354 isEqualNodes(node.variables, other.variables) &&
1355 isEqualNodes(node.initialization, other.initialization) &&
1356 isEqualTokens(node.leftSeparator, other.leftSeparator) &&
1357 isEqualNodes(node.condition, other.condition) &&
1358 isEqualTokens(node.rightSeparator, other.rightSeparator) &&
1359 _isEqualNodeLists(node.updaters, other.updaters) &&
1360 isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
1361 isEqualNodes(node.body, other.body);
1362 }
1363
1364 @override
1365 bool visitFunctionDeclaration(FunctionDeclaration node) {
1366 FunctionDeclaration other = _other as FunctionDeclaration;
1367 return isEqualNodes(
1368 node.documentationComment, other.documentationComment) &&
1369 _isEqualNodeLists(node.metadata, other.metadata) &&
1370 isEqualTokens(node.externalKeyword, other.externalKeyword) &&
1371 isEqualNodes(node.returnType, other.returnType) &&
1372 isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
1373 isEqualNodes(node.name, other.name) &&
1374 isEqualNodes(node.functionExpression, other.functionExpression);
1375 }
1376
1377 @override
1378 bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
1379 FunctionDeclarationStatement other = _other as FunctionDeclarationStatement;
1380 return isEqualNodes(node.functionDeclaration, other.functionDeclaration);
1381 }
1382
1383 @override
1384 bool visitFunctionExpression(FunctionExpression node) {
1385 FunctionExpression other = _other as FunctionExpression;
1386 return isEqualNodes(node.parameters, other.parameters) &&
1387 isEqualNodes(node.body, other.body);
1388 }
1389
1390 @override
1391 bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
1392 FunctionExpressionInvocation other = _other as FunctionExpressionInvocation;
1393 return isEqualNodes(node.function, other.function) &&
1394 isEqualNodes(node.argumentList, other.argumentList);
1395 }
1396
1397 @override
1398 bool visitFunctionTypeAlias(FunctionTypeAlias node) {
1399 FunctionTypeAlias other = _other as FunctionTypeAlias;
1400 return isEqualNodes(
1401 node.documentationComment, other.documentationComment) &&
1402 _isEqualNodeLists(node.metadata, other.metadata) &&
1403 isEqualTokens(node.typedefKeyword, other.typedefKeyword) &&
1404 isEqualNodes(node.returnType, other.returnType) &&
1405 isEqualNodes(node.name, other.name) &&
1406 isEqualNodes(node.typeParameters, other.typeParameters) &&
1407 isEqualNodes(node.parameters, other.parameters) &&
1408 isEqualTokens(node.semicolon, other.semicolon);
1409 }
1410
1411 @override
1412 bool visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
1413 FunctionTypedFormalParameter other = _other as FunctionTypedFormalParameter;
1414 return isEqualNodes(
1415 node.documentationComment, other.documentationComment) &&
1416 _isEqualNodeLists(node.metadata, other.metadata) &&
1417 isEqualNodes(node.returnType, other.returnType) &&
1418 isEqualNodes(node.identifier, other.identifier) &&
1419 isEqualNodes(node.parameters, other.parameters);
1420 }
1421
1422 @override
1423 bool visitHideCombinator(HideCombinator node) {
1424 HideCombinator other = _other as HideCombinator;
1425 return isEqualTokens(node.keyword, other.keyword) &&
1426 _isEqualNodeLists(node.hiddenNames, other.hiddenNames);
1427 }
1428
1429 @override
1430 bool visitIfStatement(IfStatement node) {
1431 IfStatement other = _other as IfStatement;
1432 return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
1433 isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
1434 isEqualNodes(node.condition, other.condition) &&
1435 isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
1436 isEqualNodes(node.thenStatement, other.thenStatement) &&
1437 isEqualTokens(node.elseKeyword, other.elseKeyword) &&
1438 isEqualNodes(node.elseStatement, other.elseStatement);
1439 }
1440
1441 @override
1442 bool visitImplementsClause(ImplementsClause node) {
1443 ImplementsClause other = _other as ImplementsClause;
1444 return isEqualTokens(node.implementsKeyword, other.implementsKeyword) &&
1445 _isEqualNodeLists(node.interfaces, other.interfaces);
1446 }
1447
1448 @override
1449 bool visitImportDirective(ImportDirective node) {
1450 ImportDirective other = _other as ImportDirective;
1451 return isEqualNodes(
1452 node.documentationComment, other.documentationComment) &&
1453 _isEqualNodeLists(node.metadata, other.metadata) &&
1454 isEqualTokens(node.keyword, other.keyword) &&
1455 isEqualNodes(node.uri, other.uri) &&
1456 isEqualTokens(node.deferredKeyword, other.deferredKeyword) &&
1457 isEqualTokens(node.asKeyword, other.asKeyword) &&
1458 isEqualNodes(node.prefix, other.prefix) &&
1459 _isEqualNodeLists(node.combinators, other.combinators) &&
1460 isEqualTokens(node.semicolon, other.semicolon);
1461 }
1462
1463 @override
1464 bool visitIndexExpression(IndexExpression node) {
1465 IndexExpression other = _other as IndexExpression;
1466 return isEqualNodes(node.target, other.target) &&
1467 isEqualTokens(node.leftBracket, other.leftBracket) &&
1468 isEqualNodes(node.index, other.index) &&
1469 isEqualTokens(node.rightBracket, other.rightBracket);
1470 }
1471
1472 @override
1473 bool visitInstanceCreationExpression(InstanceCreationExpression node) {
1474 InstanceCreationExpression other = _other as InstanceCreationExpression;
1475 return isEqualTokens(node.keyword, other.keyword) &&
1476 isEqualNodes(node.constructorName, other.constructorName) &&
1477 isEqualNodes(node.argumentList, other.argumentList);
1478 }
1479
1480 @override
1481 bool visitIntegerLiteral(IntegerLiteral node) {
1482 IntegerLiteral other = _other as IntegerLiteral;
1483 return isEqualTokens(node.literal, other.literal) &&
1484 (node.value == other.value);
1485 }
1486
1487 @override
1488 bool visitInterpolationExpression(InterpolationExpression node) {
1489 InterpolationExpression other = _other as InterpolationExpression;
1490 return isEqualTokens(node.leftBracket, other.leftBracket) &&
1491 isEqualNodes(node.expression, other.expression) &&
1492 isEqualTokens(node.rightBracket, other.rightBracket);
1493 }
1494
1495 @override
1496 bool visitInterpolationString(InterpolationString node) {
1497 InterpolationString other = _other as InterpolationString;
1498 return isEqualTokens(node.contents, other.contents) &&
1499 node.value == other.value;
1500 }
1501
1502 @override
1503 bool visitIsExpression(IsExpression node) {
1504 IsExpression other = _other as IsExpression;
1505 return isEqualNodes(node.expression, other.expression) &&
1506 isEqualTokens(node.isOperator, other.isOperator) &&
1507 isEqualTokens(node.notOperator, other.notOperator) &&
1508 isEqualNodes(node.type, other.type);
1509 }
1510
1511 @override
1512 bool visitLabel(Label node) {
1513 Label other = _other as Label;
1514 return isEqualNodes(node.label, other.label) &&
1515 isEqualTokens(node.colon, other.colon);
1516 }
1517
1518 @override
1519 bool visitLabeledStatement(LabeledStatement node) {
1520 LabeledStatement other = _other as LabeledStatement;
1521 return _isEqualNodeLists(node.labels, other.labels) &&
1522 isEqualNodes(node.statement, other.statement);
1523 }
1524
1525 @override
1526 bool visitLibraryDirective(LibraryDirective node) {
1527 LibraryDirective other = _other as LibraryDirective;
1528 return isEqualNodes(
1529 node.documentationComment, other.documentationComment) &&
1530 _isEqualNodeLists(node.metadata, other.metadata) &&
1531 isEqualTokens(node.libraryKeyword, other.libraryKeyword) &&
1532 isEqualNodes(node.name, other.name) &&
1533 isEqualTokens(node.semicolon, other.semicolon);
1534 }
1535
1536 @override
1537 bool visitLibraryIdentifier(LibraryIdentifier node) {
1538 LibraryIdentifier other = _other as LibraryIdentifier;
1539 return _isEqualNodeLists(node.components, other.components);
1540 }
1541
1542 @override
1543 bool visitListLiteral(ListLiteral node) {
1544 ListLiteral other = _other as ListLiteral;
1545 return isEqualTokens(node.constKeyword, other.constKeyword) &&
1546 isEqualNodes(node.typeArguments, other.typeArguments) &&
1547 isEqualTokens(node.leftBracket, other.leftBracket) &&
1548 _isEqualNodeLists(node.elements, other.elements) &&
1549 isEqualTokens(node.rightBracket, other.rightBracket);
1550 }
1551
1552 @override
1553 bool visitMapLiteral(MapLiteral node) {
1554 MapLiteral other = _other as MapLiteral;
1555 return isEqualTokens(node.constKeyword, other.constKeyword) &&
1556 isEqualNodes(node.typeArguments, other.typeArguments) &&
1557 isEqualTokens(node.leftBracket, other.leftBracket) &&
1558 _isEqualNodeLists(node.entries, other.entries) &&
1559 isEqualTokens(node.rightBracket, other.rightBracket);
1560 }
1561
1562 @override
1563 bool visitMapLiteralEntry(MapLiteralEntry node) {
1564 MapLiteralEntry other = _other as MapLiteralEntry;
1565 return isEqualNodes(node.key, other.key) &&
1566 isEqualTokens(node.separator, other.separator) &&
1567 isEqualNodes(node.value, other.value);
1568 }
1569
1570 @override
1571 bool visitMethodDeclaration(MethodDeclaration node) {
1572 MethodDeclaration other = _other as MethodDeclaration;
1573 return isEqualNodes(
1574 node.documentationComment, other.documentationComment) &&
1575 _isEqualNodeLists(node.metadata, other.metadata) &&
1576 isEqualTokens(node.externalKeyword, other.externalKeyword) &&
1577 isEqualTokens(node.modifierKeyword, other.modifierKeyword) &&
1578 isEqualNodes(node.returnType, other.returnType) &&
1579 isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
1580 isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
1581 isEqualNodes(node.name, other.name) &&
1582 isEqualNodes(node.parameters, other.parameters) &&
1583 isEqualNodes(node.body, other.body);
1584 }
1585
1586 @override
1587 bool visitMethodInvocation(MethodInvocation node) {
1588 MethodInvocation other = _other as MethodInvocation;
1589 return isEqualNodes(node.target, other.target) &&
1590 isEqualTokens(node.operator, other.operator) &&
1591 isEqualNodes(node.methodName, other.methodName) &&
1592 isEqualNodes(node.argumentList, other.argumentList);
1593 }
1594
1595 @override
1596 bool visitNamedExpression(NamedExpression node) {
1597 NamedExpression other = _other as NamedExpression;
1598 return isEqualNodes(node.name, other.name) &&
1599 isEqualNodes(node.expression, other.expression);
1600 }
1601
1602 @override
1603 bool visitNativeClause(NativeClause node) {
1604 NativeClause other = _other as NativeClause;
1605 return isEqualTokens(node.nativeKeyword, other.nativeKeyword) &&
1606 isEqualNodes(node.name, other.name);
1607 }
1608
1609 @override
1610 bool visitNativeFunctionBody(NativeFunctionBody node) {
1611 NativeFunctionBody other = _other as NativeFunctionBody;
1612 return isEqualTokens(node.nativeKeyword, other.nativeKeyword) &&
1613 isEqualNodes(node.stringLiteral, other.stringLiteral) &&
1614 isEqualTokens(node.semicolon, other.semicolon);
1615 }
1616
1617 @override
1618 bool visitNullLiteral(NullLiteral node) {
1619 NullLiteral other = _other as NullLiteral;
1620 return isEqualTokens(node.literal, other.literal);
1621 }
1622
1623 @override
1624 bool visitParenthesizedExpression(ParenthesizedExpression node) {
1625 ParenthesizedExpression other = _other as ParenthesizedExpression;
1626 return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
1627 isEqualNodes(node.expression, other.expression) &&
1628 isEqualTokens(node.rightParenthesis, other.rightParenthesis);
1629 }
1630
1631 @override
1632 bool visitPartDirective(PartDirective node) {
1633 PartDirective other = _other as PartDirective;
1634 return isEqualNodes(
1635 node.documentationComment, other.documentationComment) &&
1636 _isEqualNodeLists(node.metadata, other.metadata) &&
1637 isEqualTokens(node.partKeyword, other.partKeyword) &&
1638 isEqualNodes(node.uri, other.uri) &&
1639 isEqualTokens(node.semicolon, other.semicolon);
1640 }
1641
1642 @override
1643 bool visitPartOfDirective(PartOfDirective node) {
1644 PartOfDirective other = _other as PartOfDirective;
1645 return isEqualNodes(
1646 node.documentationComment, other.documentationComment) &&
1647 _isEqualNodeLists(node.metadata, other.metadata) &&
1648 isEqualTokens(node.partKeyword, other.partKeyword) &&
1649 isEqualTokens(node.ofKeyword, other.ofKeyword) &&
1650 isEqualNodes(node.libraryName, other.libraryName) &&
1651 isEqualTokens(node.semicolon, other.semicolon);
1652 }
1653
1654 @override
1655 bool visitPostfixExpression(PostfixExpression node) {
1656 PostfixExpression other = _other as PostfixExpression;
1657 return isEqualNodes(node.operand, other.operand) &&
1658 isEqualTokens(node.operator, other.operator);
1659 }
1660
1661 @override
1662 bool visitPrefixedIdentifier(PrefixedIdentifier node) {
1663 PrefixedIdentifier other = _other as PrefixedIdentifier;
1664 return isEqualNodes(node.prefix, other.prefix) &&
1665 isEqualTokens(node.period, other.period) &&
1666 isEqualNodes(node.identifier, other.identifier);
1667 }
1668
1669 @override
1670 bool visitPrefixExpression(PrefixExpression node) {
1671 PrefixExpression other = _other as PrefixExpression;
1672 return isEqualTokens(node.operator, other.operator) &&
1673 isEqualNodes(node.operand, other.operand);
1674 }
1675
1676 @override
1677 bool visitPropertyAccess(PropertyAccess node) {
1678 PropertyAccess other = _other as PropertyAccess;
1679 return isEqualNodes(node.target, other.target) &&
1680 isEqualTokens(node.operator, other.operator) &&
1681 isEqualNodes(node.propertyName, other.propertyName);
1682 }
1683
1684 @override
1685 bool visitRedirectingConstructorInvocation(
1686 RedirectingConstructorInvocation node) {
1687 RedirectingConstructorInvocation other =
1688 _other as RedirectingConstructorInvocation;
1689 return isEqualTokens(node.thisKeyword, other.thisKeyword) &&
1690 isEqualTokens(node.period, other.period) &&
1691 isEqualNodes(node.constructorName, other.constructorName) &&
1692 isEqualNodes(node.argumentList, other.argumentList);
1693 }
1694
1695 @override
1696 bool visitRethrowExpression(RethrowExpression node) {
1697 RethrowExpression other = _other as RethrowExpression;
1698 return isEqualTokens(node.rethrowKeyword, other.rethrowKeyword);
1699 }
1700
1701 @override
1702 bool visitReturnStatement(ReturnStatement node) {
1703 ReturnStatement other = _other as ReturnStatement;
1704 return isEqualTokens(node.returnKeyword, other.returnKeyword) &&
1705 isEqualNodes(node.expression, other.expression) &&
1706 isEqualTokens(node.semicolon, other.semicolon);
1707 }
1708
1709 @override
1710 bool visitScriptTag(ScriptTag node) {
1711 ScriptTag other = _other as ScriptTag;
1712 return isEqualTokens(node.scriptTag, other.scriptTag);
1713 }
1714
1715 @override
1716 bool visitShowCombinator(ShowCombinator node) {
1717 ShowCombinator other = _other as ShowCombinator;
1718 return isEqualTokens(node.keyword, other.keyword) &&
1719 _isEqualNodeLists(node.shownNames, other.shownNames);
1720 }
1721
1722 @override
1723 bool visitSimpleFormalParameter(SimpleFormalParameter node) {
1724 SimpleFormalParameter other = _other as SimpleFormalParameter;
1725 return isEqualNodes(
1726 node.documentationComment, other.documentationComment) &&
1727 _isEqualNodeLists(node.metadata, other.metadata) &&
1728 isEqualTokens(node.keyword, other.keyword) &&
1729 isEqualNodes(node.type, other.type) &&
1730 isEqualNodes(node.identifier, other.identifier);
1731 }
1732
1733 @override
1734 bool visitSimpleIdentifier(SimpleIdentifier node) {
1735 SimpleIdentifier other = _other as SimpleIdentifier;
1736 return isEqualTokens(node.token, other.token);
1737 }
1738
1739 @override
1740 bool visitSimpleStringLiteral(SimpleStringLiteral node) {
1741 SimpleStringLiteral other = _other as SimpleStringLiteral;
1742 return isEqualTokens(node.literal, other.literal) &&
1743 (node.value == other.value);
1744 }
1745
1746 @override
1747 bool visitStringInterpolation(StringInterpolation node) {
1748 StringInterpolation other = _other as StringInterpolation;
1749 return _isEqualNodeLists(node.elements, other.elements);
1750 }
1751
1752 @override
1753 bool visitSuperConstructorInvocation(SuperConstructorInvocation node) {
1754 SuperConstructorInvocation other = _other as SuperConstructorInvocation;
1755 return isEqualTokens(node.superKeyword, other.superKeyword) &&
1756 isEqualTokens(node.period, other.period) &&
1757 isEqualNodes(node.constructorName, other.constructorName) &&
1758 isEqualNodes(node.argumentList, other.argumentList);
1759 }
1760
1761 @override
1762 bool visitSuperExpression(SuperExpression node) {
1763 SuperExpression other = _other as SuperExpression;
1764 return isEqualTokens(node.superKeyword, other.superKeyword);
1765 }
1766
1767 @override
1768 bool visitSwitchCase(SwitchCase node) {
1769 SwitchCase other = _other as SwitchCase;
1770 return _isEqualNodeLists(node.labels, other.labels) &&
1771 isEqualTokens(node.keyword, other.keyword) &&
1772 isEqualNodes(node.expression, other.expression) &&
1773 isEqualTokens(node.colon, other.colon) &&
1774 _isEqualNodeLists(node.statements, other.statements);
1775 }
1776
1777 @override
1778 bool visitSwitchDefault(SwitchDefault node) {
1779 SwitchDefault other = _other as SwitchDefault;
1780 return _isEqualNodeLists(node.labels, other.labels) &&
1781 isEqualTokens(node.keyword, other.keyword) &&
1782 isEqualTokens(node.colon, other.colon) &&
1783 _isEqualNodeLists(node.statements, other.statements);
1784 }
1785
1786 @override
1787 bool visitSwitchStatement(SwitchStatement node) {
1788 SwitchStatement other = _other as SwitchStatement;
1789 return isEqualTokens(node.switchKeyword, other.switchKeyword) &&
1790 isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
1791 isEqualNodes(node.expression, other.expression) &&
1792 isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
1793 isEqualTokens(node.leftBracket, other.leftBracket) &&
1794 _isEqualNodeLists(node.members, other.members) &&
1795 isEqualTokens(node.rightBracket, other.rightBracket);
1796 }
1797
1798 @override
1799 bool visitSymbolLiteral(SymbolLiteral node) {
1800 SymbolLiteral other = _other as SymbolLiteral;
1801 return isEqualTokens(node.poundSign, other.poundSign) &&
1802 _isEqualTokenLists(node.components, other.components);
1803 }
1804
1805 @override
1806 bool visitThisExpression(ThisExpression node) {
1807 ThisExpression other = _other as ThisExpression;
1808 return isEqualTokens(node.thisKeyword, other.thisKeyword);
1809 }
1810
1811 @override
1812 bool visitThrowExpression(ThrowExpression node) {
1813 ThrowExpression other = _other as ThrowExpression;
1814 return isEqualTokens(node.throwKeyword, other.throwKeyword) &&
1815 isEqualNodes(node.expression, other.expression);
1816 }
1817
1818 @override
1819 bool visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
1820 TopLevelVariableDeclaration other = _other as TopLevelVariableDeclaration;
1821 return isEqualNodes(
1822 node.documentationComment, other.documentationComment) &&
1823 _isEqualNodeLists(node.metadata, other.metadata) &&
1824 isEqualNodes(node.variables, other.variables) &&
1825 isEqualTokens(node.semicolon, other.semicolon);
1826 }
1827
1828 @override
1829 bool visitTryStatement(TryStatement node) {
1830 TryStatement other = _other as TryStatement;
1831 return isEqualTokens(node.tryKeyword, other.tryKeyword) &&
1832 isEqualNodes(node.body, other.body) &&
1833 _isEqualNodeLists(node.catchClauses, other.catchClauses) &&
1834 isEqualTokens(node.finallyKeyword, other.finallyKeyword) &&
1835 isEqualNodes(node.finallyBlock, other.finallyBlock);
1836 }
1837
1838 @override
1839 bool visitTypeArgumentList(TypeArgumentList node) {
1840 TypeArgumentList other = _other as TypeArgumentList;
1841 return isEqualTokens(node.leftBracket, other.leftBracket) &&
1842 _isEqualNodeLists(node.arguments, other.arguments) &&
1843 isEqualTokens(node.rightBracket, other.rightBracket);
1844 }
1845
1846 @override
1847 bool visitTypeName(TypeName node) {
1848 TypeName other = _other as TypeName;
1849 return isEqualNodes(node.name, other.name) &&
1850 isEqualNodes(node.typeArguments, other.typeArguments);
1851 }
1852
1853 @override
1854 bool visitTypeParameter(TypeParameter node) {
1855 TypeParameter other = _other as TypeParameter;
1856 return isEqualNodes(
1857 node.documentationComment, other.documentationComment) &&
1858 _isEqualNodeLists(node.metadata, other.metadata) &&
1859 isEqualNodes(node.name, other.name) &&
1860 isEqualTokens(node.extendsKeyword, other.extendsKeyword) &&
1861 isEqualNodes(node.bound, other.bound);
1862 }
1863
1864 @override
1865 bool visitTypeParameterList(TypeParameterList node) {
1866 TypeParameterList other = _other as TypeParameterList;
1867 return isEqualTokens(node.leftBracket, other.leftBracket) &&
1868 _isEqualNodeLists(node.typeParameters, other.typeParameters) &&
1869 isEqualTokens(node.rightBracket, other.rightBracket);
1870 }
1871
1872 @override
1873 bool visitVariableDeclaration(VariableDeclaration node) {
1874 VariableDeclaration other = _other as VariableDeclaration;
1875 return isEqualNodes(
1876 node.documentationComment, other.documentationComment) &&
1877 _isEqualNodeLists(node.metadata, other.metadata) &&
1878 isEqualNodes(node.name, other.name) &&
1879 isEqualTokens(node.equals, other.equals) &&
1880 isEqualNodes(node.initializer, other.initializer);
1881 }
1882
1883 @override
1884 bool visitVariableDeclarationList(VariableDeclarationList node) {
1885 VariableDeclarationList other = _other as VariableDeclarationList;
1886 return isEqualNodes(
1887 node.documentationComment, other.documentationComment) &&
1888 _isEqualNodeLists(node.metadata, other.metadata) &&
1889 isEqualTokens(node.keyword, other.keyword) &&
1890 isEqualNodes(node.type, other.type) &&
1891 _isEqualNodeLists(node.variables, other.variables);
1892 }
1893
1894 @override
1895 bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
1896 VariableDeclarationStatement other = _other as VariableDeclarationStatement;
1897 return isEqualNodes(node.variables, other.variables) &&
1898 isEqualTokens(node.semicolon, other.semicolon);
1899 }
1900
1901 @override
1902 bool visitWhileStatement(WhileStatement node) {
1903 WhileStatement other = _other as WhileStatement;
1904 return isEqualTokens(node.whileKeyword, other.whileKeyword) &&
1905 isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
1906 isEqualNodes(node.condition, other.condition) &&
1907 isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
1908 isEqualNodes(node.body, other.body);
1909 }
1910
1911 @override
1912 bool visitWithClause(WithClause node) {
1913 WithClause other = _other as WithClause;
1914 return isEqualTokens(node.withKeyword, other.withKeyword) &&
1915 _isEqualNodeLists(node.mixinTypes, other.mixinTypes);
1916 }
1917
1918 @override
1919 bool visitYieldStatement(YieldStatement node) {
1920 YieldStatement other = _other as YieldStatement;
1921 return isEqualTokens(node.yieldKeyword, other.yieldKeyword) &&
1922 isEqualNodes(node.expression, other.expression) &&
1923 isEqualTokens(node.semicolon, other.semicolon);
1924 }
1925
1926 /**
1927 * Return `true` if the [first] and [second] lists of AST nodes have the same
1928 * size and corresponding elements are equal.
1929 */
1930 bool _isEqualNodeLists(NodeList first, NodeList second) {
1931 if (first == null) {
1932 return second == null;
1933 } else if (second == null) {
1934 return false;
1935 }
1936 int size = first.length;
1937 if (second.length != size) {
1938 return false;
1939 }
1940 for (int i = 0; i < size; i++) {
1941 if (!isEqualNodes(first[i], second[i])) {
1942 return false;
1943 }
1944 }
1945 return true;
1946 }
1947
1948 /**
1949 * Return `true` if the [first] and [second] lists of tokens have the same
1950 * length and corresponding elements are equal.
1951 */
1952 bool _isEqualTokenLists(List<Token> first, List<Token> second) {
1953 int length = first.length;
1954 if (second.length != length) {
1955 return false;
1956 }
1957 for (int i = 0; i < length; i++) {
1958 if (!isEqualTokens(first[i], second[i])) {
1959 return false;
1960 }
1961 }
1962 return true;
1963 }
1964
1965 /**
1966 * Return `true` if the [first] and [second] nodes are equal.
1967 */
1968 static bool equalNodes(AstNode first, AstNode second) {
1969 AstComparator comparator = new AstComparator();
1970 return comparator.isEqualNodes(first, second);
1971 }
1972 }
1973
1974 /**
1975 * Instances of the class [ConstantEvaluator] evaluate constant expressions to
1976 * produce their compile-time value.
1977 *
1978 * According to the Dart Language Specification:
1979 *
1980 * > A constant expression is one of the following:
1981 * >
1982 * > * A literal number.
1983 * > * A literal boolean.
1984 * > * A literal string where any interpolated expression is a compile-time
1985 * > constant that evaluates to a numeric, string or boolean value or to
1986 * > **null**.
1987 * > * A literal symbol.
1988 * > * **null**.
1989 * > * A qualified reference to a static constant variable.
1990 * > * An identifier expression that denotes a constant variable, class or type
1991 * > alias.
1992 * > * A constant constructor invocation.
1993 * > * A constant list literal.
1994 * > * A constant map literal.
1995 * > * A simple or qualified identifier denoting a top-level function or a
1996 * > static method.
1997 * > * A parenthesized expression _(e)_ where _e_ is a constant expression.
1998 * > * <span>
1999 * > An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i>
2000 * > where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
2001 * > expressions and <i>identical()</i> is statically bound to the predefined
2002 * > dart function <i>identical()</i> discussed above.
2003 * > </span>
2004 * > * <span>
2005 * > An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i>
2006 * > or <i>e<sub>1</sub> != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and
2007 * > <i>e<sub>2</sub></i> are constant expressions that evaluate to a
2008 * > numeric, string or boolean value.
2009 * > </span>
2010 * > * <span>
2011 * > An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp;
2012 * > e<sub>2</sub></i> or <i>e<sub>1</sub> || e<sub>2</sub></i>, where
2013 * > <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
2014 * > expressions that evaluate to a boolean value.
2015 * > </span>
2016 * > * <span>
2017 * > An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^
2018 * > e<sub>2</sub></i>, <i>e<sub>1</sub> &amp; e<sub>2</sub></i>,
2019 * > <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;&gt;
2020 * > e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where
2021 * > <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
2022 * > expressions that evaluate to an integer value or to <b>null</b>.
2023 * > </span>
2024 * > * <span>
2025 * > An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> +
2026 * > e<sub>2</sub></i>, <i>e<sub>1</sub> -e<sub>2</sub></i>,
2027 * > <i>e<sub>1</sub> * e<sub>2</sub></i>, <i>e<sub>1</sub> /
2028 * > e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>,
2029 * > <i>e<sub>1</sub> &gt; e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;
2030 * > e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;= e<sub>2</sub></i>,
2031 * > <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or <i>e<sub>1</sub> %
2032 * > e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and
2033 * > <i>e<sub>2</sub></i> are constant expressions that evaluate to a numeric
2034 * > value or to <b>null</b>.
2035 * > </span>
2036 * > * <span>
2037 * > An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> :
2038 * > e<sub>3</sub></i> where <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and
2039 * > <i>e<sub>3</sub></i> are constant expressions, and <i>e<sub>1</sub></i>
2040 * > evaluates to a boolean value.
2041 * > </span>
2042 *
2043 * The values returned by instances of this class are therefore `null` and
2044 * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and
2045 * `DartObject`.
2046 *
2047 * In addition, this class defines several values that can be returned to
2048 * indicate various conditions encountered during evaluation. These are
2049 * documented with the static fields that define those values.
2050 */
2051 class ConstantEvaluator extends GeneralizingAstVisitor<Object> {
2052 /**
2053 * The value returned for expressions (or non-expression nodes) that are not
2054 * compile-time constant expressions.
2055 */
2056 static Object NOT_A_CONSTANT = new Object();
2057
2058 @override
2059 Object visitAdjacentStrings(AdjacentStrings node) {
2060 StringBuffer buffer = new StringBuffer();
2061 for (StringLiteral string in node.strings) {
2062 Object value = string.accept(this);
2063 if (identical(value, NOT_A_CONSTANT)) {
2064 return value;
2065 }
2066 buffer.write(value);
2067 }
2068 return buffer.toString();
2069 }
2070
2071 @override
2072 Object visitBinaryExpression(BinaryExpression node) {
2073 Object leftOperand = node.leftOperand.accept(this);
2074 if (identical(leftOperand, NOT_A_CONSTANT)) {
2075 return leftOperand;
2076 }
2077 Object rightOperand = node.rightOperand.accept(this);
2078 if (identical(rightOperand, NOT_A_CONSTANT)) {
2079 return rightOperand;
2080 }
2081 while (true) {
2082 if (node.operator.type == TokenType.AMPERSAND) {
2083 // integer or {@code null}
2084 if (leftOperand is int && rightOperand is int) {
2085 return leftOperand & rightOperand;
2086 }
2087 } else if (node.operator.type == TokenType.AMPERSAND_AMPERSAND) {
2088 // boolean or {@code null}
2089 if (leftOperand is bool && rightOperand is bool) {
2090 return leftOperand && rightOperand;
2091 }
2092 } else if (node.operator.type == TokenType.BANG_EQ) {
2093 // numeric, string, boolean, or {@code null}
2094 if (leftOperand is bool && rightOperand is bool) {
2095 return leftOperand != rightOperand;
2096 } else if (leftOperand is num && rightOperand is num) {
2097 return leftOperand != rightOperand;
2098 } else if (leftOperand is String && rightOperand is String) {
2099 return leftOperand != rightOperand;
2100 }
2101 } else if (node.operator.type == TokenType.BAR) {
2102 // integer or {@code null}
2103 if (leftOperand is int && rightOperand is int) {
2104 return leftOperand | rightOperand;
2105 }
2106 } else if (node.operator.type == TokenType.BAR_BAR) {
2107 // boolean or {@code null}
2108 if (leftOperand is bool && rightOperand is bool) {
2109 return leftOperand || rightOperand;
2110 }
2111 } else if (node.operator.type == TokenType.CARET) {
2112 // integer or {@code null}
2113 if (leftOperand is int && rightOperand is int) {
2114 return leftOperand ^ rightOperand;
2115 }
2116 } else if (node.operator.type == TokenType.EQ_EQ) {
2117 // numeric, string, boolean, or {@code null}
2118 if (leftOperand is bool && rightOperand is bool) {
2119 return leftOperand == rightOperand;
2120 } else if (leftOperand is num && rightOperand is num) {
2121 return leftOperand == rightOperand;
2122 } else if (leftOperand is String && rightOperand is String) {
2123 return leftOperand == rightOperand;
2124 }
2125 } else if (node.operator.type == TokenType.GT) {
2126 // numeric or {@code null}
2127 if (leftOperand is num && rightOperand is num) {
2128 return leftOperand.compareTo(rightOperand) > 0;
2129 }
2130 } else if (node.operator.type == TokenType.GT_EQ) {
2131 // numeric or {@code null}
2132 if (leftOperand is num && rightOperand is num) {
2133 return leftOperand.compareTo(rightOperand) >= 0;
2134 }
2135 } else if (node.operator.type == TokenType.GT_GT) {
2136 // integer or {@code null}
2137 if (leftOperand is int && rightOperand is int) {
2138 return leftOperand >> rightOperand;
2139 }
2140 } else if (node.operator.type == TokenType.LT) {
2141 // numeric or {@code null}
2142 if (leftOperand is num && rightOperand is num) {
2143 return leftOperand.compareTo(rightOperand) < 0;
2144 }
2145 } else if (node.operator.type == TokenType.LT_EQ) {
2146 // numeric or {@code null}
2147 if (leftOperand is num && rightOperand is num) {
2148 return leftOperand.compareTo(rightOperand) <= 0;
2149 }
2150 } else if (node.operator.type == TokenType.LT_LT) {
2151 // integer or {@code null}
2152 if (leftOperand is int && rightOperand is int) {
2153 return leftOperand << rightOperand;
2154 }
2155 } else if (node.operator.type == TokenType.MINUS) {
2156 // numeric or {@code null}
2157 if (leftOperand is num && rightOperand is num) {
2158 return leftOperand - rightOperand;
2159 }
2160 } else if (node.operator.type == TokenType.PERCENT) {
2161 // numeric or {@code null}
2162 if (leftOperand is num && rightOperand is num) {
2163 return leftOperand.remainder(rightOperand);
2164 }
2165 } else if (node.operator.type == TokenType.PLUS) {
2166 // numeric or {@code null}
2167 if (leftOperand is num && rightOperand is num) {
2168 return leftOperand + rightOperand;
2169 }
2170 } else if (node.operator.type == TokenType.STAR) {
2171 // numeric or {@code null}
2172 if (leftOperand is num && rightOperand is num) {
2173 return leftOperand * rightOperand;
2174 }
2175 } else if (node.operator.type == TokenType.SLASH) {
2176 // numeric or {@code null}
2177 if (leftOperand is num && rightOperand is num) {
2178 return leftOperand / rightOperand;
2179 }
2180 } else if (node.operator.type == TokenType.TILDE_SLASH) {
2181 // numeric or {@code null}
2182 if (leftOperand is num && rightOperand is num) {
2183 return leftOperand ~/ rightOperand;
2184 }
2185 } else {}
2186 break;
2187 }
2188 // TODO(brianwilkerson) This doesn't handle numeric conversions.
2189 return visitExpression(node);
2190 }
2191
2192 @override
2193 Object visitBooleanLiteral(BooleanLiteral node) => node.value ? true : false;
2194
2195 @override
2196 Object visitDoubleLiteral(DoubleLiteral node) => node.value;
2197
2198 @override
2199 Object visitIntegerLiteral(IntegerLiteral node) => node.value;
2200
2201 @override
2202 Object visitInterpolationExpression(InterpolationExpression node) {
2203 Object value = node.expression.accept(this);
2204 if (value == null || value is bool || value is String || value is num) {
2205 return value;
2206 }
2207 return NOT_A_CONSTANT;
2208 }
2209
2210 @override
2211 Object visitInterpolationString(InterpolationString node) => node.value;
2212
2213 @override
2214 Object visitListLiteral(ListLiteral node) {
2215 List<Object> list = new List<Object>();
2216 for (Expression element in node.elements) {
2217 Object value = element.accept(this);
2218 if (identical(value, NOT_A_CONSTANT)) {
2219 return value;
2220 }
2221 list.add(value);
2222 }
2223 return list;
2224 }
2225
2226 @override
2227 Object visitMapLiteral(MapLiteral node) {
2228 HashMap<String, Object> map = new HashMap<String, Object>();
2229 for (MapLiteralEntry entry in node.entries) {
2230 Object key = entry.key.accept(this);
2231 Object value = entry.value.accept(this);
2232 if (key is! String || identical(value, NOT_A_CONSTANT)) {
2233 return NOT_A_CONSTANT;
2234 }
2235 map[(key as String)] = value;
2236 }
2237 return map;
2238 }
2239
2240 @override
2241 Object visitMethodInvocation(MethodInvocation node) => visitNode(node);
2242
2243 @override
2244 Object visitNode(AstNode node) => NOT_A_CONSTANT;
2245
2246 @override
2247 Object visitNullLiteral(NullLiteral node) => null;
2248
2249 @override
2250 Object visitParenthesizedExpression(ParenthesizedExpression node) =>
2251 node.expression.accept(this);
2252
2253 @override
2254 Object visitPrefixedIdentifier(PrefixedIdentifier node) =>
2255 _getConstantValue(null);
2256
2257 @override
2258 Object visitPrefixExpression(PrefixExpression node) {
2259 Object operand = node.operand.accept(this);
2260 if (identical(operand, NOT_A_CONSTANT)) {
2261 return operand;
2262 }
2263 while (true) {
2264 if (node.operator.type == TokenType.BANG) {
2265 if (identical(operand, true)) {
2266 return false;
2267 } else if (identical(operand, false)) {
2268 return true;
2269 }
2270 } else if (node.operator.type == TokenType.TILDE) {
2271 if (operand is int) {
2272 return ~operand;
2273 }
2274 } else if (node.operator.type == TokenType.MINUS) {
2275 if (operand == null) {
2276 return null;
2277 } else if (operand is num) {
2278 return -operand;
2279 }
2280 } else {}
2281 break;
2282 }
2283 return NOT_A_CONSTANT;
2284 }
2285
2286 @override
2287 Object visitPropertyAccess(PropertyAccess node) => _getConstantValue(null);
2288
2289 @override
2290 Object visitSimpleIdentifier(SimpleIdentifier node) =>
2291 _getConstantValue(null);
2292
2293 @override
2294 Object visitSimpleStringLiteral(SimpleStringLiteral node) => node.value;
2295
2296 @override
2297 Object visitStringInterpolation(StringInterpolation node) {
2298 StringBuffer buffer = new StringBuffer();
2299 for (InterpolationElement element in node.elements) {
2300 Object value = element.accept(this);
2301 if (identical(value, NOT_A_CONSTANT)) {
2302 return value;
2303 }
2304 buffer.write(value);
2305 }
2306 return buffer.toString();
2307 }
2308
2309 @override
2310 Object visitSymbolLiteral(SymbolLiteral node) {
2311 // TODO(brianwilkerson) This isn't optimal because a Symbol is not a String.
2312 StringBuffer buffer = new StringBuffer();
2313 for (Token component in node.components) {
2314 if (buffer.length > 0) {
2315 buffer.writeCharCode(0x2E);
2316 }
2317 buffer.write(component.lexeme);
2318 }
2319 return buffer.toString();
2320 }
2321
2322 /**
2323 * Return the constant value of the static constant represented by the given
2324 * [element].
2325 */
2326 Object _getConstantValue(Element element) {
2327 // TODO(brianwilkerson) Implement this
2328 if (element is FieldElement) {
2329 FieldElement field = element;
2330 if (field.isStatic && field.isConst) {
2331 //field.getConstantValue();
2332 }
2333 // } else if (element instanceof VariableElement) {
2334 // VariableElement variable = (VariableElement) element;
2335 // if (variable.isStatic() && variable.isConst()) {
2336 // //variable.getConstantValue();
2337 // }
2338 }
2339 return NOT_A_CONSTANT;
2340 }
2341 }
2342
2343 /**
2344 * A recursive AST visitor that is used to run over [Expression]s to determine
2345 * whether the expression is composed by at least one deferred
2346 * [PrefixedIdentifier].
2347 *
2348 * See [PrefixedIdentifier.isDeferred].
2349 */
2350 class DeferredLibraryReferenceDetector extends RecursiveAstVisitor<Object> {
2351 /**
2352 * A flag indicating whether an identifier from a deferred library has been
2353 * found.
2354 */
2355 bool _result = false;
2356
2357 /**
2358 * Return `true` if the visitor found a [PrefixedIdentifier] that returned
2359 * `true` to the [PrefixedIdentifier.isDeferred] query.
2360 */
2361 bool get result => _result;
2362
2363 @override
2364 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
2365 if (!_result) {
2366 if (node.isDeferred) {
2367 _result = true;
2368 }
2369 }
2370 return null;
2371 }
2372 }
2373
2374 /**
2375 * An object used to locate the [Element] associated with a given [AstNode].
2376 */
2377 class ElementLocator {
2378 /**
2379 * Return the element associated with the given [node], or `null` if there is
2380 * no element associated with the node.
2381 */
2382 static Element locate(AstNode node) {
2383 if (node == null) {
2384 return null;
2385 }
2386 ElementLocator_ElementMapper mapper = new ElementLocator_ElementMapper();
2387 return node.accept(mapper);
2388 }
2389 }
2390
2391 /**
2392 * Visitor that maps nodes to elements.
2393 */
2394 class ElementLocator_ElementMapper extends GeneralizingAstVisitor<Element> {
2395 @override
2396 Element visitAnnotation(Annotation node) => node.element;
2397
2398 @override
2399 Element visitAssignmentExpression(AssignmentExpression node) =>
2400 node.bestElement;
2401
2402 @override
2403 Element visitBinaryExpression(BinaryExpression node) => node.bestElement;
2404
2405 @override
2406 Element visitClassDeclaration(ClassDeclaration node) => node.element;
2407
2408 @override
2409 Element visitCompilationUnit(CompilationUnit node) => node.element;
2410
2411 @override
2412 Element visitConstructorDeclaration(ConstructorDeclaration node) =>
2413 node.element;
2414
2415 @override
2416 Element visitFunctionDeclaration(FunctionDeclaration node) => node.element;
2417
2418 @override
2419 Element visitIdentifier(Identifier node) {
2420 AstNode parent = node.parent;
2421 // Type name in Annotation
2422 if (parent is Annotation) {
2423 Annotation annotation = parent;
2424 if (identical(annotation.name, node) &&
2425 annotation.constructorName == null) {
2426 return annotation.element;
2427 }
2428 }
2429 // Extra work to map Constructor Declarations to their associated
2430 // Constructor Elements
2431 if (parent is ConstructorDeclaration) {
2432 Identifier returnType = parent.returnType;
2433 if (identical(returnType, node)) {
2434 SimpleIdentifier name = parent.name;
2435 if (name != null) {
2436 return name.bestElement;
2437 }
2438 Element element = node.bestElement;
2439 if (element is ClassElement) {
2440 return element.unnamedConstructor;
2441 }
2442 }
2443 }
2444 if (parent is LibraryIdentifier) {
2445 AstNode grandParent = parent.parent;
2446 if (grandParent is PartOfDirective) {
2447 Element element = grandParent.element;
2448 if (element is LibraryElement) {
2449 return element.definingCompilationUnit;
2450 }
2451 }
2452 }
2453 return node.bestElement;
2454 }
2455
2456 @override
2457 Element visitImportDirective(ImportDirective node) => node.element;
2458
2459 @override
2460 Element visitIndexExpression(IndexExpression node) => node.bestElement;
2461
2462 @override
2463 Element visitInstanceCreationExpression(InstanceCreationExpression node) =>
2464 node.staticElement;
2465
2466 @override
2467 Element visitLibraryDirective(LibraryDirective node) => node.element;
2468
2469 @override
2470 Element visitMethodDeclaration(MethodDeclaration node) => node.element;
2471
2472 @override
2473 Element visitMethodInvocation(MethodInvocation node) =>
2474 node.methodName.bestElement;
2475
2476 @override
2477 Element visitPartOfDirective(PartOfDirective node) => node.element;
2478
2479 @override
2480 Element visitPostfixExpression(PostfixExpression node) => node.bestElement;
2481
2482 @override
2483 Element visitPrefixedIdentifier(PrefixedIdentifier node) => node.bestElement;
2484
2485 @override
2486 Element visitPrefixExpression(PrefixExpression node) => node.bestElement;
2487
2488 @override
2489 Element visitStringLiteral(StringLiteral node) {
2490 AstNode parent = node.parent;
2491 if (parent is UriBasedDirective) {
2492 return parent.uriElement;
2493 }
2494 return null;
2495 }
2496
2497 @override
2498 Element visitVariableDeclaration(VariableDeclaration node) => node.element;
2499 }
2500
2501 /**
2502 * An object that will clone any AST structure that it visits. The cloner will
2503 * clone the structure, replacing the specified ASTNode with a new ASTNode,
2504 * mapping the old token stream to a new token stream, and preserving resolution
2505 * results.
2506 */
2507 class IncrementalAstCloner implements AstVisitor<AstNode> {
2508 /**
2509 * The node to be replaced during the cloning process.
2510 */
2511 final AstNode _oldNode;
2512
2513 /**
2514 * The replacement node used during the cloning process.
2515 */
2516 final AstNode _newNode;
2517
2518 /**
2519 * A mapping of old tokens to new tokens used during the cloning process.
2520 */
2521 final TokenMap _tokenMap;
2522
2523 /**
2524 * Construct a new instance that will replace the [oldNode] with the [newNode]
2525 * in the process of cloning an existing AST structure. The [tokenMap] is a
2526 * mapping of old tokens to new tokens.
2527 */
2528 IncrementalAstCloner(this._oldNode, this._newNode, this._tokenMap);
2529
2530 @override
2531 AdjacentStrings visitAdjacentStrings(AdjacentStrings node) =>
2532 new AdjacentStrings(_cloneNodeList(node.strings));
2533
2534 @override
2535 Annotation visitAnnotation(Annotation node) {
2536 Annotation copy = new Annotation(
2537 _mapToken(node.atSign),
2538 _cloneNode(node.name),
2539 _mapToken(node.period),
2540 _cloneNode(node.constructorName),
2541 _cloneNode(node.arguments));
2542 copy.element = node.element;
2543 return copy;
2544 }
2545
2546 @override
2547 ArgumentList visitArgumentList(ArgumentList node) => new ArgumentList(
2548 _mapToken(node.leftParenthesis),
2549 _cloneNodeList(node.arguments),
2550 _mapToken(node.rightParenthesis));
2551
2552 @override
2553 AsExpression visitAsExpression(AsExpression node) {
2554 AsExpression copy = new AsExpression(_cloneNode(node.expression),
2555 _mapToken(node.asOperator), _cloneNode(node.type));
2556 copy.propagatedType = node.propagatedType;
2557 copy.staticType = node.staticType;
2558 return copy;
2559 }
2560
2561 @override
2562 AstNode visitAssertStatement(AssertStatement node) => new AssertStatement(
2563 _mapToken(node.assertKeyword),
2564 _mapToken(node.leftParenthesis),
2565 _cloneNode(node.condition),
2566 _mapToken(node.comma),
2567 _cloneNode(node.message),
2568 _mapToken(node.rightParenthesis),
2569 _mapToken(node.semicolon));
2570
2571 @override
2572 AssignmentExpression visitAssignmentExpression(AssignmentExpression node) {
2573 AssignmentExpression copy = new AssignmentExpression(
2574 _cloneNode(node.leftHandSide),
2575 _mapToken(node.operator),
2576 _cloneNode(node.rightHandSide));
2577 copy.propagatedElement = node.propagatedElement;
2578 copy.propagatedType = node.propagatedType;
2579 copy.staticElement = node.staticElement;
2580 copy.staticType = node.staticType;
2581 return copy;
2582 }
2583
2584 @override
2585 AwaitExpression visitAwaitExpression(AwaitExpression node) =>
2586 new AwaitExpression(
2587 _mapToken(node.awaitKeyword), _cloneNode(node.expression));
2588
2589 @override
2590 BinaryExpression visitBinaryExpression(BinaryExpression node) {
2591 BinaryExpression copy = new BinaryExpression(_cloneNode(node.leftOperand),
2592 _mapToken(node.operator), _cloneNode(node.rightOperand));
2593 copy.propagatedElement = node.propagatedElement;
2594 copy.propagatedType = node.propagatedType;
2595 copy.staticElement = node.staticElement;
2596 copy.staticType = node.staticType;
2597 return copy;
2598 }
2599
2600 @override
2601 Block visitBlock(Block node) => new Block(_mapToken(node.leftBracket),
2602 _cloneNodeList(node.statements), _mapToken(node.rightBracket));
2603
2604 @override
2605 BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) =>
2606 new BlockFunctionBody(_mapToken(node.keyword), _mapToken(node.star),
2607 _cloneNode(node.block));
2608
2609 @override
2610 BooleanLiteral visitBooleanLiteral(BooleanLiteral node) {
2611 BooleanLiteral copy =
2612 new BooleanLiteral(_mapToken(node.literal), node.value);
2613 copy.propagatedType = node.propagatedType;
2614 copy.staticType = node.staticType;
2615 return copy;
2616 }
2617
2618 @override
2619 BreakStatement visitBreakStatement(BreakStatement node) => new BreakStatement(
2620 _mapToken(node.breakKeyword),
2621 _cloneNode(node.label),
2622 _mapToken(node.semicolon));
2623
2624 @override
2625 CascadeExpression visitCascadeExpression(CascadeExpression node) {
2626 CascadeExpression copy = new CascadeExpression(
2627 _cloneNode(node.target), _cloneNodeList(node.cascadeSections));
2628 copy.propagatedType = node.propagatedType;
2629 copy.staticType = node.staticType;
2630 return copy;
2631 }
2632
2633 @override
2634 CatchClause visitCatchClause(CatchClause node) => new CatchClause(
2635 _mapToken(node.onKeyword),
2636 _cloneNode(node.exceptionType),
2637 _mapToken(node.catchKeyword),
2638 _mapToken(node.leftParenthesis),
2639 _cloneNode(node.exceptionParameter),
2640 _mapToken(node.comma),
2641 _cloneNode(node.stackTraceParameter),
2642 _mapToken(node.rightParenthesis),
2643 _cloneNode(node.body));
2644
2645 @override
2646 ClassDeclaration visitClassDeclaration(ClassDeclaration node) {
2647 ClassDeclaration copy = new ClassDeclaration(
2648 _cloneNode(node.documentationComment),
2649 _cloneNodeList(node.metadata),
2650 _mapToken(node.abstractKeyword),
2651 _mapToken(node.classKeyword),
2652 _cloneNode(node.name),
2653 _cloneNode(node.typeParameters),
2654 _cloneNode(node.extendsClause),
2655 _cloneNode(node.withClause),
2656 _cloneNode(node.implementsClause),
2657 _mapToken(node.leftBracket),
2658 _cloneNodeList(node.members),
2659 _mapToken(node.rightBracket));
2660 copy.nativeClause = _cloneNode(node.nativeClause);
2661 return copy;
2662 }
2663
2664 @override
2665 ClassTypeAlias visitClassTypeAlias(ClassTypeAlias node) => new ClassTypeAlias(
2666 _cloneNode(node.documentationComment),
2667 _cloneNodeList(node.metadata),
2668 _mapToken(node.typedefKeyword),
2669 _cloneNode(node.name),
2670 _cloneNode(node.typeParameters),
2671 _mapToken(node.equals),
2672 _mapToken(node.abstractKeyword),
2673 _cloneNode(node.superclass),
2674 _cloneNode(node.withClause),
2675 _cloneNode(node.implementsClause),
2676 _mapToken(node.semicolon));
2677
2678 @override
2679 Comment visitComment(Comment node) {
2680 if (node.isDocumentation) {
2681 return Comment.createDocumentationCommentWithReferences(
2682 _mapTokens(node.tokens), _cloneNodeList(node.references));
2683 } else if (node.isBlock) {
2684 return Comment.createBlockComment(_mapTokens(node.tokens));
2685 }
2686 return Comment.createEndOfLineComment(_mapTokens(node.tokens));
2687 }
2688
2689 @override
2690 CommentReference visitCommentReference(CommentReference node) =>
2691 new CommentReference(
2692 _mapToken(node.newKeyword), _cloneNode(node.identifier));
2693
2694 @override
2695 CompilationUnit visitCompilationUnit(CompilationUnit node) {
2696 CompilationUnit copy = new CompilationUnit(
2697 _mapToken(node.beginToken),
2698 _cloneNode(node.scriptTag),
2699 _cloneNodeList(node.directives),
2700 _cloneNodeList(node.declarations),
2701 _mapToken(node.endToken));
2702 copy.lineInfo = node.lineInfo;
2703 copy.element = node.element;
2704 return copy;
2705 }
2706
2707 @override
2708 ConditionalExpression visitConditionalExpression(ConditionalExpression node) {
2709 ConditionalExpression copy = new ConditionalExpression(
2710 _cloneNode(node.condition),
2711 _mapToken(node.question),
2712 _cloneNode(node.thenExpression),
2713 _mapToken(node.colon),
2714 _cloneNode(node.elseExpression));
2715 copy.propagatedType = node.propagatedType;
2716 copy.staticType = node.staticType;
2717 return copy;
2718 }
2719
2720 @override
2721 Configuration visitConfiguration(Configuration node) => new Configuration(
2722 _mapToken(node.ifKeyword),
2723 _mapToken(node.leftParenthesis),
2724 _cloneNode(node.name),
2725 _mapToken(node.equalToken),
2726 _cloneNode(node.value),
2727 _mapToken(node.rightParenthesis),
2728 _cloneNode(node.libraryUri));
2729
2730 @override
2731 ConstructorDeclaration visitConstructorDeclaration(
2732 ConstructorDeclaration node) {
2733 ConstructorDeclaration copy = new ConstructorDeclaration(
2734 _cloneNode(node.documentationComment),
2735 _cloneNodeList(node.metadata),
2736 _mapToken(node.externalKeyword),
2737 _mapToken(node.constKeyword),
2738 _mapToken(node.factoryKeyword),
2739 _cloneNode(node.returnType),
2740 _mapToken(node.period),
2741 _cloneNode(node.name),
2742 _cloneNode(node.parameters),
2743 _mapToken(node.separator),
2744 _cloneNodeList(node.initializers),
2745 _cloneNode(node.redirectedConstructor),
2746 _cloneNode(node.body));
2747 copy.element = node.element;
2748 return copy;
2749 }
2750
2751 @override
2752 ConstructorFieldInitializer visitConstructorFieldInitializer(
2753 ConstructorFieldInitializer node) =>
2754 new ConstructorFieldInitializer(
2755 _mapToken(node.thisKeyword),
2756 _mapToken(node.period),
2757 _cloneNode(node.fieldName),
2758 _mapToken(node.equals),
2759 _cloneNode(node.expression));
2760
2761 @override
2762 ConstructorName visitConstructorName(ConstructorName node) {
2763 ConstructorName copy = new ConstructorName(
2764 _cloneNode(node.type), _mapToken(node.period), _cloneNode(node.name));
2765 copy.staticElement = node.staticElement;
2766 return copy;
2767 }
2768
2769 @override
2770 ContinueStatement visitContinueStatement(ContinueStatement node) =>
2771 new ContinueStatement(_mapToken(node.continueKeyword),
2772 _cloneNode(node.label), _mapToken(node.semicolon));
2773
2774 @override
2775 DeclaredIdentifier visitDeclaredIdentifier(DeclaredIdentifier node) =>
2776 new DeclaredIdentifier(
2777 _cloneNode(node.documentationComment),
2778 _cloneNodeList(node.metadata),
2779 _mapToken(node.keyword),
2780 _cloneNode(node.type),
2781 _cloneNode(node.identifier));
2782
2783 @override
2784 DefaultFormalParameter visitDefaultFormalParameter(
2785 DefaultFormalParameter node) =>
2786 new DefaultFormalParameter(_cloneNode(node.parameter), node.kind,
2787 _mapToken(node.separator), _cloneNode(node.defaultValue));
2788
2789 @override
2790 DoStatement visitDoStatement(DoStatement node) => new DoStatement(
2791 _mapToken(node.doKeyword),
2792 _cloneNode(node.body),
2793 _mapToken(node.whileKeyword),
2794 _mapToken(node.leftParenthesis),
2795 _cloneNode(node.condition),
2796 _mapToken(node.rightParenthesis),
2797 _mapToken(node.semicolon));
2798
2799 @override
2800 DottedName visitDottedName(DottedName node) =>
2801 new DottedName(_cloneNodeList(node.components));
2802
2803 @override
2804 DoubleLiteral visitDoubleLiteral(DoubleLiteral node) {
2805 DoubleLiteral copy = new DoubleLiteral(_mapToken(node.literal), node.value);
2806 copy.propagatedType = node.propagatedType;
2807 copy.staticType = node.staticType;
2808 return copy;
2809 }
2810
2811 @override
2812 EmptyFunctionBody visitEmptyFunctionBody(EmptyFunctionBody node) =>
2813 new EmptyFunctionBody(_mapToken(node.semicolon));
2814
2815 @override
2816 EmptyStatement visitEmptyStatement(EmptyStatement node) =>
2817 new EmptyStatement(_mapToken(node.semicolon));
2818
2819 @override
2820 AstNode visitEnumConstantDeclaration(EnumConstantDeclaration node) =>
2821 new EnumConstantDeclaration(_cloneNode(node.documentationComment),
2822 _cloneNodeList(node.metadata), _cloneNode(node.name));
2823
2824 @override
2825 AstNode visitEnumDeclaration(EnumDeclaration node) => new EnumDeclaration(
2826 _cloneNode(node.documentationComment),
2827 _cloneNodeList(node.metadata),
2828 _mapToken(node.enumKeyword),
2829 _cloneNode(node.name),
2830 _mapToken(node.leftBracket),
2831 _cloneNodeList(node.constants),
2832 _mapToken(node.rightBracket));
2833
2834 @override
2835 ExportDirective visitExportDirective(ExportDirective node) {
2836 ExportDirective copy = new ExportDirective(
2837 _cloneNode(node.documentationComment),
2838 _cloneNodeList(node.metadata),
2839 _mapToken(node.keyword),
2840 _cloneNode(node.uri),
2841 _cloneNodeList(node.configurations),
2842 _cloneNodeList(node.combinators),
2843 _mapToken(node.semicolon));
2844 copy.element = node.element;
2845 return copy;
2846 }
2847
2848 @override
2849 ExpressionFunctionBody visitExpressionFunctionBody(
2850 ExpressionFunctionBody node) =>
2851 new ExpressionFunctionBody(
2852 _mapToken(node.keyword),
2853 _mapToken(node.functionDefinition),
2854 _cloneNode(node.expression),
2855 _mapToken(node.semicolon));
2856
2857 @override
2858 ExpressionStatement visitExpressionStatement(ExpressionStatement node) =>
2859 new ExpressionStatement(
2860 _cloneNode(node.expression), _mapToken(node.semicolon));
2861
2862 @override
2863 ExtendsClause visitExtendsClause(ExtendsClause node) => new ExtendsClause(
2864 _mapToken(node.extendsKeyword), _cloneNode(node.superclass));
2865
2866 @override
2867 FieldDeclaration visitFieldDeclaration(FieldDeclaration node) =>
2868 new FieldDeclaration(
2869 _cloneNode(node.documentationComment),
2870 _cloneNodeList(node.metadata),
2871 _mapToken(node.staticKeyword),
2872 _cloneNode(node.fields),
2873 _mapToken(node.semicolon));
2874
2875 @override
2876 FieldFormalParameter visitFieldFormalParameter(FieldFormalParameter node) =>
2877 new FieldFormalParameter(
2878 _cloneNode(node.documentationComment),
2879 _cloneNodeList(node.metadata),
2880 _mapToken(node.keyword),
2881 _cloneNode(node.type),
2882 _mapToken(node.thisKeyword),
2883 _mapToken(node.period),
2884 _cloneNode(node.identifier),
2885 _cloneNode(node.typeParameters),
2886 _cloneNode(node.parameters));
2887
2888 @override
2889 ForEachStatement visitForEachStatement(ForEachStatement node) {
2890 DeclaredIdentifier loopVariable = node.loopVariable;
2891 if (loopVariable == null) {
2892 return new ForEachStatement.withReference(
2893 _mapToken(node.awaitKeyword),
2894 _mapToken(node.forKeyword),
2895 _mapToken(node.leftParenthesis),
2896 _cloneNode(node.identifier),
2897 _mapToken(node.inKeyword),
2898 _cloneNode(node.iterable),
2899 _mapToken(node.rightParenthesis),
2900 _cloneNode(node.body));
2901 }
2902 return new ForEachStatement.withDeclaration(
2903 _mapToken(node.awaitKeyword),
2904 _mapToken(node.forKeyword),
2905 _mapToken(node.leftParenthesis),
2906 _cloneNode(loopVariable),
2907 _mapToken(node.inKeyword),
2908 _cloneNode(node.iterable),
2909 _mapToken(node.rightParenthesis),
2910 _cloneNode(node.body));
2911 }
2912
2913 @override
2914 FormalParameterList visitFormalParameterList(FormalParameterList node) =>
2915 new FormalParameterList(
2916 _mapToken(node.leftParenthesis),
2917 _cloneNodeList(node.parameters),
2918 _mapToken(node.leftDelimiter),
2919 _mapToken(node.rightDelimiter),
2920 _mapToken(node.rightParenthesis));
2921
2922 @override
2923 ForStatement visitForStatement(ForStatement node) => new ForStatement(
2924 _mapToken(node.forKeyword),
2925 _mapToken(node.leftParenthesis),
2926 _cloneNode(node.variables),
2927 _cloneNode(node.initialization),
2928 _mapToken(node.leftSeparator),
2929 _cloneNode(node.condition),
2930 _mapToken(node.rightSeparator),
2931 _cloneNodeList(node.updaters),
2932 _mapToken(node.rightParenthesis),
2933 _cloneNode(node.body));
2934
2935 @override
2936 FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) =>
2937 new FunctionDeclaration(
2938 _cloneNode(node.documentationComment),
2939 _cloneNodeList(node.metadata),
2940 _mapToken(node.externalKeyword),
2941 _cloneNode(node.returnType),
2942 _mapToken(node.propertyKeyword),
2943 _cloneNode(node.name),
2944 _cloneNode(node.functionExpression));
2945
2946 @override
2947 FunctionDeclarationStatement visitFunctionDeclarationStatement(
2948 FunctionDeclarationStatement node) =>
2949 new FunctionDeclarationStatement(_cloneNode(node.functionDeclaration));
2950
2951 @override
2952 FunctionExpression visitFunctionExpression(FunctionExpression node) {
2953 FunctionExpression copy = new FunctionExpression(
2954 _cloneNode(node.typeParameters),
2955 _cloneNode(node.parameters),
2956 _cloneNode(node.body));
2957 copy.element = node.element;
2958 copy.propagatedType = node.propagatedType;
2959 copy.staticType = node.staticType;
2960 return copy;
2961 }
2962
2963 @override
2964 FunctionExpressionInvocation visitFunctionExpressionInvocation(
2965 FunctionExpressionInvocation node) {
2966 FunctionExpressionInvocation copy = new FunctionExpressionInvocation(
2967 _cloneNode(node.function),
2968 _cloneNode(node.typeArguments),
2969 _cloneNode(node.argumentList));
2970 copy.propagatedElement = node.propagatedElement;
2971 copy.propagatedType = node.propagatedType;
2972 copy.staticElement = node.staticElement;
2973 copy.staticType = node.staticType;
2974 return copy;
2975 }
2976
2977 @override
2978 FunctionTypeAlias visitFunctionTypeAlias(FunctionTypeAlias node) =>
2979 new FunctionTypeAlias(
2980 _cloneNode(node.documentationComment),
2981 _cloneNodeList(node.metadata),
2982 _mapToken(node.typedefKeyword),
2983 _cloneNode(node.returnType),
2984 _cloneNode(node.name),
2985 _cloneNode(node.typeParameters),
2986 _cloneNode(node.parameters),
2987 _mapToken(node.semicolon));
2988
2989 @override
2990 FunctionTypedFormalParameter visitFunctionTypedFormalParameter(
2991 FunctionTypedFormalParameter node) =>
2992 new FunctionTypedFormalParameter(
2993 _cloneNode(node.documentationComment),
2994 _cloneNodeList(node.metadata),
2995 _cloneNode(node.returnType),
2996 _cloneNode(node.identifier),
2997 _cloneNode(node.typeParameters),
2998 _cloneNode(node.parameters));
2999
3000 @override
3001 HideCombinator visitHideCombinator(HideCombinator node) => new HideCombinator(
3002 _mapToken(node.keyword), _cloneNodeList(node.hiddenNames));
3003
3004 @override
3005 IfStatement visitIfStatement(IfStatement node) => new IfStatement(
3006 _mapToken(node.ifKeyword),
3007 _mapToken(node.leftParenthesis),
3008 _cloneNode(node.condition),
3009 _mapToken(node.rightParenthesis),
3010 _cloneNode(node.thenStatement),
3011 _mapToken(node.elseKeyword),
3012 _cloneNode(node.elseStatement));
3013
3014 @override
3015 ImplementsClause visitImplementsClause(ImplementsClause node) =>
3016 new ImplementsClause(
3017 _mapToken(node.implementsKeyword), _cloneNodeList(node.interfaces));
3018
3019 @override
3020 ImportDirective visitImportDirective(ImportDirective node) =>
3021 new ImportDirective(
3022 _cloneNode(node.documentationComment),
3023 _cloneNodeList(node.metadata),
3024 _mapToken(node.keyword),
3025 _cloneNode(node.uri),
3026 _cloneNodeList(node.configurations),
3027 _mapToken(node.deferredKeyword),
3028 _mapToken(node.asKeyword),
3029 _cloneNode(node.prefix),
3030 _cloneNodeList(node.combinators),
3031 _mapToken(node.semicolon));
3032
3033 @override
3034 IndexExpression visitIndexExpression(IndexExpression node) {
3035 Token period = _mapToken(node.period);
3036 IndexExpression copy;
3037 if (period == null) {
3038 copy = new IndexExpression.forTarget(
3039 _cloneNode(node.target),
3040 _mapToken(node.leftBracket),
3041 _cloneNode(node.index),
3042 _mapToken(node.rightBracket));
3043 } else {
3044 copy = new IndexExpression.forCascade(period, _mapToken(node.leftBracket),
3045 _cloneNode(node.index), _mapToken(node.rightBracket));
3046 }
3047 copy.auxiliaryElements = node.auxiliaryElements;
3048 copy.propagatedElement = node.propagatedElement;
3049 copy.propagatedType = node.propagatedType;
3050 copy.staticElement = node.staticElement;
3051 copy.staticType = node.staticType;
3052 return copy;
3053 }
3054
3055 @override
3056 InstanceCreationExpression visitInstanceCreationExpression(
3057 InstanceCreationExpression node) {
3058 InstanceCreationExpression copy = new InstanceCreationExpression(
3059 _mapToken(node.keyword),
3060 _cloneNode(node.constructorName),
3061 _cloneNode(node.argumentList));
3062 copy.propagatedType = node.propagatedType;
3063 copy.staticElement = node.staticElement;
3064 copy.staticType = node.staticType;
3065 return copy;
3066 }
3067
3068 @override
3069 IntegerLiteral visitIntegerLiteral(IntegerLiteral node) {
3070 IntegerLiteral copy =
3071 new IntegerLiteral(_mapToken(node.literal), node.value);
3072 copy.propagatedType = node.propagatedType;
3073 copy.staticType = node.staticType;
3074 return copy;
3075 }
3076
3077 @override
3078 InterpolationExpression visitInterpolationExpression(
3079 InterpolationExpression node) =>
3080 new InterpolationExpression(_mapToken(node.leftBracket),
3081 _cloneNode(node.expression), _mapToken(node.rightBracket));
3082
3083 @override
3084 InterpolationString visitInterpolationString(InterpolationString node) =>
3085 new InterpolationString(_mapToken(node.contents), node.value);
3086
3087 @override
3088 IsExpression visitIsExpression(IsExpression node) {
3089 IsExpression copy = new IsExpression(
3090 _cloneNode(node.expression),
3091 _mapToken(node.isOperator),
3092 _mapToken(node.notOperator),
3093 _cloneNode(node.type));
3094 copy.propagatedType = node.propagatedType;
3095 copy.staticType = node.staticType;
3096 return copy;
3097 }
3098
3099 @override
3100 Label visitLabel(Label node) =>
3101 new Label(_cloneNode(node.label), _mapToken(node.colon));
3102
3103 @override
3104 LabeledStatement visitLabeledStatement(LabeledStatement node) =>
3105 new LabeledStatement(
3106 _cloneNodeList(node.labels), _cloneNode(node.statement));
3107
3108 @override
3109 LibraryDirective visitLibraryDirective(LibraryDirective node) =>
3110 new LibraryDirective(
3111 _cloneNode(node.documentationComment),
3112 _cloneNodeList(node.metadata),
3113 _mapToken(node.libraryKeyword),
3114 _cloneNode(node.name),
3115 _mapToken(node.semicolon));
3116
3117 @override
3118 LibraryIdentifier visitLibraryIdentifier(LibraryIdentifier node) {
3119 LibraryIdentifier copy =
3120 new LibraryIdentifier(_cloneNodeList(node.components));
3121 copy.propagatedType = node.propagatedType;
3122 copy.staticType = node.staticType;
3123 return copy;
3124 }
3125
3126 @override
3127 ListLiteral visitListLiteral(ListLiteral node) {
3128 ListLiteral copy = new ListLiteral(
3129 _mapToken(node.constKeyword),
3130 _cloneNode(node.typeArguments),
3131 _mapToken(node.leftBracket),
3132 _cloneNodeList(node.elements),
3133 _mapToken(node.rightBracket));
3134 copy.propagatedType = node.propagatedType;
3135 copy.staticType = node.staticType;
3136 return copy;
3137 }
3138
3139 @override
3140 MapLiteral visitMapLiteral(MapLiteral node) {
3141 MapLiteral copy = new MapLiteral(
3142 _mapToken(node.constKeyword),
3143 _cloneNode(node.typeArguments),
3144 _mapToken(node.leftBracket),
3145 _cloneNodeList(node.entries),
3146 _mapToken(node.rightBracket));
3147 copy.propagatedType = node.propagatedType;
3148 copy.staticType = node.staticType;
3149 return copy;
3150 }
3151
3152 @override
3153 MapLiteralEntry visitMapLiteralEntry(MapLiteralEntry node) =>
3154 new MapLiteralEntry(_cloneNode(node.key), _mapToken(node.separator),
3155 _cloneNode(node.value));
3156
3157 @override
3158 MethodDeclaration visitMethodDeclaration(MethodDeclaration node) =>
3159 new MethodDeclaration(
3160 _cloneNode(node.documentationComment),
3161 _cloneNodeList(node.metadata),
3162 _mapToken(node.externalKeyword),
3163 _mapToken(node.modifierKeyword),
3164 _cloneNode(node.returnType),
3165 _mapToken(node.propertyKeyword),
3166 _mapToken(node.operatorKeyword),
3167 _cloneNode(node.name),
3168 _cloneNode(node.typeParameters),
3169 _cloneNode(node.parameters),
3170 _cloneNode(node.body));
3171
3172 @override
3173 MethodInvocation visitMethodInvocation(MethodInvocation node) {
3174 MethodInvocation copy = new MethodInvocation(
3175 _cloneNode(node.target),
3176 _mapToken(node.operator),
3177 _cloneNode(node.methodName),
3178 _cloneNode(node.typeArguments),
3179 _cloneNode(node.argumentList));
3180 copy.propagatedType = node.propagatedType;
3181 copy.staticType = node.staticType;
3182 return copy;
3183 }
3184
3185 @override
3186 NamedExpression visitNamedExpression(NamedExpression node) {
3187 NamedExpression copy =
3188 new NamedExpression(_cloneNode(node.name), _cloneNode(node.expression));
3189 copy.propagatedType = node.propagatedType;
3190 copy.staticType = node.staticType;
3191 return copy;
3192 }
3193
3194 @override
3195 AstNode visitNativeClause(NativeClause node) =>
3196 new NativeClause(_mapToken(node.nativeKeyword), _cloneNode(node.name));
3197
3198 @override
3199 NativeFunctionBody visitNativeFunctionBody(NativeFunctionBody node) =>
3200 new NativeFunctionBody(_mapToken(node.nativeKeyword),
3201 _cloneNode(node.stringLiteral), _mapToken(node.semicolon));
3202
3203 @override
3204 NullLiteral visitNullLiteral(NullLiteral node) {
3205 NullLiteral copy = new NullLiteral(_mapToken(node.literal));
3206 copy.propagatedType = node.propagatedType;
3207 copy.staticType = node.staticType;
3208 return copy;
3209 }
3210
3211 @override
3212 ParenthesizedExpression visitParenthesizedExpression(
3213 ParenthesizedExpression node) {
3214 ParenthesizedExpression copy = new ParenthesizedExpression(
3215 _mapToken(node.leftParenthesis),
3216 _cloneNode(node.expression),
3217 _mapToken(node.rightParenthesis));
3218 copy.propagatedType = node.propagatedType;
3219 copy.staticType = node.staticType;
3220 return copy;
3221 }
3222
3223 @override
3224 PartDirective visitPartDirective(PartDirective node) {
3225 PartDirective copy = new PartDirective(
3226 _cloneNode(node.documentationComment),
3227 _cloneNodeList(node.metadata),
3228 _mapToken(node.partKeyword),
3229 _cloneNode(node.uri),
3230 _mapToken(node.semicolon));
3231 copy.element = node.element;
3232 return copy;
3233 }
3234
3235 @override
3236 PartOfDirective visitPartOfDirective(PartOfDirective node) {
3237 PartOfDirective copy = new PartOfDirective(
3238 _cloneNode(node.documentationComment),
3239 _cloneNodeList(node.metadata),
3240 _mapToken(node.partKeyword),
3241 _mapToken(node.ofKeyword),
3242 _cloneNode(node.libraryName),
3243 _mapToken(node.semicolon));
3244 copy.element = node.element;
3245 return copy;
3246 }
3247
3248 @override
3249 PostfixExpression visitPostfixExpression(PostfixExpression node) {
3250 PostfixExpression copy = new PostfixExpression(
3251 _cloneNode(node.operand), _mapToken(node.operator));
3252 copy.propagatedElement = node.propagatedElement;
3253 copy.propagatedType = node.propagatedType;
3254 copy.staticElement = node.staticElement;
3255 copy.staticType = node.staticType;
3256 return copy;
3257 }
3258
3259 @override
3260 PrefixedIdentifier visitPrefixedIdentifier(PrefixedIdentifier node) {
3261 PrefixedIdentifier copy = new PrefixedIdentifier(_cloneNode(node.prefix),
3262 _mapToken(node.period), _cloneNode(node.identifier));
3263 copy.propagatedType = node.propagatedType;
3264 copy.staticType = node.staticType;
3265 return copy;
3266 }
3267
3268 @override
3269 PrefixExpression visitPrefixExpression(PrefixExpression node) {
3270 PrefixExpression copy = new PrefixExpression(
3271 _mapToken(node.operator), _cloneNode(node.operand));
3272 copy.propagatedElement = node.propagatedElement;
3273 copy.propagatedType = node.propagatedType;
3274 copy.staticElement = node.staticElement;
3275 copy.staticType = node.staticType;
3276 return copy;
3277 }
3278
3279 @override
3280 PropertyAccess visitPropertyAccess(PropertyAccess node) {
3281 PropertyAccess copy = new PropertyAccess(_cloneNode(node.target),
3282 _mapToken(node.operator), _cloneNode(node.propertyName));
3283 copy.propagatedType = node.propagatedType;
3284 copy.staticType = node.staticType;
3285 return copy;
3286 }
3287
3288 @override
3289 RedirectingConstructorInvocation visitRedirectingConstructorInvocation(
3290 RedirectingConstructorInvocation node) {
3291 RedirectingConstructorInvocation copy =
3292 new RedirectingConstructorInvocation(
3293 _mapToken(node.thisKeyword),
3294 _mapToken(node.period),
3295 _cloneNode(node.constructorName),
3296 _cloneNode(node.argumentList));
3297 copy.staticElement = node.staticElement;
3298 return copy;
3299 }
3300
3301 @override
3302 RethrowExpression visitRethrowExpression(RethrowExpression node) {
3303 RethrowExpression copy =
3304 new RethrowExpression(_mapToken(node.rethrowKeyword));
3305 copy.propagatedType = node.propagatedType;
3306 copy.staticType = node.staticType;
3307 return copy;
3308 }
3309
3310 @override
3311 ReturnStatement visitReturnStatement(ReturnStatement node) =>
3312 new ReturnStatement(_mapToken(node.returnKeyword),
3313 _cloneNode(node.expression), _mapToken(node.semicolon));
3314
3315 @override
3316 ScriptTag visitScriptTag(ScriptTag node) =>
3317 new ScriptTag(_mapToken(node.scriptTag));
3318
3319 @override
3320 ShowCombinator visitShowCombinator(ShowCombinator node) => new ShowCombinator(
3321 _mapToken(node.keyword), _cloneNodeList(node.shownNames));
3322
3323 @override
3324 SimpleFormalParameter visitSimpleFormalParameter(
3325 SimpleFormalParameter node) =>
3326 new SimpleFormalParameter(
3327 _cloneNode(node.documentationComment),
3328 _cloneNodeList(node.metadata),
3329 _mapToken(node.keyword),
3330 _cloneNode(node.type),
3331 _cloneNode(node.identifier));
3332
3333 @override
3334 SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) {
3335 Token mappedToken = _mapToken(node.token);
3336 if (mappedToken == null) {
3337 // This only happens for SimpleIdentifiers created by the parser as part
3338 // of scanning documentation comments (the tokens for those identifiers
3339 // are not in the original token stream and hence do not get copied).
3340 // This extra check can be removed if the scanner is changed to scan
3341 // documentation comments for the parser.
3342 mappedToken = node.token;
3343 }
3344 SimpleIdentifier copy = new SimpleIdentifier(mappedToken);
3345 copy.auxiliaryElements = node.auxiliaryElements;
3346 copy.propagatedElement = node.propagatedElement;
3347 copy.propagatedType = node.propagatedType;
3348 copy.staticElement = node.staticElement;
3349 copy.staticType = node.staticType;
3350 return copy;
3351 }
3352
3353 @override
3354 SimpleStringLiteral visitSimpleStringLiteral(SimpleStringLiteral node) {
3355 SimpleStringLiteral copy =
3356 new SimpleStringLiteral(_mapToken(node.literal), node.value);
3357 copy.propagatedType = node.propagatedType;
3358 copy.staticType = node.staticType;
3359 return copy;
3360 }
3361
3362 @override
3363 StringInterpolation visitStringInterpolation(StringInterpolation node) {
3364 StringInterpolation copy =
3365 new StringInterpolation(_cloneNodeList(node.elements));
3366 copy.propagatedType = node.propagatedType;
3367 copy.staticType = node.staticType;
3368 return copy;
3369 }
3370
3371 @override
3372 SuperConstructorInvocation visitSuperConstructorInvocation(
3373 SuperConstructorInvocation node) {
3374 SuperConstructorInvocation copy = new SuperConstructorInvocation(
3375 _mapToken(node.superKeyword),
3376 _mapToken(node.period),
3377 _cloneNode(node.constructorName),
3378 _cloneNode(node.argumentList));
3379 copy.staticElement = node.staticElement;
3380 return copy;
3381 }
3382
3383 @override
3384 SuperExpression visitSuperExpression(SuperExpression node) {
3385 SuperExpression copy = new SuperExpression(_mapToken(node.superKeyword));
3386 copy.propagatedType = node.propagatedType;
3387 copy.staticType = node.staticType;
3388 return copy;
3389 }
3390
3391 @override
3392 SwitchCase visitSwitchCase(SwitchCase node) => new SwitchCase(
3393 _cloneNodeList(node.labels),
3394 _mapToken(node.keyword),
3395 _cloneNode(node.expression),
3396 _mapToken(node.colon),
3397 _cloneNodeList(node.statements));
3398
3399 @override
3400 SwitchDefault visitSwitchDefault(SwitchDefault node) => new SwitchDefault(
3401 _cloneNodeList(node.labels),
3402 _mapToken(node.keyword),
3403 _mapToken(node.colon),
3404 _cloneNodeList(node.statements));
3405
3406 @override
3407 SwitchStatement visitSwitchStatement(SwitchStatement node) =>
3408 new SwitchStatement(
3409 _mapToken(node.switchKeyword),
3410 _mapToken(node.leftParenthesis),
3411 _cloneNode(node.expression),
3412 _mapToken(node.rightParenthesis),
3413 _mapToken(node.leftBracket),
3414 _cloneNodeList(node.members),
3415 _mapToken(node.rightBracket));
3416
3417 @override
3418 AstNode visitSymbolLiteral(SymbolLiteral node) {
3419 SymbolLiteral copy = new SymbolLiteral(
3420 _mapToken(node.poundSign), _mapTokens(node.components));
3421 copy.propagatedType = node.propagatedType;
3422 copy.staticType = node.staticType;
3423 return copy;
3424 }
3425
3426 @override
3427 ThisExpression visitThisExpression(ThisExpression node) {
3428 ThisExpression copy = new ThisExpression(_mapToken(node.thisKeyword));
3429 copy.propagatedType = node.propagatedType;
3430 copy.staticType = node.staticType;
3431 return copy;
3432 }
3433
3434 @override
3435 ThrowExpression visitThrowExpression(ThrowExpression node) {
3436 ThrowExpression copy = new ThrowExpression(
3437 _mapToken(node.throwKeyword), _cloneNode(node.expression));
3438 copy.propagatedType = node.propagatedType;
3439 copy.staticType = node.staticType;
3440 return copy;
3441 }
3442
3443 @override
3444 TopLevelVariableDeclaration visitTopLevelVariableDeclaration(
3445 TopLevelVariableDeclaration node) =>
3446 new TopLevelVariableDeclaration(
3447 _cloneNode(node.documentationComment),
3448 _cloneNodeList(node.metadata),
3449 _cloneNode(node.variables),
3450 _mapToken(node.semicolon));
3451
3452 @override
3453 TryStatement visitTryStatement(TryStatement node) => new TryStatement(
3454 _mapToken(node.tryKeyword),
3455 _cloneNode(node.body),
3456 _cloneNodeList(node.catchClauses),
3457 _mapToken(node.finallyKeyword),
3458 _cloneNode(node.finallyBlock));
3459
3460 @override
3461 TypeArgumentList visitTypeArgumentList(TypeArgumentList node) =>
3462 new TypeArgumentList(_mapToken(node.leftBracket),
3463 _cloneNodeList(node.arguments), _mapToken(node.rightBracket));
3464
3465 @override
3466 TypeName visitTypeName(TypeName node) {
3467 TypeName copy =
3468 new TypeName(_cloneNode(node.name), _cloneNode(node.typeArguments));
3469 copy.type = node.type;
3470 return copy;
3471 }
3472
3473 @override
3474 TypeParameter visitTypeParameter(TypeParameter node) => new TypeParameter(
3475 _cloneNode(node.documentationComment),
3476 _cloneNodeList(node.metadata),
3477 _cloneNode(node.name),
3478 _mapToken(node.extendsKeyword),
3479 _cloneNode(node.bound));
3480
3481 @override
3482 TypeParameterList visitTypeParameterList(TypeParameterList node) =>
3483 new TypeParameterList(_mapToken(node.leftBracket),
3484 _cloneNodeList(node.typeParameters), _mapToken(node.rightBracket));
3485
3486 @override
3487 VariableDeclaration visitVariableDeclaration(VariableDeclaration node) =>
3488 new VariableDeclaration(_cloneNode(node.name), _mapToken(node.equals),
3489 _cloneNode(node.initializer));
3490
3491 @override
3492 VariableDeclarationList visitVariableDeclarationList(
3493 VariableDeclarationList node) =>
3494 new VariableDeclarationList(
3495 null,
3496 _cloneNodeList(node.metadata),
3497 _mapToken(node.keyword),
3498 _cloneNode(node.type),
3499 _cloneNodeList(node.variables));
3500
3501 @override
3502 VariableDeclarationStatement visitVariableDeclarationStatement(
3503 VariableDeclarationStatement node) =>
3504 new VariableDeclarationStatement(
3505 _cloneNode(node.variables), _mapToken(node.semicolon));
3506
3507 @override
3508 WhileStatement visitWhileStatement(WhileStatement node) => new WhileStatement(
3509 _mapToken(node.whileKeyword),
3510 _mapToken(node.leftParenthesis),
3511 _cloneNode(node.condition),
3512 _mapToken(node.rightParenthesis),
3513 _cloneNode(node.body));
3514
3515 @override
3516 WithClause visitWithClause(WithClause node) => new WithClause(
3517 _mapToken(node.withKeyword), _cloneNodeList(node.mixinTypes));
3518
3519 @override
3520 YieldStatement visitYieldStatement(YieldStatement node) => new YieldStatement(
3521 _mapToken(node.yieldKeyword),
3522 _mapToken(node.star),
3523 _cloneNode(node.expression),
3524 _mapToken(node.semicolon));
3525
3526 AstNode _cloneNode(AstNode node) {
3527 if (node == null) {
3528 return null;
3529 }
3530 if (identical(node, _oldNode)) {
3531 return _newNode;
3532 }
3533 return node.accept(this) as AstNode;
3534 }
3535
3536 List _cloneNodeList(NodeList nodes) {
3537 List clonedNodes = new List();
3538 for (AstNode node in nodes) {
3539 clonedNodes.add(_cloneNode(node));
3540 }
3541 return clonedNodes;
3542 }
3543
3544 Token _mapToken(Token oldToken) {
3545 if (oldToken == null) {
3546 return null;
3547 }
3548 return _tokenMap.get(oldToken);
3549 }
3550
3551 List<Token> _mapTokens(List<Token> oldTokens) {
3552 List<Token> newTokens = new List<Token>(oldTokens.length);
3553 for (int index = 0; index < newTokens.length; index++) {
3554 newTokens[index] = _mapToken(oldTokens[index]);
3555 }
3556 return newTokens;
3557 }
3558 }
3559
3560 /**
3561 * An object used to locate the [AstNode] associated with a source range, given
3562 * the AST structure built from the source. More specifically, they will return
3563 * the [AstNode] with the shortest length whose source range completely
3564 * encompasses the specified range.
3565 */
3566 class NodeLocator extends UnifyingAstVisitor<Object> {
3567 /**
3568 * The start offset of the range used to identify the node.
3569 */
3570 int _startOffset = 0;
3571
3572 /**
3573 * The end offset of the range used to identify the node.
3574 */
3575 int _endOffset = 0;
3576
3577 /**
3578 * The element that was found that corresponds to the given source range, or
3579 * `null` if there is no such element.
3580 */
3581 AstNode _foundNode;
3582
3583 /**
3584 * Initialize a newly created locator to locate an [AstNode] by locating the
3585 * node within an AST structure that corresponds to the given range of
3586 * characters (between the [startOffset] and [endOffset] in the source.
3587 */
3588 NodeLocator(int startOffset, [int endOffset])
3589 : this._startOffset = startOffset,
3590 this._endOffset = endOffset == null ? startOffset : endOffset;
3591
3592 /**
3593 * Return the node that was found that corresponds to the given source range
3594 * or `null` if there is no such node.
3595 */
3596 AstNode get foundNode => _foundNode;
3597
3598 /**
3599 * Search within the given AST [node] for an identifier representing an
3600 * element in the specified source range. Return the element that was found,
3601 * or `null` if no element was found.
3602 */
3603 AstNode searchWithin(AstNode node) {
3604 if (node == null) {
3605 return null;
3606 }
3607 try {
3608 node.accept(this);
3609 } on NodeLocator_NodeFoundException {
3610 // A node with the right source position was found.
3611 } catch (exception, stackTrace) {
3612 AnalysisEngine.instance.logger.logInformation(
3613 "Unable to locate element at offset ($_startOffset - $_endOffset)",
3614 new CaughtException(exception, stackTrace));
3615 return null;
3616 }
3617 return _foundNode;
3618 }
3619
3620 @override
3621 Object visitNode(AstNode node) {
3622 Token beginToken = node.beginToken;
3623 Token endToken = node.endToken;
3624 // Don't include synthetic tokens.
3625 while (endToken != beginToken) {
3626 if (endToken.type == TokenType.EOF || !endToken.isSynthetic) {
3627 break;
3628 }
3629 endToken = endToken.previous;
3630 }
3631 int end = endToken.end;
3632 int start = node.offset;
3633 if (end < _startOffset) {
3634 return null;
3635 }
3636 if (start > _endOffset) {
3637 return null;
3638 }
3639 try {
3640 node.visitChildren(this);
3641 } on NodeLocator_NodeFoundException {
3642 rethrow;
3643 } catch (exception, stackTrace) {
3644 // Ignore the exception and proceed in order to visit the rest of the
3645 // structure.
3646 AnalysisEngine.instance.logger.logInformation(
3647 "Exception caught while traversing an AST structure.",
3648 new CaughtException(exception, stackTrace));
3649 }
3650 if (start <= _startOffset && _endOffset <= end) {
3651 _foundNode = node;
3652 throw new NodeLocator_NodeFoundException();
3653 }
3654 return null;
3655 }
3656 }
3657
3658 /**
3659 * An object used to locate the [AstNode] associated with a source range.
3660 * More specifically, they will return the deepest [AstNode] which completely
3661 * encompasses the specified range.
3662 */
3663 class NodeLocator2 extends UnifyingAstVisitor<Object> {
3664 /**
3665 * The inclusive start offset of the range used to identify the node.
3666 */
3667 int _startOffset = 0;
3668
3669 /**
3670 * The inclusive end offset of the range used to identify the node.
3671 */
3672 int _endOffset = 0;
3673
3674 /**
3675 * The found node or `null` if there is no such node.
3676 */
3677 AstNode _foundNode;
3678
3679 /**
3680 * Initialize a newly created locator to locate the deepest [AstNode] for
3681 * which `node.offset <= [startOffset]` and `[endOffset] < node.end`.
3682 *
3683 * If [endOffset] is not provided, then it is considered the same as the
3684 * given [startOffset].
3685 */
3686 NodeLocator2(int startOffset, [int endOffset])
3687 : this._startOffset = startOffset,
3688 this._endOffset = endOffset == null ? startOffset : endOffset;
3689
3690 /**
3691 * Search within the given AST [node] and return the node that was found,
3692 * or `null` if no node was found.
3693 */
3694 AstNode searchWithin(AstNode node) {
3695 if (node == null) {
3696 return null;
3697 }
3698 try {
3699 node.accept(this);
3700 } on NodeLocator_NodeFoundException {} catch (exception, stackTrace) {
3701 AnalysisEngine.instance.logger.logInformation(
3702 "Unable to locate element at offset ($_startOffset - $_endOffset)",
3703 new CaughtException(exception, stackTrace));
3704 return null;
3705 }
3706 return _foundNode;
3707 }
3708
3709 @override
3710 Object visitNode(AstNode node) {
3711 Token beginToken = node.beginToken;
3712 Token endToken = node.endToken;
3713 // Don't include synthetic tokens.
3714 while (endToken != beginToken) {
3715 if (endToken.type == TokenType.EOF || !endToken.isSynthetic) {
3716 break;
3717 }
3718 endToken = endToken.previous;
3719 }
3720 int end = endToken.end;
3721 int start = node.offset;
3722 if (end <= _startOffset) {
3723 return null;
3724 }
3725 if (start > _endOffset) {
3726 return null;
3727 }
3728 try {
3729 node.visitChildren(this);
3730 } on NodeLocator_NodeFoundException {
3731 rethrow;
3732 } catch (exception, stackTrace) {
3733 // Ignore the exception and proceed in order to visit the rest of the
3734 // structure.
3735 AnalysisEngine.instance.logger.logInformation(
3736 "Exception caught while traversing an AST structure.",
3737 new CaughtException(exception, stackTrace));
3738 }
3739 if (start <= _startOffset && _endOffset < end) {
3740 _foundNode = node;
3741 throw new NodeLocator_NodeFoundException();
3742 }
3743 return null;
3744 }
3745 }
3746
3747 /**
3748 * An exception used by [NodeLocator] to cancel visiting after a node has been
3749 * found.
3750 */
3751 class NodeLocator_NodeFoundException extends RuntimeException {}
3752
3753 /**
3754 * An object that will replace one child node in an AST node with another node.
3755 */
3756 class NodeReplacer implements AstVisitor<bool> {
3757 /**
3758 * The node being replaced.
3759 */
3760 final AstNode _oldNode;
3761
3762 /**
3763 * The node that is replacing the old node.
3764 */
3765 final AstNode _newNode;
3766
3767 /**
3768 * Initialize a newly created node locator to replace the [_oldNode] with the
3769 * [_newNode].
3770 */
3771 NodeReplacer(this._oldNode, this._newNode);
3772
3773 @override
3774 bool visitAdjacentStrings(AdjacentStrings node) {
3775 if (_replaceInList(node.strings)) {
3776 return true;
3777 }
3778 return visitNode(node);
3779 }
3780
3781 bool visitAnnotatedNode(AnnotatedNode node) {
3782 if (identical(node.documentationComment, _oldNode)) {
3783 node.documentationComment = _newNode as Comment;
3784 return true;
3785 } else if (_replaceInList(node.metadata)) {
3786 return true;
3787 }
3788 return visitNode(node);
3789 }
3790
3791 @override
3792 bool visitAnnotation(Annotation node) {
3793 if (identical(node.arguments, _oldNode)) {
3794 node.arguments = _newNode as ArgumentList;
3795 return true;
3796 } else if (identical(node.constructorName, _oldNode)) {
3797 node.constructorName = _newNode as SimpleIdentifier;
3798 return true;
3799 } else if (identical(node.name, _oldNode)) {
3800 node.name = _newNode as Identifier;
3801 return true;
3802 }
3803 return visitNode(node);
3804 }
3805
3806 @override
3807 bool visitArgumentList(ArgumentList node) {
3808 if (_replaceInList(node.arguments)) {
3809 return true;
3810 }
3811 return visitNode(node);
3812 }
3813
3814 @override
3815 bool visitAsExpression(AsExpression node) {
3816 if (identical(node.expression, _oldNode)) {
3817 node.expression = _newNode as Expression;
3818 return true;
3819 } else if (identical(node.type, _oldNode)) {
3820 node.type = _newNode as TypeName;
3821 return true;
3822 }
3823 return visitNode(node);
3824 }
3825
3826 @override
3827 bool visitAssertStatement(AssertStatement node) {
3828 if (identical(node.condition, _oldNode)) {
3829 node.condition = _newNode as Expression;
3830 return true;
3831 }
3832 if (identical(node.message, _oldNode)) {
3833 node.message = _newNode as Expression;
3834 return true;
3835 }
3836 return visitNode(node);
3837 }
3838
3839 @override
3840 bool visitAssignmentExpression(AssignmentExpression node) {
3841 if (identical(node.leftHandSide, _oldNode)) {
3842 node.leftHandSide = _newNode as Expression;
3843 return true;
3844 } else if (identical(node.rightHandSide, _oldNode)) {
3845 node.rightHandSide = _newNode as Expression;
3846 return true;
3847 }
3848 return visitNode(node);
3849 }
3850
3851 @override
3852 bool visitAwaitExpression(AwaitExpression node) {
3853 if (identical(node.expression, _oldNode)) {
3854 node.expression = _newNode as Expression;
3855 return true;
3856 }
3857 return visitNode(node);
3858 }
3859
3860 @override
3861 bool visitBinaryExpression(BinaryExpression node) {
3862 if (identical(node.leftOperand, _oldNode)) {
3863 node.leftOperand = _newNode as Expression;
3864 return true;
3865 } else if (identical(node.rightOperand, _oldNode)) {
3866 node.rightOperand = _newNode as Expression;
3867 return true;
3868 }
3869 return visitNode(node);
3870 }
3871
3872 @override
3873 bool visitBlock(Block node) {
3874 if (_replaceInList(node.statements)) {
3875 return true;
3876 }
3877 return visitNode(node);
3878 }
3879
3880 @override
3881 bool visitBlockFunctionBody(BlockFunctionBody node) {
3882 if (identical(node.block, _oldNode)) {
3883 node.block = _newNode as Block;
3884 return true;
3885 }
3886 return visitNode(node);
3887 }
3888
3889 @override
3890 bool visitBooleanLiteral(BooleanLiteral node) => visitNode(node);
3891
3892 @override
3893 bool visitBreakStatement(BreakStatement node) {
3894 if (identical(node.label, _oldNode)) {
3895 node.label = _newNode as SimpleIdentifier;
3896 return true;
3897 }
3898 return visitNode(node);
3899 }
3900
3901 @override
3902 bool visitCascadeExpression(CascadeExpression node) {
3903 if (identical(node.target, _oldNode)) {
3904 node.target = _newNode as Expression;
3905 return true;
3906 } else if (_replaceInList(node.cascadeSections)) {
3907 return true;
3908 }
3909 return visitNode(node);
3910 }
3911
3912 @override
3913 bool visitCatchClause(CatchClause node) {
3914 if (identical(node.exceptionType, _oldNode)) {
3915 node.exceptionType = _newNode as TypeName;
3916 return true;
3917 } else if (identical(node.exceptionParameter, _oldNode)) {
3918 node.exceptionParameter = _newNode as SimpleIdentifier;
3919 return true;
3920 } else if (identical(node.stackTraceParameter, _oldNode)) {
3921 node.stackTraceParameter = _newNode as SimpleIdentifier;
3922 return true;
3923 }
3924 return visitNode(node);
3925 }
3926
3927 @override
3928 bool visitClassDeclaration(ClassDeclaration node) {
3929 if (identical(node.name, _oldNode)) {
3930 node.name = _newNode as SimpleIdentifier;
3931 return true;
3932 } else if (identical(node.typeParameters, _oldNode)) {
3933 node.typeParameters = _newNode as TypeParameterList;
3934 return true;
3935 } else if (identical(node.extendsClause, _oldNode)) {
3936 node.extendsClause = _newNode as ExtendsClause;
3937 return true;
3938 } else if (identical(node.withClause, _oldNode)) {
3939 node.withClause = _newNode as WithClause;
3940 return true;
3941 } else if (identical(node.implementsClause, _oldNode)) {
3942 node.implementsClause = _newNode as ImplementsClause;
3943 return true;
3944 } else if (identical(node.nativeClause, _oldNode)) {
3945 node.nativeClause = _newNode as NativeClause;
3946 return true;
3947 } else if (_replaceInList(node.members)) {
3948 return true;
3949 }
3950 return visitAnnotatedNode(node);
3951 }
3952
3953 @override
3954 bool visitClassTypeAlias(ClassTypeAlias node) {
3955 if (identical(node.name, _oldNode)) {
3956 node.name = _newNode as SimpleIdentifier;
3957 return true;
3958 } else if (identical(node.typeParameters, _oldNode)) {
3959 node.typeParameters = _newNode as TypeParameterList;
3960 return true;
3961 } else if (identical(node.superclass, _oldNode)) {
3962 node.superclass = _newNode as TypeName;
3963 return true;
3964 } else if (identical(node.withClause, _oldNode)) {
3965 node.withClause = _newNode as WithClause;
3966 return true;
3967 } else if (identical(node.implementsClause, _oldNode)) {
3968 node.implementsClause = _newNode as ImplementsClause;
3969 return true;
3970 }
3971 return visitAnnotatedNode(node);
3972 }
3973
3974 @override
3975 bool visitComment(Comment node) {
3976 if (_replaceInList(node.references)) {
3977 return true;
3978 }
3979 return visitNode(node);
3980 }
3981
3982 @override
3983 bool visitCommentReference(CommentReference node) {
3984 if (identical(node.identifier, _oldNode)) {
3985 node.identifier = _newNode as Identifier;
3986 return true;
3987 }
3988 return visitNode(node);
3989 }
3990
3991 @override
3992 bool visitCompilationUnit(CompilationUnit node) {
3993 if (identical(node.scriptTag, _oldNode)) {
3994 node.scriptTag = _newNode as ScriptTag;
3995 return true;
3996 } else if (_replaceInList(node.directives)) {
3997 return true;
3998 } else if (_replaceInList(node.declarations)) {
3999 return true;
4000 }
4001 return visitNode(node);
4002 }
4003
4004 @override
4005 bool visitConditionalExpression(ConditionalExpression node) {
4006 if (identical(node.condition, _oldNode)) {
4007 node.condition = _newNode as Expression;
4008 return true;
4009 } else if (identical(node.thenExpression, _oldNode)) {
4010 node.thenExpression = _newNode as Expression;
4011 return true;
4012 } else if (identical(node.elseExpression, _oldNode)) {
4013 node.elseExpression = _newNode as Expression;
4014 return true;
4015 }
4016 return visitNode(node);
4017 }
4018
4019 @override
4020 bool visitConfiguration(Configuration node) {
4021 if (identical(node.name, _oldNode)) {
4022 node.name = _newNode as DottedName;
4023 return true;
4024 } else if (identical(node.value, _oldNode)) {
4025 node.value = _newNode as StringLiteral;
4026 return true;
4027 } else if (identical(node.libraryUri, _oldNode)) {
4028 node.libraryUri = _newNode as StringLiteral;
4029 return true;
4030 }
4031 return visitNode(node);
4032 }
4033
4034 @override
4035 bool visitConstructorDeclaration(ConstructorDeclaration node) {
4036 if (identical(node.returnType, _oldNode)) {
4037 node.returnType = _newNode as Identifier;
4038 return true;
4039 } else if (identical(node.name, _oldNode)) {
4040 node.name = _newNode as SimpleIdentifier;
4041 return true;
4042 } else if (identical(node.parameters, _oldNode)) {
4043 node.parameters = _newNode as FormalParameterList;
4044 return true;
4045 } else if (identical(node.redirectedConstructor, _oldNode)) {
4046 node.redirectedConstructor = _newNode as ConstructorName;
4047 return true;
4048 } else if (identical(node.body, _oldNode)) {
4049 node.body = _newNode as FunctionBody;
4050 return true;
4051 } else if (_replaceInList(node.initializers)) {
4052 return true;
4053 }
4054 return visitAnnotatedNode(node);
4055 }
4056
4057 @override
4058 bool visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
4059 if (identical(node.fieldName, _oldNode)) {
4060 node.fieldName = _newNode as SimpleIdentifier;
4061 return true;
4062 } else if (identical(node.expression, _oldNode)) {
4063 node.expression = _newNode as Expression;
4064 return true;
4065 }
4066 return visitNode(node);
4067 }
4068
4069 @override
4070 bool visitConstructorName(ConstructorName node) {
4071 if (identical(node.type, _oldNode)) {
4072 node.type = _newNode as TypeName;
4073 return true;
4074 } else if (identical(node.name, _oldNode)) {
4075 node.name = _newNode as SimpleIdentifier;
4076 return true;
4077 }
4078 return visitNode(node);
4079 }
4080
4081 @override
4082 bool visitContinueStatement(ContinueStatement node) {
4083 if (identical(node.label, _oldNode)) {
4084 node.label = _newNode as SimpleIdentifier;
4085 return true;
4086 }
4087 return visitNode(node);
4088 }
4089
4090 @override
4091 bool visitDeclaredIdentifier(DeclaredIdentifier node) {
4092 if (identical(node.type, _oldNode)) {
4093 node.type = _newNode as TypeName;
4094 return true;
4095 } else if (identical(node.identifier, _oldNode)) {
4096 node.identifier = _newNode as SimpleIdentifier;
4097 return true;
4098 }
4099 return visitAnnotatedNode(node);
4100 }
4101
4102 @override
4103 bool visitDefaultFormalParameter(DefaultFormalParameter node) {
4104 if (identical(node.parameter, _oldNode)) {
4105 node.parameter = _newNode as NormalFormalParameter;
4106 return true;
4107 } else if (identical(node.defaultValue, _oldNode)) {
4108 node.defaultValue = _newNode as Expression;
4109 return true;
4110 }
4111 return visitNode(node);
4112 }
4113
4114 @override
4115 bool visitDoStatement(DoStatement node) {
4116 if (identical(node.body, _oldNode)) {
4117 node.body = _newNode as Statement;
4118 return true;
4119 } else if (identical(node.condition, _oldNode)) {
4120 node.condition = _newNode as Expression;
4121 return true;
4122 }
4123 return visitNode(node);
4124 }
4125
4126 @override
4127 bool visitDottedName(DottedName node) {
4128 if (_replaceInList(node.components)) {
4129 return true;
4130 }
4131 return visitNode(node);
4132 }
4133
4134 @override
4135 bool visitDoubleLiteral(DoubleLiteral node) => visitNode(node);
4136
4137 @override
4138 bool visitEmptyFunctionBody(EmptyFunctionBody node) => visitNode(node);
4139
4140 @override
4141 bool visitEmptyStatement(EmptyStatement node) => visitNode(node);
4142
4143 @override
4144 bool visitEnumConstantDeclaration(EnumConstantDeclaration node) {
4145 if (identical(node.name, _oldNode)) {
4146 node.name = _newNode as SimpleIdentifier;
4147 return true;
4148 }
4149 return visitAnnotatedNode(node);
4150 }
4151
4152 @override
4153 bool visitEnumDeclaration(EnumDeclaration node) {
4154 if (identical(node.name, _oldNode)) {
4155 node.name = _newNode as SimpleIdentifier;
4156 return true;
4157 } else if (_replaceInList(node.constants)) {
4158 return true;
4159 }
4160 return visitAnnotatedNode(node);
4161 }
4162
4163 @override
4164 bool visitExportDirective(ExportDirective node) =>
4165 visitNamespaceDirective(node);
4166
4167 @override
4168 bool visitExpressionFunctionBody(ExpressionFunctionBody node) {
4169 if (identical(node.expression, _oldNode)) {
4170 node.expression = _newNode as Expression;
4171 return true;
4172 }
4173 return visitNode(node);
4174 }
4175
4176 @override
4177 bool visitExpressionStatement(ExpressionStatement node) {
4178 if (identical(node.expression, _oldNode)) {
4179 node.expression = _newNode as Expression;
4180 return true;
4181 }
4182 return visitNode(node);
4183 }
4184
4185 @override
4186 bool visitExtendsClause(ExtendsClause node) {
4187 if (identical(node.superclass, _oldNode)) {
4188 node.superclass = _newNode as TypeName;
4189 return true;
4190 }
4191 return visitNode(node);
4192 }
4193
4194 @override
4195 bool visitFieldDeclaration(FieldDeclaration node) {
4196 if (identical(node.fields, _oldNode)) {
4197 node.fields = _newNode as VariableDeclarationList;
4198 return true;
4199 }
4200 return visitAnnotatedNode(node);
4201 }
4202
4203 @override
4204 bool visitFieldFormalParameter(FieldFormalParameter node) {
4205 if (identical(node.type, _oldNode)) {
4206 node.type = _newNode as TypeName;
4207 return true;
4208 } else if (identical(node.parameters, _oldNode)) {
4209 node.parameters = _newNode as FormalParameterList;
4210 return true;
4211 }
4212 return visitNormalFormalParameter(node);
4213 }
4214
4215 @override
4216 bool visitForEachStatement(ForEachStatement node) {
4217 if (identical(node.loopVariable, _oldNode)) {
4218 node.loopVariable = _newNode as DeclaredIdentifier;
4219 return true;
4220 } else if (identical(node.identifier, _oldNode)) {
4221 node.identifier = _newNode as SimpleIdentifier;
4222 return true;
4223 } else if (identical(node.iterable, _oldNode)) {
4224 node.iterable = _newNode as Expression;
4225 return true;
4226 } else if (identical(node.body, _oldNode)) {
4227 node.body = _newNode as Statement;
4228 return true;
4229 }
4230 return visitNode(node);
4231 }
4232
4233 @override
4234 bool visitFormalParameterList(FormalParameterList node) {
4235 if (_replaceInList(node.parameters)) {
4236 return true;
4237 }
4238 return visitNode(node);
4239 }
4240
4241 @override
4242 bool visitForStatement(ForStatement node) {
4243 if (identical(node.variables, _oldNode)) {
4244 node.variables = _newNode as VariableDeclarationList;
4245 return true;
4246 } else if (identical(node.initialization, _oldNode)) {
4247 node.initialization = _newNode as Expression;
4248 return true;
4249 } else if (identical(node.condition, _oldNode)) {
4250 node.condition = _newNode as Expression;
4251 return true;
4252 } else if (identical(node.body, _oldNode)) {
4253 node.body = _newNode as Statement;
4254 return true;
4255 } else if (_replaceInList(node.updaters)) {
4256 return true;
4257 }
4258 return visitNode(node);
4259 }
4260
4261 @override
4262 bool visitFunctionDeclaration(FunctionDeclaration node) {
4263 if (identical(node.returnType, _oldNode)) {
4264 node.returnType = _newNode as TypeName;
4265 return true;
4266 } else if (identical(node.name, _oldNode)) {
4267 node.name = _newNode as SimpleIdentifier;
4268 return true;
4269 } else if (identical(node.functionExpression, _oldNode)) {
4270 node.functionExpression = _newNode as FunctionExpression;
4271 return true;
4272 }
4273 return visitAnnotatedNode(node);
4274 }
4275
4276 @override
4277 bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
4278 if (identical(node.functionDeclaration, _oldNode)) {
4279 node.functionDeclaration = _newNode as FunctionDeclaration;
4280 return true;
4281 }
4282 return visitNode(node);
4283 }
4284
4285 @override
4286 bool visitFunctionExpression(FunctionExpression node) {
4287 if (identical(node.parameters, _oldNode)) {
4288 node.parameters = _newNode as FormalParameterList;
4289 return true;
4290 } else if (identical(node.body, _oldNode)) {
4291 node.body = _newNode as FunctionBody;
4292 return true;
4293 }
4294 return visitNode(node);
4295 }
4296
4297 @override
4298 bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
4299 if (identical(node.function, _oldNode)) {
4300 node.function = _newNode as Expression;
4301 return true;
4302 } else if (identical(node.argumentList, _oldNode)) {
4303 node.argumentList = _newNode as ArgumentList;
4304 return true;
4305 }
4306 return visitNode(node);
4307 }
4308
4309 @override
4310 bool visitFunctionTypeAlias(FunctionTypeAlias node) {
4311 if (identical(node.returnType, _oldNode)) {
4312 node.returnType = _newNode as TypeName;
4313 return true;
4314 } else if (identical(node.name, _oldNode)) {
4315 node.name = _newNode as SimpleIdentifier;
4316 return true;
4317 } else if (identical(node.typeParameters, _oldNode)) {
4318 node.typeParameters = _newNode as TypeParameterList;
4319 return true;
4320 } else if (identical(node.parameters, _oldNode)) {
4321 node.parameters = _newNode as FormalParameterList;
4322 return true;
4323 }
4324 return visitAnnotatedNode(node);
4325 }
4326
4327 @override
4328 bool visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
4329 if (identical(node.returnType, _oldNode)) {
4330 node.returnType = _newNode as TypeName;
4331 return true;
4332 } else if (identical(node.parameters, _oldNode)) {
4333 node.parameters = _newNode as FormalParameterList;
4334 return true;
4335 }
4336 return visitNormalFormalParameter(node);
4337 }
4338
4339 @override
4340 bool visitHideCombinator(HideCombinator node) {
4341 if (_replaceInList(node.hiddenNames)) {
4342 return true;
4343 }
4344 return visitNode(node);
4345 }
4346
4347 @override
4348 bool visitIfStatement(IfStatement node) {
4349 if (identical(node.condition, _oldNode)) {
4350 node.condition = _newNode as Expression;
4351 return true;
4352 } else if (identical(node.thenStatement, _oldNode)) {
4353 node.thenStatement = _newNode as Statement;
4354 return true;
4355 } else if (identical(node.elseStatement, _oldNode)) {
4356 node.elseStatement = _newNode as Statement;
4357 return true;
4358 }
4359 return visitNode(node);
4360 }
4361
4362 @override
4363 bool visitImplementsClause(ImplementsClause node) {
4364 if (_replaceInList(node.interfaces)) {
4365 return true;
4366 }
4367 return visitNode(node);
4368 }
4369
4370 @override
4371 bool visitImportDirective(ImportDirective node) {
4372 if (identical(node.prefix, _oldNode)) {
4373 node.prefix = _newNode as SimpleIdentifier;
4374 return true;
4375 }
4376 return visitNamespaceDirective(node);
4377 }
4378
4379 @override
4380 bool visitIndexExpression(IndexExpression node) {
4381 if (identical(node.target, _oldNode)) {
4382 node.target = _newNode as Expression;
4383 return true;
4384 } else if (identical(node.index, _oldNode)) {
4385 node.index = _newNode as Expression;
4386 return true;
4387 }
4388 return visitNode(node);
4389 }
4390
4391 @override
4392 bool visitInstanceCreationExpression(InstanceCreationExpression node) {
4393 if (identical(node.constructorName, _oldNode)) {
4394 node.constructorName = _newNode as ConstructorName;
4395 return true;
4396 } else if (identical(node.argumentList, _oldNode)) {
4397 node.argumentList = _newNode as ArgumentList;
4398 return true;
4399 }
4400 return visitNode(node);
4401 }
4402
4403 @override
4404 bool visitIntegerLiteral(IntegerLiteral node) => visitNode(node);
4405
4406 @override
4407 bool visitInterpolationExpression(InterpolationExpression node) {
4408 if (identical(node.expression, _oldNode)) {
4409 node.expression = _newNode as Expression;
4410 return true;
4411 }
4412 return visitNode(node);
4413 }
4414
4415 @override
4416 bool visitInterpolationString(InterpolationString node) => visitNode(node);
4417
4418 @override
4419 bool visitIsExpression(IsExpression node) {
4420 if (identical(node.expression, _oldNode)) {
4421 node.expression = _newNode as Expression;
4422 return true;
4423 } else if (identical(node.type, _oldNode)) {
4424 node.type = _newNode as TypeName;
4425 return true;
4426 }
4427 return visitNode(node);
4428 }
4429
4430 @override
4431 bool visitLabel(Label node) {
4432 if (identical(node.label, _oldNode)) {
4433 node.label = _newNode as SimpleIdentifier;
4434 return true;
4435 }
4436 return visitNode(node);
4437 }
4438
4439 @override
4440 bool visitLabeledStatement(LabeledStatement node) {
4441 if (identical(node.statement, _oldNode)) {
4442 node.statement = _newNode as Statement;
4443 return true;
4444 } else if (_replaceInList(node.labels)) {
4445 return true;
4446 }
4447 return visitNode(node);
4448 }
4449
4450 @override
4451 bool visitLibraryDirective(LibraryDirective node) {
4452 if (identical(node.name, _oldNode)) {
4453 node.name = _newNode as LibraryIdentifier;
4454 return true;
4455 }
4456 return visitAnnotatedNode(node);
4457 }
4458
4459 @override
4460 bool visitLibraryIdentifier(LibraryIdentifier node) {
4461 if (_replaceInList(node.components)) {
4462 return true;
4463 }
4464 return visitNode(node);
4465 }
4466
4467 @override
4468 bool visitListLiteral(ListLiteral node) {
4469 if (_replaceInList(node.elements)) {
4470 return true;
4471 }
4472 return visitTypedLiteral(node);
4473 }
4474
4475 @override
4476 bool visitMapLiteral(MapLiteral node) {
4477 if (_replaceInList(node.entries)) {
4478 return true;
4479 }
4480 return visitTypedLiteral(node);
4481 }
4482
4483 @override
4484 bool visitMapLiteralEntry(MapLiteralEntry node) {
4485 if (identical(node.key, _oldNode)) {
4486 node.key = _newNode as Expression;
4487 return true;
4488 } else if (identical(node.value, _oldNode)) {
4489 node.value = _newNode as Expression;
4490 return true;
4491 }
4492 return visitNode(node);
4493 }
4494
4495 @override
4496 bool visitMethodDeclaration(MethodDeclaration node) {
4497 if (identical(node.returnType, _oldNode)) {
4498 node.returnType = _newNode as TypeName;
4499 return true;
4500 } else if (identical(node.name, _oldNode)) {
4501 node.name = _newNode as SimpleIdentifier;
4502 return true;
4503 } else if (identical(node.parameters, _oldNode)) {
4504 node.parameters = _newNode as FormalParameterList;
4505 return true;
4506 } else if (identical(node.body, _oldNode)) {
4507 node.body = _newNode as FunctionBody;
4508 return true;
4509 }
4510 return visitAnnotatedNode(node);
4511 }
4512
4513 @override
4514 bool visitMethodInvocation(MethodInvocation node) {
4515 if (identical(node.target, _oldNode)) {
4516 node.target = _newNode as Expression;
4517 return true;
4518 } else if (identical(node.methodName, _oldNode)) {
4519 node.methodName = _newNode as SimpleIdentifier;
4520 return true;
4521 } else if (identical(node.argumentList, _oldNode)) {
4522 node.argumentList = _newNode as ArgumentList;
4523 return true;
4524 }
4525 return visitNode(node);
4526 }
4527
4528 @override
4529 bool visitNamedExpression(NamedExpression node) {
4530 if (identical(node.name, _oldNode)) {
4531 node.name = _newNode as Label;
4532 return true;
4533 } else if (identical(node.expression, _oldNode)) {
4534 node.expression = _newNode as Expression;
4535 return true;
4536 }
4537 return visitNode(node);
4538 }
4539
4540 bool visitNamespaceDirective(NamespaceDirective node) {
4541 if (_replaceInList(node.combinators)) {
4542 return true;
4543 }
4544 return visitUriBasedDirective(node);
4545 }
4546
4547 @override
4548 bool visitNativeClause(NativeClause node) {
4549 if (identical(node.name, _oldNode)) {
4550 node.name = _newNode as StringLiteral;
4551 return true;
4552 }
4553 return visitNode(node);
4554 }
4555
4556 @override
4557 bool visitNativeFunctionBody(NativeFunctionBody node) {
4558 if (identical(node.stringLiteral, _oldNode)) {
4559 node.stringLiteral = _newNode as StringLiteral;
4560 return true;
4561 }
4562 return visitNode(node);
4563 }
4564
4565 bool visitNode(AstNode node) {
4566 throw new IllegalArgumentException(
4567 "The old node is not a child of it's parent");
4568 }
4569
4570 bool visitNormalFormalParameter(NormalFormalParameter node) {
4571 if (identical(node.documentationComment, _oldNode)) {
4572 node.documentationComment = _newNode as Comment;
4573 return true;
4574 } else if (identical(node.identifier, _oldNode)) {
4575 node.identifier = _newNode as SimpleIdentifier;
4576 return true;
4577 } else if (_replaceInList(node.metadata)) {
4578 return true;
4579 }
4580 return visitNode(node);
4581 }
4582
4583 @override
4584 bool visitNullLiteral(NullLiteral node) => visitNode(node);
4585
4586 @override
4587 bool visitParenthesizedExpression(ParenthesizedExpression node) {
4588 if (identical(node.expression, _oldNode)) {
4589 node.expression = _newNode as Expression;
4590 return true;
4591 }
4592 return visitNode(node);
4593 }
4594
4595 @override
4596 bool visitPartDirective(PartDirective node) => visitUriBasedDirective(node);
4597
4598 @override
4599 bool visitPartOfDirective(PartOfDirective node) {
4600 if (identical(node.libraryName, _oldNode)) {
4601 node.libraryName = _newNode as LibraryIdentifier;
4602 return true;
4603 }
4604 return visitAnnotatedNode(node);
4605 }
4606
4607 @override
4608 bool visitPostfixExpression(PostfixExpression node) {
4609 if (identical(node.operand, _oldNode)) {
4610 node.operand = _newNode as Expression;
4611 return true;
4612 }
4613 return visitNode(node);
4614 }
4615
4616 @override
4617 bool visitPrefixedIdentifier(PrefixedIdentifier node) {
4618 if (identical(node.prefix, _oldNode)) {
4619 node.prefix = _newNode as SimpleIdentifier;
4620 return true;
4621 } else if (identical(node.identifier, _oldNode)) {
4622 node.identifier = _newNode as SimpleIdentifier;
4623 return true;
4624 }
4625 return visitNode(node);
4626 }
4627
4628 @override
4629 bool visitPrefixExpression(PrefixExpression node) {
4630 if (identical(node.operand, _oldNode)) {
4631 node.operand = _newNode as Expression;
4632 return true;
4633 }
4634 return visitNode(node);
4635 }
4636
4637 @override
4638 bool visitPropertyAccess(PropertyAccess node) {
4639 if (identical(node.target, _oldNode)) {
4640 node.target = _newNode as Expression;
4641 return true;
4642 } else if (identical(node.propertyName, _oldNode)) {
4643 node.propertyName = _newNode as SimpleIdentifier;
4644 return true;
4645 }
4646 return visitNode(node);
4647 }
4648
4649 @override
4650 bool visitRedirectingConstructorInvocation(
4651 RedirectingConstructorInvocation node) {
4652 if (identical(node.constructorName, _oldNode)) {
4653 node.constructorName = _newNode as SimpleIdentifier;
4654 return true;
4655 } else if (identical(node.argumentList, _oldNode)) {
4656 node.argumentList = _newNode as ArgumentList;
4657 return true;
4658 }
4659 return visitNode(node);
4660 }
4661
4662 @override
4663 bool visitRethrowExpression(RethrowExpression node) => visitNode(node);
4664
4665 @override
4666 bool visitReturnStatement(ReturnStatement node) {
4667 if (identical(node.expression, _oldNode)) {
4668 node.expression = _newNode as Expression;
4669 return true;
4670 }
4671 return visitNode(node);
4672 }
4673
4674 @override
4675 bool visitScriptTag(ScriptTag scriptTag) => visitNode(scriptTag);
4676
4677 @override
4678 bool visitShowCombinator(ShowCombinator node) {
4679 if (_replaceInList(node.shownNames)) {
4680 return true;
4681 }
4682 return visitNode(node);
4683 }
4684
4685 @override
4686 bool visitSimpleFormalParameter(SimpleFormalParameter node) {
4687 if (identical(node.type, _oldNode)) {
4688 node.type = _newNode as TypeName;
4689 return true;
4690 }
4691 return visitNormalFormalParameter(node);
4692 }
4693
4694 @override
4695 bool visitSimpleIdentifier(SimpleIdentifier node) => visitNode(node);
4696
4697 @override
4698 bool visitSimpleStringLiteral(SimpleStringLiteral node) => visitNode(node);
4699
4700 @override
4701 bool visitStringInterpolation(StringInterpolation node) {
4702 if (_replaceInList(node.elements)) {
4703 return true;
4704 }
4705 return visitNode(node);
4706 }
4707
4708 @override
4709 bool visitSuperConstructorInvocation(SuperConstructorInvocation node) {
4710 if (identical(node.constructorName, _oldNode)) {
4711 node.constructorName = _newNode as SimpleIdentifier;
4712 return true;
4713 } else if (identical(node.argumentList, _oldNode)) {
4714 node.argumentList = _newNode as ArgumentList;
4715 return true;
4716 }
4717 return visitNode(node);
4718 }
4719
4720 @override
4721 bool visitSuperExpression(SuperExpression node) => visitNode(node);
4722
4723 @override
4724 bool visitSwitchCase(SwitchCase node) {
4725 if (identical(node.expression, _oldNode)) {
4726 node.expression = _newNode as Expression;
4727 return true;
4728 }
4729 return visitSwitchMember(node);
4730 }
4731
4732 @override
4733 bool visitSwitchDefault(SwitchDefault node) => visitSwitchMember(node);
4734
4735 bool visitSwitchMember(SwitchMember node) {
4736 if (_replaceInList(node.labels)) {
4737 return true;
4738 } else if (_replaceInList(node.statements)) {
4739 return true;
4740 }
4741 return visitNode(node);
4742 }
4743
4744 @override
4745 bool visitSwitchStatement(SwitchStatement node) {
4746 if (identical(node.expression, _oldNode)) {
4747 node.expression = _newNode as Expression;
4748 return true;
4749 } else if (_replaceInList(node.members)) {
4750 return true;
4751 }
4752 return visitNode(node);
4753 }
4754
4755 @override
4756 bool visitSymbolLiteral(SymbolLiteral node) => visitNode(node);
4757
4758 @override
4759 bool visitThisExpression(ThisExpression node) => visitNode(node);
4760
4761 @override
4762 bool visitThrowExpression(ThrowExpression node) {
4763 if (identical(node.expression, _oldNode)) {
4764 node.expression = _newNode as Expression;
4765 return true;
4766 }
4767 return visitNode(node);
4768 }
4769
4770 @override
4771 bool visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
4772 if (identical(node.variables, _oldNode)) {
4773 node.variables = _newNode as VariableDeclarationList;
4774 return true;
4775 }
4776 return visitAnnotatedNode(node);
4777 }
4778
4779 @override
4780 bool visitTryStatement(TryStatement node) {
4781 if (identical(node.body, _oldNode)) {
4782 node.body = _newNode as Block;
4783 return true;
4784 } else if (identical(node.finallyBlock, _oldNode)) {
4785 node.finallyBlock = _newNode as Block;
4786 return true;
4787 } else if (_replaceInList(node.catchClauses)) {
4788 return true;
4789 }
4790 return visitNode(node);
4791 }
4792
4793 @override
4794 bool visitTypeArgumentList(TypeArgumentList node) {
4795 if (_replaceInList(node.arguments)) {
4796 return true;
4797 }
4798 return visitNode(node);
4799 }
4800
4801 bool visitTypedLiteral(TypedLiteral node) {
4802 if (identical(node.typeArguments, _oldNode)) {
4803 node.typeArguments = _newNode as TypeArgumentList;
4804 return true;
4805 }
4806 return visitNode(node);
4807 }
4808
4809 @override
4810 bool visitTypeName(TypeName node) {
4811 if (identical(node.name, _oldNode)) {
4812 node.name = _newNode as Identifier;
4813 return true;
4814 } else if (identical(node.typeArguments, _oldNode)) {
4815 node.typeArguments = _newNode as TypeArgumentList;
4816 return true;
4817 }
4818 return visitNode(node);
4819 }
4820
4821 @override
4822 bool visitTypeParameter(TypeParameter node) {
4823 if (identical(node.name, _oldNode)) {
4824 node.name = _newNode as SimpleIdentifier;
4825 return true;
4826 } else if (identical(node.bound, _oldNode)) {
4827 node.bound = _newNode as TypeName;
4828 return true;
4829 }
4830 return visitNode(node);
4831 }
4832
4833 @override
4834 bool visitTypeParameterList(TypeParameterList node) {
4835 if (_replaceInList(node.typeParameters)) {
4836 return true;
4837 }
4838 return visitNode(node);
4839 }
4840
4841 bool visitUriBasedDirective(UriBasedDirective node) {
4842 if (identical(node.uri, _oldNode)) {
4843 node.uri = _newNode as StringLiteral;
4844 return true;
4845 }
4846 return visitAnnotatedNode(node);
4847 }
4848
4849 @override
4850 bool visitVariableDeclaration(VariableDeclaration node) {
4851 if (identical(node.name, _oldNode)) {
4852 node.name = _newNode as SimpleIdentifier;
4853 return true;
4854 } else if (identical(node.initializer, _oldNode)) {
4855 node.initializer = _newNode as Expression;
4856 return true;
4857 }
4858 return visitAnnotatedNode(node);
4859 }
4860
4861 @override
4862 bool visitVariableDeclarationList(VariableDeclarationList node) {
4863 if (identical(node.type, _oldNode)) {
4864 node.type = _newNode as TypeName;
4865 return true;
4866 } else if (_replaceInList(node.variables)) {
4867 return true;
4868 }
4869 return visitNode(node);
4870 }
4871
4872 @override
4873 bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
4874 if (identical(node.variables, _oldNode)) {
4875 node.variables = _newNode as VariableDeclarationList;
4876 return true;
4877 }
4878 return visitNode(node);
4879 }
4880
4881 @override
4882 bool visitWhileStatement(WhileStatement node) {
4883 if (identical(node.condition, _oldNode)) {
4884 node.condition = _newNode as Expression;
4885 return true;
4886 } else if (identical(node.body, _oldNode)) {
4887 node.body = _newNode as Statement;
4888 return true;
4889 }
4890 return visitNode(node);
4891 }
4892
4893 @override
4894 bool visitWithClause(WithClause node) {
4895 if (_replaceInList(node.mixinTypes)) {
4896 return true;
4897 }
4898 return visitNode(node);
4899 }
4900
4901 @override
4902 bool visitYieldStatement(YieldStatement node) {
4903 if (identical(node.expression, _oldNode)) {
4904 node.expression = _newNode as Expression;
4905 return true;
4906 }
4907 return visitNode(node);
4908 }
4909
4910 bool _replaceInList(NodeList list) {
4911 int count = list.length;
4912 for (int i = 0; i < count; i++) {
4913 if (identical(_oldNode, list[i])) {
4914 list[i] = _newNode;
4915 return true;
4916 }
4917 }
4918 return false;
4919 }
4920
4921 /**
4922 * Replace the [oldNode] with the [newNode] in the AST structure containing
4923 * the old node. Return `true` if the replacement was successful.
4924 *
4925 * Throws an [IllegalArgumentException] if either node is `null`, if the old
4926 * node does not have a parent node, or if the AST structure has been
4927 * corrupted.
4928 */
4929 static bool replace(AstNode oldNode, AstNode newNode) {
4930 if (oldNode == null || newNode == null) {
4931 throw new IllegalArgumentException(
4932 "The old and new nodes must be non-null");
4933 } else if (identical(oldNode, newNode)) {
4934 return true;
4935 }
4936 AstNode parent = oldNode.parent;
4937 if (parent == null) {
4938 throw new IllegalArgumentException(
4939 "The old node is not a child of another node");
4940 }
4941 NodeReplacer replacer = new NodeReplacer(oldNode, newNode);
4942 return parent.accept(replacer);
4943 }
4944 }
4945
4946 /**
4947 * Traverse the AST from initial child node to successive parents, building a
4948 * collection of local variable and parameter names visible to the initial child
4949 * node. In case of name shadowing, the first name seen is the most specific one
4950 * so names are not redefined.
4951 *
4952 * Completion test code coverage is 95%. The two basic blocks that are not
4953 * executed cannot be executed. They are included for future reference.
4954 */
4955 class ScopedNameFinder extends GeneralizingAstVisitor<Object> {
4956 Declaration _declarationNode;
4957
4958 AstNode _immediateChild;
4959
4960 Map<String, SimpleIdentifier> _locals =
4961 new HashMap<String, SimpleIdentifier>();
4962
4963 final int _position;
4964
4965 bool _referenceIsWithinLocalFunction = false;
4966
4967 ScopedNameFinder(this._position);
4968
4969 Declaration get declaration => _declarationNode;
4970
4971 Map<String, SimpleIdentifier> get locals => _locals;
4972
4973 @override
4974 Object visitBlock(Block node) {
4975 _checkStatements(node.statements);
4976 return super.visitBlock(node);
4977 }
4978
4979 @override
4980 Object visitCatchClause(CatchClause node) {
4981 _addToScope(node.exceptionParameter);
4982 _addToScope(node.stackTraceParameter);
4983 return super.visitCatchClause(node);
4984 }
4985
4986 @override
4987 Object visitConstructorDeclaration(ConstructorDeclaration node) {
4988 if (!identical(_immediateChild, node.parameters)) {
4989 _addParameters(node.parameters.parameters);
4990 }
4991 _declarationNode = node;
4992 return null;
4993 }
4994
4995 @override
4996 Object visitFieldDeclaration(FieldDeclaration node) {
4997 _declarationNode = node;
4998 return null;
4999 }
5000
5001 @override
5002 Object visitForEachStatement(ForEachStatement node) {
5003 DeclaredIdentifier loopVariable = node.loopVariable;
5004 if (loopVariable != null) {
5005 _addToScope(loopVariable.identifier);
5006 }
5007 return super.visitForEachStatement(node);
5008 }
5009
5010 @override
5011 Object visitForStatement(ForStatement node) {
5012 if (!identical(_immediateChild, node.variables) && node.variables != null) {
5013 _addVariables(node.variables.variables);
5014 }
5015 return super.visitForStatement(node);
5016 }
5017
5018 @override
5019 Object visitFunctionDeclaration(FunctionDeclaration node) {
5020 if (node.parent is! FunctionDeclarationStatement) {
5021 _declarationNode = node;
5022 return null;
5023 }
5024 return super.visitFunctionDeclaration(node);
5025 }
5026
5027 @override
5028 Object visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
5029 _referenceIsWithinLocalFunction = true;
5030 return super.visitFunctionDeclarationStatement(node);
5031 }
5032
5033 @override
5034 Object visitFunctionExpression(FunctionExpression node) {
5035 if (node.parameters != null &&
5036 !identical(_immediateChild, node.parameters)) {
5037 _addParameters(node.parameters.parameters);
5038 }
5039 return super.visitFunctionExpression(node);
5040 }
5041
5042 @override
5043 Object visitMethodDeclaration(MethodDeclaration node) {
5044 _declarationNode = node;
5045 if (node.parameters == null) {
5046 return null;
5047 }
5048 if (!identical(_immediateChild, node.parameters)) {
5049 _addParameters(node.parameters.parameters);
5050 }
5051 return null;
5052 }
5053
5054 @override
5055 Object visitNode(AstNode node) {
5056 _immediateChild = node;
5057 AstNode parent = node.parent;
5058 if (parent != null) {
5059 parent.accept(this);
5060 }
5061 return null;
5062 }
5063
5064 @override
5065 Object visitSwitchMember(SwitchMember node) {
5066 _checkStatements(node.statements);
5067 return super.visitSwitchMember(node);
5068 }
5069
5070 @override
5071 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
5072 _declarationNode = node;
5073 return null;
5074 }
5075
5076 @override
5077 Object visitTypeAlias(TypeAlias node) {
5078 _declarationNode = node;
5079 return null;
5080 }
5081
5082 void _addParameters(NodeList<FormalParameter> vars) {
5083 for (FormalParameter var2 in vars) {
5084 _addToScope(var2.identifier);
5085 }
5086 }
5087
5088 void _addToScope(SimpleIdentifier identifier) {
5089 if (identifier != null && _isInRange(identifier)) {
5090 String name = identifier.name;
5091 if (!_locals.containsKey(name)) {
5092 _locals[name] = identifier;
5093 }
5094 }
5095 }
5096
5097 void _addVariables(NodeList<VariableDeclaration> variables) {
5098 for (VariableDeclaration variable in variables) {
5099 _addToScope(variable.name);
5100 }
5101 }
5102
5103 /**
5104 * Check the given list of [statements] for any that come before the immediate
5105 * child and that define a name that would be visible to the immediate child.
5106 */
5107 void _checkStatements(List<Statement> statements) {
5108 for (Statement statement in statements) {
5109 if (identical(statement, _immediateChild)) {
5110 return;
5111 }
5112 if (statement is VariableDeclarationStatement) {
5113 _addVariables(statement.variables.variables);
5114 } else if (statement is FunctionDeclarationStatement &&
5115 !_referenceIsWithinLocalFunction) {
5116 _addToScope(statement.functionDeclaration.name);
5117 }
5118 }
5119 }
5120
5121 bool _isInRange(AstNode node) {
5122 if (_position < 0) {
5123 // if source position is not set then all nodes are in range
5124 return true;
5125 // not reached
5126 }
5127 return node.end < _position;
5128 }
5129 }
5130
5131 /**
5132 * A visitor used to write a source representation of a visited AST node (and
5133 * all of it's children) to a writer.
5134 */
5135 class ToSourceVisitor implements AstVisitor<Object> {
5136 /**
5137 * The writer to which the source is to be written.
5138 */
5139 final PrintWriter _writer;
5140
5141 /**
5142 * Initialize a newly created visitor to write source code representing the
5143 * visited nodes to the given [writer].
5144 */
5145 ToSourceVisitor(this._writer);
5146
5147 @override
5148 Object visitAdjacentStrings(AdjacentStrings node) {
5149 _visitNodeListWithSeparator(node.strings, " ");
5150 return null;
5151 }
5152
5153 @override
5154 Object visitAnnotation(Annotation node) {
5155 _writer.print('@');
5156 _visitNode(node.name);
5157 _visitNodeWithPrefix(".", node.constructorName);
5158 _visitNode(node.arguments);
5159 return null;
5160 }
5161
5162 @override
5163 Object visitArgumentList(ArgumentList node) {
5164 _writer.print('(');
5165 _visitNodeListWithSeparator(node.arguments, ", ");
5166 _writer.print(')');
5167 return null;
5168 }
5169
5170 @override
5171 Object visitAsExpression(AsExpression node) {
5172 _visitNode(node.expression);
5173 _writer.print(" as ");
5174 _visitNode(node.type);
5175 return null;
5176 }
5177
5178 @override
5179 Object visitAssertStatement(AssertStatement node) {
5180 _writer.print("assert (");
5181 _visitNode(node.condition);
5182 if (node.message != null) {
5183 _writer.print(', ');
5184 _visitNode(node.message);
5185 }
5186 _writer.print(");");
5187 return null;
5188 }
5189
5190 @override
5191 Object visitAssignmentExpression(AssignmentExpression node) {
5192 _visitNode(node.leftHandSide);
5193 _writer.print(' ');
5194 _writer.print(node.operator.lexeme);
5195 _writer.print(' ');
5196 _visitNode(node.rightHandSide);
5197 return null;
5198 }
5199
5200 @override
5201 Object visitAwaitExpression(AwaitExpression node) {
5202 _writer.print("await ");
5203 _visitNode(node.expression);
5204 return null;
5205 }
5206
5207 @override
5208 Object visitBinaryExpression(BinaryExpression node) {
5209 _visitNode(node.leftOperand);
5210 _writer.print(' ');
5211 _writer.print(node.operator.lexeme);
5212 _writer.print(' ');
5213 _visitNode(node.rightOperand);
5214 return null;
5215 }
5216
5217 @override
5218 Object visitBlock(Block node) {
5219 _writer.print('{');
5220 _visitNodeListWithSeparator(node.statements, " ");
5221 _writer.print('}');
5222 return null;
5223 }
5224
5225 @override
5226 Object visitBlockFunctionBody(BlockFunctionBody node) {
5227 Token keyword = node.keyword;
5228 if (keyword != null) {
5229 _writer.print(keyword.lexeme);
5230 if (node.star != null) {
5231 _writer.print('*');
5232 }
5233 _writer.print(' ');
5234 }
5235 _visitNode(node.block);
5236 return null;
5237 }
5238
5239 @override
5240 Object visitBooleanLiteral(BooleanLiteral node) {
5241 _writer.print(node.literal.lexeme);
5242 return null;
5243 }
5244
5245 @override
5246 Object visitBreakStatement(BreakStatement node) {
5247 _writer.print("break");
5248 _visitNodeWithPrefix(" ", node.label);
5249 _writer.print(";");
5250 return null;
5251 }
5252
5253 @override
5254 Object visitCascadeExpression(CascadeExpression node) {
5255 _visitNode(node.target);
5256 _visitNodeList(node.cascadeSections);
5257 return null;
5258 }
5259
5260 @override
5261 Object visitCatchClause(CatchClause node) {
5262 _visitNodeWithPrefix("on ", node.exceptionType);
5263 if (node.catchKeyword != null) {
5264 if (node.exceptionType != null) {
5265 _writer.print(' ');
5266 }
5267 _writer.print("catch (");
5268 _visitNode(node.exceptionParameter);
5269 _visitNodeWithPrefix(", ", node.stackTraceParameter);
5270 _writer.print(") ");
5271 } else {
5272 _writer.print(" ");
5273 }
5274 _visitNode(node.body);
5275 return null;
5276 }
5277
5278 @override
5279 Object visitClassDeclaration(ClassDeclaration node) {
5280 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5281 _visitTokenWithSuffix(node.abstractKeyword, " ");
5282 _writer.print("class ");
5283 _visitNode(node.name);
5284 _visitNode(node.typeParameters);
5285 _visitNodeWithPrefix(" ", node.extendsClause);
5286 _visitNodeWithPrefix(" ", node.withClause);
5287 _visitNodeWithPrefix(" ", node.implementsClause);
5288 _writer.print(" {");
5289 _visitNodeListWithSeparator(node.members, " ");
5290 _writer.print("}");
5291 return null;
5292 }
5293
5294 @override
5295 Object visitClassTypeAlias(ClassTypeAlias node) {
5296 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5297 if (node.abstractKeyword != null) {
5298 _writer.print("abstract ");
5299 }
5300 _writer.print("class ");
5301 _visitNode(node.name);
5302 _visitNode(node.typeParameters);
5303 _writer.print(" = ");
5304 _visitNode(node.superclass);
5305 _visitNodeWithPrefix(" ", node.withClause);
5306 _visitNodeWithPrefix(" ", node.implementsClause);
5307 _writer.print(";");
5308 return null;
5309 }
5310
5311 @override
5312 Object visitComment(Comment node) => null;
5313
5314 @override
5315 Object visitCommentReference(CommentReference node) => null;
5316
5317 @override
5318 Object visitCompilationUnit(CompilationUnit node) {
5319 ScriptTag scriptTag = node.scriptTag;
5320 NodeList<Directive> directives = node.directives;
5321 _visitNode(scriptTag);
5322 String prefix = scriptTag == null ? "" : " ";
5323 _visitNodeListWithSeparatorAndPrefix(prefix, directives, " ");
5324 prefix = scriptTag == null && directives.isEmpty ? "" : " ";
5325 _visitNodeListWithSeparatorAndPrefix(prefix, node.declarations, " ");
5326 return null;
5327 }
5328
5329 @override
5330 Object visitConditionalExpression(ConditionalExpression node) {
5331 _visitNode(node.condition);
5332 _writer.print(" ? ");
5333 _visitNode(node.thenExpression);
5334 _writer.print(" : ");
5335 _visitNode(node.elseExpression);
5336 return null;
5337 }
5338
5339 @override
5340 Object visitConfiguration(Configuration node) {
5341 _writer.print('if (');
5342 _visitNode(node.name);
5343 _visitNodeWithPrefix(" == ", node.value);
5344 _writer.print(') ');
5345 _visitNode(node.libraryUri);
5346 return null;
5347 }
5348
5349 @override
5350 Object visitConstructorDeclaration(ConstructorDeclaration node) {
5351 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5352 _visitTokenWithSuffix(node.externalKeyword, " ");
5353 _visitTokenWithSuffix(node.constKeyword, " ");
5354 _visitTokenWithSuffix(node.factoryKeyword, " ");
5355 _visitNode(node.returnType);
5356 _visitNodeWithPrefix(".", node.name);
5357 _visitNode(node.parameters);
5358 _visitNodeListWithSeparatorAndPrefix(" : ", node.initializers, ", ");
5359 _visitNodeWithPrefix(" = ", node.redirectedConstructor);
5360 _visitFunctionWithPrefix(" ", node.body);
5361 return null;
5362 }
5363
5364 @override
5365 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
5366 _visitTokenWithSuffix(node.thisKeyword, ".");
5367 _visitNode(node.fieldName);
5368 _writer.print(" = ");
5369 _visitNode(node.expression);
5370 return null;
5371 }
5372
5373 @override
5374 Object visitConstructorName(ConstructorName node) {
5375 _visitNode(node.type);
5376 _visitNodeWithPrefix(".", node.name);
5377 return null;
5378 }
5379
5380 @override
5381 Object visitContinueStatement(ContinueStatement node) {
5382 _writer.print("continue");
5383 _visitNodeWithPrefix(" ", node.label);
5384 _writer.print(";");
5385 return null;
5386 }
5387
5388 @override
5389 Object visitDeclaredIdentifier(DeclaredIdentifier node) {
5390 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5391 _visitTokenWithSuffix(node.keyword, " ");
5392 _visitNodeWithSuffix(node.type, " ");
5393 _visitNode(node.identifier);
5394 return null;
5395 }
5396
5397 @override
5398 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
5399 _visitNode(node.parameter);
5400 if (node.separator != null) {
5401 _writer.print(" ");
5402 _writer.print(node.separator.lexeme);
5403 _visitNodeWithPrefix(" ", node.defaultValue);
5404 }
5405 return null;
5406 }
5407
5408 @override
5409 Object visitDoStatement(DoStatement node) {
5410 _writer.print("do ");
5411 _visitNode(node.body);
5412 _writer.print(" while (");
5413 _visitNode(node.condition);
5414 _writer.print(");");
5415 return null;
5416 }
5417
5418 @override
5419 Object visitDottedName(DottedName node) {
5420 _visitNodeListWithSeparator(node.components, ".");
5421 return null;
5422 }
5423
5424 @override
5425 Object visitDoubleLiteral(DoubleLiteral node) {
5426 _writer.print(node.literal.lexeme);
5427 return null;
5428 }
5429
5430 @override
5431 Object visitEmptyFunctionBody(EmptyFunctionBody node) {
5432 _writer.print(';');
5433 return null;
5434 }
5435
5436 @override
5437 Object visitEmptyStatement(EmptyStatement node) {
5438 _writer.print(';');
5439 return null;
5440 }
5441
5442 @override
5443 Object visitEnumConstantDeclaration(EnumConstantDeclaration node) {
5444 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5445 _visitNode(node.name);
5446 return null;
5447 }
5448
5449 @override
5450 Object visitEnumDeclaration(EnumDeclaration node) {
5451 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5452 _writer.print("enum ");
5453 _visitNode(node.name);
5454 _writer.print(" {");
5455 _visitNodeListWithSeparator(node.constants, ", ");
5456 _writer.print("}");
5457 return null;
5458 }
5459
5460 @override
5461 Object visitExportDirective(ExportDirective node) {
5462 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5463 _writer.print("export ");
5464 _visitNode(node.uri);
5465 _visitNodeListWithSeparatorAndPrefix(" ", node.combinators, " ");
5466 _writer.print(';');
5467 return null;
5468 }
5469
5470 @override
5471 Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
5472 Token keyword = node.keyword;
5473 if (keyword != null) {
5474 _writer.print(keyword.lexeme);
5475 _writer.print(' ');
5476 }
5477 _writer.print("=> ");
5478 _visitNode(node.expression);
5479 if (node.semicolon != null) {
5480 _writer.print(';');
5481 }
5482 return null;
5483 }
5484
5485 @override
5486 Object visitExpressionStatement(ExpressionStatement node) {
5487 _visitNode(node.expression);
5488 _writer.print(';');
5489 return null;
5490 }
5491
5492 @override
5493 Object visitExtendsClause(ExtendsClause node) {
5494 _writer.print("extends ");
5495 _visitNode(node.superclass);
5496 return null;
5497 }
5498
5499 @override
5500 Object visitFieldDeclaration(FieldDeclaration node) {
5501 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5502 _visitTokenWithSuffix(node.staticKeyword, " ");
5503 _visitNode(node.fields);
5504 _writer.print(";");
5505 return null;
5506 }
5507
5508 @override
5509 Object visitFieldFormalParameter(FieldFormalParameter node) {
5510 _visitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
5511 _visitTokenWithSuffix(node.keyword, " ");
5512 _visitNodeWithSuffix(node.type, " ");
5513 _writer.print("this.");
5514 _visitNode(node.identifier);
5515 _visitNode(node.typeParameters);
5516 _visitNode(node.parameters);
5517 return null;
5518 }
5519
5520 @override
5521 Object visitForEachStatement(ForEachStatement node) {
5522 DeclaredIdentifier loopVariable = node.loopVariable;
5523 if (node.awaitKeyword != null) {
5524 _writer.print("await ");
5525 }
5526 _writer.print("for (");
5527 if (loopVariable == null) {
5528 _visitNode(node.identifier);
5529 } else {
5530 _visitNode(loopVariable);
5531 }
5532 _writer.print(" in ");
5533 _visitNode(node.iterable);
5534 _writer.print(") ");
5535 _visitNode(node.body);
5536 return null;
5537 }
5538
5539 @override
5540 Object visitFormalParameterList(FormalParameterList node) {
5541 String groupEnd = null;
5542 _writer.print('(');
5543 NodeList<FormalParameter> parameters = node.parameters;
5544 int size = parameters.length;
5545 for (int i = 0; i < size; i++) {
5546 FormalParameter parameter = parameters[i];
5547 if (i > 0) {
5548 _writer.print(", ");
5549 }
5550 if (groupEnd == null && parameter is DefaultFormalParameter) {
5551 if (parameter.kind == ParameterKind.NAMED) {
5552 groupEnd = "}";
5553 _writer.print('{');
5554 } else {
5555 groupEnd = "]";
5556 _writer.print('[');
5557 }
5558 }
5559 parameter.accept(this);
5560 }
5561 if (groupEnd != null) {
5562 _writer.print(groupEnd);
5563 }
5564 _writer.print(')');
5565 return null;
5566 }
5567
5568 @override
5569 Object visitForStatement(ForStatement node) {
5570 Expression initialization = node.initialization;
5571 _writer.print("for (");
5572 if (initialization != null) {
5573 _visitNode(initialization);
5574 } else {
5575 _visitNode(node.variables);
5576 }
5577 _writer.print(";");
5578 _visitNodeWithPrefix(" ", node.condition);
5579 _writer.print(";");
5580 _visitNodeListWithSeparatorAndPrefix(" ", node.updaters, ", ");
5581 _writer.print(") ");
5582 _visitNode(node.body);
5583 return null;
5584 }
5585
5586 @override
5587 Object visitFunctionDeclaration(FunctionDeclaration node) {
5588 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5589 _visitTokenWithSuffix(node.externalKeyword, " ");
5590 _visitNodeWithSuffix(node.returnType, " ");
5591 _visitTokenWithSuffix(node.propertyKeyword, " ");
5592 _visitNode(node.name);
5593 _visitNode(node.functionExpression);
5594 return null;
5595 }
5596
5597 @override
5598 Object visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
5599 _visitNode(node.functionDeclaration);
5600 return null;
5601 }
5602
5603 @override
5604 Object visitFunctionExpression(FunctionExpression node) {
5605 _visitNode(node.typeParameters);
5606 _visitNode(node.parameters);
5607 if (node.body is! EmptyFunctionBody) {
5608 _writer.print(' ');
5609 }
5610 _visitNode(node.body);
5611 return null;
5612 }
5613
5614 @override
5615 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
5616 _visitNode(node.function);
5617 _visitNode(node.typeArguments);
5618 _visitNode(node.argumentList);
5619 return null;
5620 }
5621
5622 @override
5623 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
5624 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5625 _writer.print("typedef ");
5626 _visitNodeWithSuffix(node.returnType, " ");
5627 _visitNode(node.name);
5628 _visitNode(node.typeParameters);
5629 _visitNode(node.parameters);
5630 _writer.print(";");
5631 return null;
5632 }
5633
5634 @override
5635 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
5636 _visitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
5637 _visitNodeWithSuffix(node.returnType, " ");
5638 _visitNode(node.identifier);
5639 _visitNode(node.typeParameters);
5640 _visitNode(node.parameters);
5641 return null;
5642 }
5643
5644 @override
5645 Object visitHideCombinator(HideCombinator node) {
5646 _writer.print("hide ");
5647 _visitNodeListWithSeparator(node.hiddenNames, ", ");
5648 return null;
5649 }
5650
5651 @override
5652 Object visitIfStatement(IfStatement node) {
5653 _writer.print("if (");
5654 _visitNode(node.condition);
5655 _writer.print(") ");
5656 _visitNode(node.thenStatement);
5657 _visitNodeWithPrefix(" else ", node.elseStatement);
5658 return null;
5659 }
5660
5661 @override
5662 Object visitImplementsClause(ImplementsClause node) {
5663 _writer.print("implements ");
5664 _visitNodeListWithSeparator(node.interfaces, ", ");
5665 return null;
5666 }
5667
5668 @override
5669 Object visitImportDirective(ImportDirective node) {
5670 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5671 _writer.print("import ");
5672 _visitNode(node.uri);
5673 if (node.deferredKeyword != null) {
5674 _writer.print(" deferred");
5675 }
5676 _visitNodeWithPrefix(" as ", node.prefix);
5677 _visitNodeListWithSeparatorAndPrefix(" ", node.combinators, " ");
5678 _writer.print(';');
5679 return null;
5680 }
5681
5682 @override
5683 Object visitIndexExpression(IndexExpression node) {
5684 if (node.isCascaded) {
5685 _writer.print("..");
5686 } else {
5687 _visitNode(node.target);
5688 }
5689 _writer.print('[');
5690 _visitNode(node.index);
5691 _writer.print(']');
5692 return null;
5693 }
5694
5695 @override
5696 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
5697 _visitTokenWithSuffix(node.keyword, " ");
5698 _visitNode(node.constructorName);
5699 _visitNode(node.argumentList);
5700 return null;
5701 }
5702
5703 @override
5704 Object visitIntegerLiteral(IntegerLiteral node) {
5705 _writer.print(node.literal.lexeme);
5706 return null;
5707 }
5708
5709 @override
5710 Object visitInterpolationExpression(InterpolationExpression node) {
5711 if (node.rightBracket != null) {
5712 _writer.print("\${");
5713 _visitNode(node.expression);
5714 _writer.print("}");
5715 } else {
5716 _writer.print("\$");
5717 _visitNode(node.expression);
5718 }
5719 return null;
5720 }
5721
5722 @override
5723 Object visitInterpolationString(InterpolationString node) {
5724 _writer.print(node.contents.lexeme);
5725 return null;
5726 }
5727
5728 @override
5729 Object visitIsExpression(IsExpression node) {
5730 _visitNode(node.expression);
5731 if (node.notOperator == null) {
5732 _writer.print(" is ");
5733 } else {
5734 _writer.print(" is! ");
5735 }
5736 _visitNode(node.type);
5737 return null;
5738 }
5739
5740 @override
5741 Object visitLabel(Label node) {
5742 _visitNode(node.label);
5743 _writer.print(":");
5744 return null;
5745 }
5746
5747 @override
5748 Object visitLabeledStatement(LabeledStatement node) {
5749 _visitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
5750 _visitNode(node.statement);
5751 return null;
5752 }
5753
5754 @override
5755 Object visitLibraryDirective(LibraryDirective node) {
5756 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5757 _writer.print("library ");
5758 _visitNode(node.name);
5759 _writer.print(';');
5760 return null;
5761 }
5762
5763 @override
5764 Object visitLibraryIdentifier(LibraryIdentifier node) {
5765 _writer.print(node.name);
5766 return null;
5767 }
5768
5769 @override
5770 Object visitListLiteral(ListLiteral node) {
5771 if (node.constKeyword != null) {
5772 _writer.print(node.constKeyword.lexeme);
5773 _writer.print(' ');
5774 }
5775 _visitNodeWithSuffix(node.typeArguments, " ");
5776 _writer.print("[");
5777 _visitNodeListWithSeparator(node.elements, ", ");
5778 _writer.print("]");
5779 return null;
5780 }
5781
5782 @override
5783 Object visitMapLiteral(MapLiteral node) {
5784 if (node.constKeyword != null) {
5785 _writer.print(node.constKeyword.lexeme);
5786 _writer.print(' ');
5787 }
5788 _visitNodeWithSuffix(node.typeArguments, " ");
5789 _writer.print("{");
5790 _visitNodeListWithSeparator(node.entries, ", ");
5791 _writer.print("}");
5792 return null;
5793 }
5794
5795 @override
5796 Object visitMapLiteralEntry(MapLiteralEntry node) {
5797 _visitNode(node.key);
5798 _writer.print(" : ");
5799 _visitNode(node.value);
5800 return null;
5801 }
5802
5803 @override
5804 Object visitMethodDeclaration(MethodDeclaration node) {
5805 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5806 _visitTokenWithSuffix(node.externalKeyword, " ");
5807 _visitTokenWithSuffix(node.modifierKeyword, " ");
5808 _visitNodeWithSuffix(node.returnType, " ");
5809 _visitTokenWithSuffix(node.propertyKeyword, " ");
5810 _visitTokenWithSuffix(node.operatorKeyword, " ");
5811 _visitNode(node.name);
5812 if (!node.isGetter) {
5813 _visitNode(node.typeParameters);
5814 _visitNode(node.parameters);
5815 }
5816 _visitFunctionWithPrefix(" ", node.body);
5817 return null;
5818 }
5819
5820 @override
5821 Object visitMethodInvocation(MethodInvocation node) {
5822 if (node.isCascaded) {
5823 _writer.print("..");
5824 } else {
5825 if (node.target != null) {
5826 node.target.accept(this);
5827 _writer.print(node.operator.lexeme);
5828 }
5829 }
5830 _visitNode(node.methodName);
5831 _visitNode(node.typeArguments);
5832 _visitNode(node.argumentList);
5833 return null;
5834 }
5835
5836 @override
5837 Object visitNamedExpression(NamedExpression node) {
5838 _visitNode(node.name);
5839 _visitNodeWithPrefix(" ", node.expression);
5840 return null;
5841 }
5842
5843 @override
5844 Object visitNativeClause(NativeClause node) {
5845 _writer.print("native ");
5846 _visitNode(node.name);
5847 return null;
5848 }
5849
5850 @override
5851 Object visitNativeFunctionBody(NativeFunctionBody node) {
5852 _writer.print("native ");
5853 _visitNode(node.stringLiteral);
5854 _writer.print(';');
5855 return null;
5856 }
5857
5858 @override
5859 Object visitNullLiteral(NullLiteral node) {
5860 _writer.print("null");
5861 return null;
5862 }
5863
5864 @override
5865 Object visitParenthesizedExpression(ParenthesizedExpression node) {
5866 _writer.print('(');
5867 _visitNode(node.expression);
5868 _writer.print(')');
5869 return null;
5870 }
5871
5872 @override
5873 Object visitPartDirective(PartDirective node) {
5874 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5875 _writer.print("part ");
5876 _visitNode(node.uri);
5877 _writer.print(';');
5878 return null;
5879 }
5880
5881 @override
5882 Object visitPartOfDirective(PartOfDirective node) {
5883 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
5884 _writer.print("part of ");
5885 _visitNode(node.libraryName);
5886 _writer.print(';');
5887 return null;
5888 }
5889
5890 @override
5891 Object visitPostfixExpression(PostfixExpression node) {
5892 _visitNode(node.operand);
5893 _writer.print(node.operator.lexeme);
5894 return null;
5895 }
5896
5897 @override
5898 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
5899 _visitNode(node.prefix);
5900 _writer.print('.');
5901 _visitNode(node.identifier);
5902 return null;
5903 }
5904
5905 @override
5906 Object visitPrefixExpression(PrefixExpression node) {
5907 _writer.print(node.operator.lexeme);
5908 _visitNode(node.operand);
5909 return null;
5910 }
5911
5912 @override
5913 Object visitPropertyAccess(PropertyAccess node) {
5914 if (node.isCascaded) {
5915 _writer.print("..");
5916 } else {
5917 _visitNode(node.target);
5918 _writer.print(node.operator.lexeme);
5919 }
5920 _visitNode(node.propertyName);
5921 return null;
5922 }
5923
5924 @override
5925 Object visitRedirectingConstructorInvocation(
5926 RedirectingConstructorInvocation node) {
5927 _writer.print("this");
5928 _visitNodeWithPrefix(".", node.constructorName);
5929 _visitNode(node.argumentList);
5930 return null;
5931 }
5932
5933 @override
5934 Object visitRethrowExpression(RethrowExpression node) {
5935 _writer.print("rethrow");
5936 return null;
5937 }
5938
5939 @override
5940 Object visitReturnStatement(ReturnStatement node) {
5941 Expression expression = node.expression;
5942 if (expression == null) {
5943 _writer.print("return;");
5944 } else {
5945 _writer.print("return ");
5946 expression.accept(this);
5947 _writer.print(";");
5948 }
5949 return null;
5950 }
5951
5952 @override
5953 Object visitScriptTag(ScriptTag node) {
5954 _writer.print(node.scriptTag.lexeme);
5955 return null;
5956 }
5957
5958 @override
5959 Object visitShowCombinator(ShowCombinator node) {
5960 _writer.print("show ");
5961 _visitNodeListWithSeparator(node.shownNames, ", ");
5962 return null;
5963 }
5964
5965 @override
5966 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
5967 _visitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
5968 _visitTokenWithSuffix(node.keyword, " ");
5969 _visitNodeWithSuffix(node.type, " ");
5970 _visitNode(node.identifier);
5971 return null;
5972 }
5973
5974 @override
5975 Object visitSimpleIdentifier(SimpleIdentifier node) {
5976 _writer.print(node.token.lexeme);
5977 return null;
5978 }
5979
5980 @override
5981 Object visitSimpleStringLiteral(SimpleStringLiteral node) {
5982 _writer.print(node.literal.lexeme);
5983 return null;
5984 }
5985
5986 @override
5987 Object visitStringInterpolation(StringInterpolation node) {
5988 _visitNodeList(node.elements);
5989 return null;
5990 }
5991
5992 @override
5993 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
5994 _writer.print("super");
5995 _visitNodeWithPrefix(".", node.constructorName);
5996 _visitNode(node.argumentList);
5997 return null;
5998 }
5999
6000 @override
6001 Object visitSuperExpression(SuperExpression node) {
6002 _writer.print("super");
6003 return null;
6004 }
6005
6006 @override
6007 Object visitSwitchCase(SwitchCase node) {
6008 _visitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
6009 _writer.print("case ");
6010 _visitNode(node.expression);
6011 _writer.print(": ");
6012 _visitNodeListWithSeparator(node.statements, " ");
6013 return null;
6014 }
6015
6016 @override
6017 Object visitSwitchDefault(SwitchDefault node) {
6018 _visitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
6019 _writer.print("default: ");
6020 _visitNodeListWithSeparator(node.statements, " ");
6021 return null;
6022 }
6023
6024 @override
6025 Object visitSwitchStatement(SwitchStatement node) {
6026 _writer.print("switch (");
6027 _visitNode(node.expression);
6028 _writer.print(") {");
6029 _visitNodeListWithSeparator(node.members, " ");
6030 _writer.print("}");
6031 return null;
6032 }
6033
6034 @override
6035 Object visitSymbolLiteral(SymbolLiteral node) {
6036 _writer.print("#");
6037 List<Token> components = node.components;
6038 for (int i = 0; i < components.length; i++) {
6039 if (i > 0) {
6040 _writer.print(".");
6041 }
6042 _writer.print(components[i].lexeme);
6043 }
6044 return null;
6045 }
6046
6047 @override
6048 Object visitThisExpression(ThisExpression node) {
6049 _writer.print("this");
6050 return null;
6051 }
6052
6053 @override
6054 Object visitThrowExpression(ThrowExpression node) {
6055 _writer.print("throw ");
6056 _visitNode(node.expression);
6057 return null;
6058 }
6059
6060 @override
6061 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
6062 _visitNodeWithSuffix(node.variables, ";");
6063 return null;
6064 }
6065
6066 @override
6067 Object visitTryStatement(TryStatement node) {
6068 _writer.print("try ");
6069 _visitNode(node.body);
6070 _visitNodeListWithSeparatorAndPrefix(" ", node.catchClauses, " ");
6071 _visitNodeWithPrefix(" finally ", node.finallyBlock);
6072 return null;
6073 }
6074
6075 @override
6076 Object visitTypeArgumentList(TypeArgumentList node) {
6077 _writer.print('<');
6078 _visitNodeListWithSeparator(node.arguments, ", ");
6079 _writer.print('>');
6080 return null;
6081 }
6082
6083 @override
6084 Object visitTypeName(TypeName node) {
6085 _visitNode(node.name);
6086 _visitNode(node.typeArguments);
6087 return null;
6088 }
6089
6090 @override
6091 Object visitTypeParameter(TypeParameter node) {
6092 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
6093 _visitNode(node.name);
6094 _visitNodeWithPrefix(" extends ", node.bound);
6095 return null;
6096 }
6097
6098 @override
6099 Object visitTypeParameterList(TypeParameterList node) {
6100 _writer.print('<');
6101 _visitNodeListWithSeparator(node.typeParameters, ", ");
6102 _writer.print('>');
6103 return null;
6104 }
6105
6106 @override
6107 Object visitVariableDeclaration(VariableDeclaration node) {
6108 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
6109 _visitNode(node.name);
6110 _visitNodeWithPrefix(" = ", node.initializer);
6111 return null;
6112 }
6113
6114 @override
6115 Object visitVariableDeclarationList(VariableDeclarationList node) {
6116 _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
6117 _visitTokenWithSuffix(node.keyword, " ");
6118 _visitNodeWithSuffix(node.type, " ");
6119 _visitNodeListWithSeparator(node.variables, ", ");
6120 return null;
6121 }
6122
6123 @override
6124 Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
6125 _visitNode(node.variables);
6126 _writer.print(";");
6127 return null;
6128 }
6129
6130 @override
6131 Object visitWhileStatement(WhileStatement node) {
6132 _writer.print("while (");
6133 _visitNode(node.condition);
6134 _writer.print(") ");
6135 _visitNode(node.body);
6136 return null;
6137 }
6138
6139 @override
6140 Object visitWithClause(WithClause node) {
6141 _writer.print("with ");
6142 _visitNodeListWithSeparator(node.mixinTypes, ", ");
6143 return null;
6144 }
6145
6146 @override
6147 Object visitYieldStatement(YieldStatement node) {
6148 if (node.star != null) {
6149 _writer.print("yield* ");
6150 } else {
6151 _writer.print("yield ");
6152 }
6153 _visitNode(node.expression);
6154 _writer.print(";");
6155 return null;
6156 }
6157
6158 /**
6159 * Visit the given function [body], printing the [prefix] before if the body
6160 * is not empty.
6161 */
6162 void _visitFunctionWithPrefix(String prefix, FunctionBody body) {
6163 if (body is! EmptyFunctionBody) {
6164 _writer.print(prefix);
6165 }
6166 _visitNode(body);
6167 }
6168
6169 /**
6170 * Safely visit the given [node].
6171 */
6172 void _visitNode(AstNode node) {
6173 if (node != null) {
6174 node.accept(this);
6175 }
6176 }
6177
6178 /**
6179 * Print a list of [nodes] without any separation.
6180 */
6181 void _visitNodeList(NodeList<AstNode> nodes) {
6182 _visitNodeListWithSeparator(nodes, "");
6183 }
6184
6185 /**
6186 * Print a list of [nodes], separated by the given [separator].
6187 */
6188 void _visitNodeListWithSeparator(NodeList<AstNode> nodes, String separator) {
6189 if (nodes != null) {
6190 int size = nodes.length;
6191 for (int i = 0; i < size; i++) {
6192 if (i > 0) {
6193 _writer.print(separator);
6194 }
6195 nodes[i].accept(this);
6196 }
6197 }
6198 }
6199
6200 /**
6201 * Print a list of [nodes], prefixed by the given [prefix] if the list is not
6202 * empty, and separated by the given [separator].
6203 */
6204 void _visitNodeListWithSeparatorAndPrefix(
6205 String prefix, NodeList<AstNode> nodes, String separator) {
6206 if (nodes != null) {
6207 int size = nodes.length;
6208 if (size > 0) {
6209 _writer.print(prefix);
6210 for (int i = 0; i < size; i++) {
6211 if (i > 0) {
6212 _writer.print(separator);
6213 }
6214 nodes[i].accept(this);
6215 }
6216 }
6217 }
6218 }
6219
6220 /**
6221 * Print a list of [nodes], separated by the given [separator], followed by
6222 * the given [suffix] if the list is not empty.
6223 */
6224 void _visitNodeListWithSeparatorAndSuffix(
6225 NodeList<AstNode> nodes, String separator, String suffix) {
6226 if (nodes != null) {
6227 int size = nodes.length;
6228 if (size > 0) {
6229 for (int i = 0; i < size; i++) {
6230 if (i > 0) {
6231 _writer.print(separator);
6232 }
6233 nodes[i].accept(this);
6234 }
6235 _writer.print(suffix);
6236 }
6237 }
6238 }
6239
6240 /**
6241 * Safely visit the given [node], printing the [prefix] before the node if it
6242 * is non-`null`.
6243 */
6244 void _visitNodeWithPrefix(String prefix, AstNode node) {
6245 if (node != null) {
6246 _writer.print(prefix);
6247 node.accept(this);
6248 }
6249 }
6250
6251 /**
6252 * Safely visit the given [node], printing the [suffix] after the node if it
6253 * is non-`null`.
6254 */
6255 void _visitNodeWithSuffix(AstNode node, String suffix) {
6256 if (node != null) {
6257 node.accept(this);
6258 _writer.print(suffix);
6259 }
6260 }
6261
6262 /**
6263 * Safely visit the given [token], printing the [suffix] after the token if it
6264 * is non-`null`.
6265 */
6266 void _visitTokenWithSuffix(Token token, String suffix) {
6267 if (token != null) {
6268 _writer.print(token.lexeme);
6269 _writer.print(suffix);
6270 }
6271 }
6272 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/dart/ast/visitor.dart ('k') | pkg/analyzer/lib/src/generated/ast.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698