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

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

Issue 1595243003: Move AST implementation out of generated (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: 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
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /**
6 * This library is deprecated. Please convert all references to this library to
7 * reference one of the following public libraries:
8 * * package:analyzer/dart/ast/ast.dart
9 * * package:analyzer/dart/ast/visitor.dart
10 *
11 * If your code is using APIs not available in these public libraries, please
12 * contact the analyzer team to either find an alternate API or have the API you
13 * depend on added to the public API.
14 */
5 library analyzer.src.generated.ast; 15 library analyzer.src.generated.ast;
scheglov 2016/01/18 19:52:31 Maybe @deprecated also? Or this will cause hints a
Brian Wilkerson 2016/01/18 21:00:50 It would cause hints, both in client code and in o
6 16
7 import 'dart:collection';
8
9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/element/element.dart';
11 import 'package:analyzer/dart/element/type.dart';
12 import 'package:analyzer/src/dart/ast/utilities.dart';
13 import 'package:analyzer/src/dart/element/element.dart';
14 import 'package:analyzer/src/dart/element/type.dart';
15 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
16 import 'package:analyzer/src/generated/java_core.dart';
17 import 'package:analyzer/src/generated/java_engine.dart';
18 import 'package:analyzer/src/generated/parser.dart';
19 import 'package:analyzer/src/generated/scanner.dart';
20 import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
21 import 'package:analyzer/src/generated/utilities_dart.dart';
22
23 export 'package:analyzer/dart/ast/ast.dart'; 17 export 'package:analyzer/dart/ast/ast.dart';
24 export 'package:analyzer/dart/ast/visitor.dart'; 18 export 'package:analyzer/dart/ast/visitor.dart';
25 export 'package:analyzer/src/dart/ast/utilities.dart'; 19 export 'package:analyzer/src/dart/ast/utilities.dart';
26
27 /**
28 * Two or more string literals that are implicitly concatenated because of being
29 * adjacent (separated only by whitespace).
30 *
31 * While the grammar only allows adjacent strings when all of the strings are of
32 * the same kind (single line or multi-line), this class doesn't enforce that
33 * restriction.
34 *
35 * > adjacentStrings ::=
36 * > [StringLiteral] [StringLiteral]+
37 */
38 class AdjacentStringsImpl extends StringLiteralImpl implements AdjacentStrings {
39 /**
40 * The strings that are implicitly concatenated.
41 */
42 NodeList<StringLiteral> _strings;
43
44 /**
45 * Initialize a newly created list of adjacent strings. To be syntactically
46 * valid, the list of [strings] must contain at least two elements.
47 */
48 AdjacentStringsImpl(List<StringLiteral> strings) {
49 _strings = new NodeList<StringLiteral>(this, strings);
50 }
51
52 @override
53 Token get beginToken => _strings.beginToken;
54
55 @override
56 Iterable get childEntities => new ChildEntities()..addAll(_strings);
57
58 @override
59 Token get endToken => _strings.endToken;
60
61 @override
62 NodeList<StringLiteral> get strings => _strings;
63
64 @override
65 accept(AstVisitor visitor) => visitor.visitAdjacentStrings(this);
66
67 @override
68 void visitChildren(AstVisitor visitor) {
69 _strings.accept(visitor);
70 }
71
72 @override
73 void _appendStringValue(StringBuffer buffer) {
74 for (StringLiteralImpl stringLiteral in strings) {
75 stringLiteral._appendStringValue(buffer);
76 }
77 }
78 }
79
80 /**
81 * An AST node that can be annotated with both a documentation comment and a
82 * list of annotations.
83 */
84 abstract class AnnotatedNodeImpl extends AstNodeImpl implements AnnotatedNode {
85 /**
86 * The documentation comment associated with this node, or `null` if this node
87 * does not have a documentation comment associated with it.
88 */
89 Comment _comment;
90
91 /**
92 * The annotations associated with this node.
93 */
94 NodeList<Annotation> _metadata;
95
96 /**
97 * Initialize a newly created annotated node. Either or both of the [comment]
98 * and [metadata] can be `null` if the node does not have the corresponding
99 * attribute.
100 */
101 AnnotatedNodeImpl(Comment comment, List<Annotation> metadata) {
102 _comment = _becomeParentOf(comment);
103 _metadata = new NodeList<Annotation>(this, metadata);
104 }
105
106 @override
107 Token get beginToken {
108 if (_comment == null) {
109 if (_metadata.isEmpty) {
110 return firstTokenAfterCommentAndMetadata;
111 }
112 return _metadata.beginToken;
113 } else if (_metadata.isEmpty) {
114 return _comment.beginToken;
115 }
116 Token commentToken = _comment.beginToken;
117 Token metadataToken = _metadata.beginToken;
118 if (commentToken.offset < metadataToken.offset) {
119 return commentToken;
120 }
121 return metadataToken;
122 }
123
124 @override
125 Comment get documentationComment => _comment;
126
127 @override
128 void set documentationComment(Comment comment) {
129 _comment = _becomeParentOf(comment);
130 }
131
132 @override
133 NodeList<Annotation> get metadata => _metadata;
134
135 @override
136 List<AstNode> get sortedCommentAndAnnotations {
137 return <AstNode>[]
138 ..add(_comment)
139 ..addAll(_metadata)
140 ..sort(AstNode.LEXICAL_ORDER);
141 }
142
143 /**
144 * Return a holder of child entities that subclasses can add to.
145 */
146 ChildEntities get _childEntities {
147 ChildEntities result = new ChildEntities();
148 if (_commentIsBeforeAnnotations()) {
149 result
150 ..add(_comment)
151 ..addAll(_metadata);
152 } else {
153 result.addAll(sortedCommentAndAnnotations);
154 }
155 return result;
156 }
157
158 @override
159 void visitChildren(AstVisitor visitor) {
160 if (_commentIsBeforeAnnotations()) {
161 _safelyVisitChild(_comment, visitor);
162 _metadata.accept(visitor);
163 } else {
164 for (AstNode child in sortedCommentAndAnnotations) {
165 child.accept(visitor);
166 }
167 }
168 }
169
170 /**
171 * Return `true` if there are no annotations before the comment. Note that a
172 * result of `true` does not imply that there is a comment, nor that there are
173 * annotations associated with this node.
174 */
175 bool _commentIsBeforeAnnotations() {
176 if (_comment == null || _metadata.isEmpty) {
177 return true;
178 }
179 Annotation firstAnnotation = _metadata[0];
180 return _comment.offset < firstAnnotation.offset;
181 }
182 }
183
184 /**
185 * An annotation that can be associated with an AST node.
186 *
187 * > metadata ::=
188 * > annotation*
189 * >
190 * > annotation ::=
191 * > '@' [Identifier] ('.' [SimpleIdentifier])? [ArgumentList]?
192 */
193 class AnnotationImpl extends AstNodeImpl implements Annotation {
194 /**
195 * The at sign that introduced the annotation.
196 */
197 Token atSign;
198
199 /**
200 * The name of the class defining the constructor that is being invoked or the
201 * name of the field that is being referenced.
202 */
203 Identifier _name;
204
205 /**
206 * The period before the constructor name, or `null` if this annotation is not
207 * the invocation of a named constructor.
208 */
209 Token period;
210
211 /**
212 * The name of the constructor being invoked, or `null` if this annotation is
213 * not the invocation of a named constructor.
214 */
215 SimpleIdentifier _constructorName;
216
217 /**
218 * The arguments to the constructor being invoked, or `null` if this
219 * annotation is not the invocation of a constructor.
220 */
221 ArgumentList _arguments;
222
223 /**
224 * The element associated with this annotation, or `null` if the AST structure
225 * has not been resolved or if this annotation could not be resolved.
226 */
227 Element _element;
228
229 /**
230 * The element annotation representing this annotation in the element model.
231 */
232 ElementAnnotation elementAnnotation;
233
234 /**
235 * Initialize a newly created annotation. Both the [period] and the
236 * [constructorName] can be `null` if the annotation is not referencing a
237 * named constructor. The [arguments] can be `null` if the annotation is not
238 * referencing a constructor.
239 */
240 AnnotationImpl(this.atSign, Identifier name, this.period,
241 SimpleIdentifier constructorName, ArgumentList arguments) {
242 _name = _becomeParentOf(name);
243 _constructorName = _becomeParentOf(constructorName);
244 _arguments = _becomeParentOf(arguments);
245 }
246
247 @override
248 ArgumentList get arguments => _arguments;
249
250 @override
251 void set arguments(ArgumentList arguments) {
252 _arguments = _becomeParentOf(arguments);
253 }
254
255 @override
256 Token get beginToken => atSign;
257
258 @override
259 Iterable get childEntities => new ChildEntities()
260 ..add(atSign)
261 ..add(_name)
262 ..add(period)
263 ..add(_constructorName)
264 ..add(_arguments);
265
266 @override
267 SimpleIdentifier get constructorName => _constructorName;
268
269 @override
270 void set constructorName(SimpleIdentifier name) {
271 _constructorName = _becomeParentOf(name);
272 }
273
274 @override
275 Element get element {
276 if (_element != null) {
277 return _element;
278 } else if (_name != null) {
279 return _name.staticElement;
280 }
281 return null;
282 }
283
284 @override
285 void set element(Element element) {
286 _element = element;
287 }
288
289 @override
290 Token get endToken {
291 if (_arguments != null) {
292 return _arguments.endToken;
293 } else if (_constructorName != null) {
294 return _constructorName.endToken;
295 }
296 return _name.endToken;
297 }
298
299 @override
300 Identifier get name => _name;
301
302 @override
303 void set name(Identifier name) {
304 _name = _becomeParentOf(name);
305 }
306
307 @override
308 accept(AstVisitor visitor) => visitor.visitAnnotation(this);
309
310 @override
311 void visitChildren(AstVisitor visitor) {
312 _safelyVisitChild(_name, visitor);
313 _safelyVisitChild(_constructorName, visitor);
314 _safelyVisitChild(_arguments, visitor);
315 }
316 }
317
318 /**
319 * A list of arguments in the invocation of an executable element (that is, a
320 * function, method, or constructor).
321 *
322 * > argumentList ::=
323 * > '(' arguments? ')'
324 * >
325 * > arguments ::=
326 * > [NamedExpression] (',' [NamedExpression])*
327 * > | [Expression] (',' [Expression])* (',' [NamedExpression])*
328 */
329 class ArgumentListImpl extends AstNodeImpl implements ArgumentList {
330 /**
331 * The left parenthesis.
332 */
333 Token leftParenthesis;
334
335 /**
336 * The expressions producing the values of the arguments.
337 */
338 NodeList<Expression> _arguments;
339
340 /**
341 * The right parenthesis.
342 */
343 Token rightParenthesis;
344
345 /**
346 * A list containing the elements representing the parameters corresponding to
347 * each of the arguments in this list, or `null` if the AST has not been
348 * resolved or if the function or method being invoked could not be determined
349 * based on static type information. The list must be the same length as the
350 * number of arguments, but can contain `null` entries if a given argument
351 * does not correspond to a formal parameter.
352 */
353 List<ParameterElement> _correspondingStaticParameters;
354
355 /**
356 * A list containing the elements representing the parameters corresponding to
357 * each of the arguments in this list, or `null` if the AST has not been
358 * resolved or if the function or method being invoked could not be determined
359 * based on propagated type information. The list must be the same length as
360 * the number of arguments, but can contain `null` entries if a given argument
361 * does not correspond to a formal parameter.
362 */
363 List<ParameterElement> _correspondingPropagatedParameters;
364
365 /**
366 * Initialize a newly created list of arguments. The list of [arguments] can
367 * be `null` if there are no arguments.
368 */
369 ArgumentListImpl(
370 this.leftParenthesis, List<Expression> arguments, this.rightParenthesis) {
371 _arguments = new NodeList<Expression>(this, arguments);
372 }
373
374 @override
375 NodeList<Expression> get arguments => _arguments;
376
377 @override
378 Token get beginToken => leftParenthesis;
379
380 @override
381 // TODO(paulberry): Add commas.
382 Iterable get childEntities => new ChildEntities()
383 ..add(leftParenthesis)
384 ..addAll(_arguments)
385 ..add(rightParenthesis);
386
387 @override
388 void set correspondingPropagatedParameters(
389 List<ParameterElement> parameters) {
390 if (parameters.length != _arguments.length) {
391 throw new IllegalArgumentException(
392 "Expected ${_arguments.length} parameters, not ${parameters.length}");
393 }
394 _correspondingPropagatedParameters = parameters;
395 }
396
397 @override
398 void set correspondingStaticParameters(List<ParameterElement> parameters) {
399 if (parameters.length != _arguments.length) {
400 throw new IllegalArgumentException(
401 "Expected ${_arguments.length} parameters, not ${parameters.length}");
402 }
403 _correspondingStaticParameters = parameters;
404 }
405
406 @override
407 Token get endToken => rightParenthesis;
408
409 @override
410 accept(AstVisitor visitor) => visitor.visitArgumentList(this);
411
412 @override
413 void visitChildren(AstVisitor visitor) {
414 _arguments.accept(visitor);
415 }
416
417 /**
418 * If
419 * * the given [expression] is a child of this list,
420 * * the AST structure has been resolved,
421 * * the function being invoked is known based on propagated type information,
422 * and
423 * * the expression corresponds to one of the parameters of the function being
424 * invoked,
425 * then return the parameter element representing the parameter to which the
426 * value of the given expression will be bound. Otherwise, return `null`.
427 */
428 ParameterElement _getPropagatedParameterElementFor(Expression expression) {
429 if (_correspondingPropagatedParameters == null ||
430 _correspondingPropagatedParameters.length != _arguments.length) {
431 // Either the AST structure has not been resolved, the invocation of which
432 // this list is a part could not be resolved, or the argument list was
433 // modified after the parameters were set.
434 return null;
435 }
436 int index = _arguments.indexOf(expression);
437 if (index < 0) {
438 // The expression isn't a child of this node.
439 return null;
440 }
441 return _correspondingPropagatedParameters[index];
442 }
443
444 /**
445 * If
446 * * the given [expression] is a child of this list,
447 * * the AST structure has been resolved,
448 * * the function being invoked is known based on static type information, and
449 * * the expression corresponds to one of the parameters of the function being
450 * invoked,
451 * then return the parameter element representing the parameter to which the
452 * value of the given expression will be bound. Otherwise, return `null`.
453 */
454 ParameterElement _getStaticParameterElementFor(Expression expression) {
455 if (_correspondingStaticParameters == null ||
456 _correspondingStaticParameters.length != _arguments.length) {
457 // Either the AST structure has not been resolved, the invocation of which
458 // this list is a part could not be resolved, or the argument list was
459 // modified after the parameters were set.
460 return null;
461 }
462 int index = _arguments.indexOf(expression);
463 if (index < 0) {
464 // The expression isn't a child of this node.
465 return null;
466 }
467 return _correspondingStaticParameters[index];
468 }
469 }
470
471 /**
472 * An as expression.
473 *
474 * > asExpression ::=
475 * > [Expression] 'as' [TypeName]
476 */
477 class AsExpressionImpl extends ExpressionImpl implements AsExpression {
478 /**
479 * The expression used to compute the value being cast.
480 */
481 Expression _expression;
482
483 /**
484 * The 'as' operator.
485 */
486 Token asOperator;
487
488 /**
489 * The name of the type being cast to.
490 */
491 TypeName _type;
492
493 /**
494 * Initialize a newly created as expression.
495 */
496 AsExpressionImpl(Expression expression, this.asOperator, TypeName type) {
497 _expression = _becomeParentOf(expression);
498 _type = _becomeParentOf(type);
499 }
500
501 @override
502 Token get beginToken => _expression.beginToken;
503
504 @override
505 Iterable get childEntities =>
506 new ChildEntities()..add(_expression)..add(asOperator)..add(_type);
507
508 @override
509 Token get endToken => _type.endToken;
510
511 @override
512 Expression get expression => _expression;
513
514 @override
515 void set expression(Expression expression) {
516 _expression = _becomeParentOf(expression);
517 }
518
519 @override
520 int get precedence => 7;
521
522 @override
523 TypeName get type => _type;
524
525 @override
526 void set type(TypeName name) {
527 _type = _becomeParentOf(name);
528 }
529
530 @override
531 accept(AstVisitor visitor) => visitor.visitAsExpression(this);
532
533 @override
534 void visitChildren(AstVisitor visitor) {
535 _safelyVisitChild(_expression, visitor);
536 _safelyVisitChild(_type, visitor);
537 }
538 }
539
540 /**
541 * An assert statement.
542 *
543 * > assertStatement ::=
544 * > 'assert' '(' [Expression] ')' ';'
545 */
546 class AssertStatementImpl extends StatementImpl implements AssertStatement {
547 /**
548 * The token representing the 'assert' keyword.
549 */
550 Token assertKeyword;
551
552 /**
553 * The left parenthesis.
554 */
555 Token leftParenthesis;
556
557 /**
558 * The condition that is being asserted to be `true`.
559 */
560 Expression _condition;
561
562 /**
563 * The comma, if a message expression was supplied. Otherwise `null`.
564 */
565 Token comma;
566
567 /**
568 * The message to report if the assertion fails. `null` if no message was
569 * supplied.
570 */
571 Expression _message;
572
573 /**
574 * The right parenthesis.
575 */
576 Token rightParenthesis;
577
578 /**
579 * The semicolon terminating the statement.
580 */
581 Token semicolon;
582
583 /**
584 * Initialize a newly created assert statement.
585 */
586 AssertStatementImpl(
587 this.assertKeyword,
588 this.leftParenthesis,
589 Expression condition,
590 this.comma,
591 Expression message,
592 this.rightParenthesis,
593 this.semicolon) {
594 _condition = _becomeParentOf(condition);
595 _message = _becomeParentOf(message);
596 }
597
598 @override
599 Token get beginToken => assertKeyword;
600
601 @override
602 Iterable get childEntities => new ChildEntities()
603 ..add(assertKeyword)
604 ..add(leftParenthesis)
605 ..add(_condition)
606 ..add(comma)
607 ..add(_message)
608 ..add(rightParenthesis)
609 ..add(semicolon);
610
611 @override
612 Expression get condition => _condition;
613
614 @override
615 void set condition(Expression condition) {
616 _condition = _becomeParentOf(condition);
617 }
618
619 @override
620 Token get endToken => semicolon;
621
622 @override
623 Expression get message => _message;
624
625 @override
626 void set message(Expression expression) {
627 _message = _becomeParentOf(expression);
628 }
629
630 @override
631 accept(AstVisitor visitor) => visitor.visitAssertStatement(this);
632
633 @override
634 void visitChildren(AstVisitor visitor) {
635 _safelyVisitChild(_condition, visitor);
636 _safelyVisitChild(message, visitor);
637 }
638 }
639
640 /**
641 * An assignment expression.
642 *
643 * > assignmentExpression ::=
644 * > [Expression] operator [Expression]
645 */
646 class AssignmentExpressionImpl extends ExpressionImpl
647 implements AssignmentExpression {
648 /**
649 * The expression used to compute the left hand side.
650 */
651 Expression _leftHandSide;
652
653 /**
654 * The assignment operator being applied.
655 */
656 Token operator;
657
658 /**
659 * The expression used to compute the right hand side.
660 */
661 Expression _rightHandSide;
662
663 /**
664 * The element associated with the operator based on the static type of the
665 * left-hand-side, or `null` if the AST structure has not been resolved, if
666 * the operator is not a compound operator, or if the operator could not be
667 * resolved.
668 */
669 MethodElement staticElement;
670
671 /**
672 * The element associated with the operator based on the propagated type of
673 * the left-hand-side, or `null` if the AST structure has not been resolved,
674 * if the operator is not a compound operator, or if the operator could not be
675 * resolved.
676 */
677 MethodElement propagatedElement;
678
679 /**
680 * Initialize a newly created assignment expression.
681 */
682 AssignmentExpressionImpl(
683 Expression leftHandSide, this.operator, Expression rightHandSide) {
684 if (leftHandSide == null || rightHandSide == null) {
685 String message;
686 if (leftHandSide == null) {
687 if (rightHandSide == null) {
688 message = "Both the left-hand and right-hand sides are null";
689 } else {
690 message = "The left-hand size is null";
691 }
692 } else {
693 message = "The right-hand size is null";
694 }
695 AnalysisEngine.instance.logger.logError(
696 message, new CaughtException(new AnalysisException(message), null));
697 }
698 _leftHandSide = _becomeParentOf(leftHandSide);
699 _rightHandSide = _becomeParentOf(rightHandSide);
700 }
701
702 @override
703 Token get beginToken => _leftHandSide.beginToken;
704
705 @override
706 MethodElement get bestElement {
707 MethodElement element = propagatedElement;
708 if (element == null) {
709 element = staticElement;
710 }
711 return element;
712 }
713
714 @override
715 Iterable get childEntities => new ChildEntities()
716 ..add(_leftHandSide)
717 ..add(operator)
718 ..add(_rightHandSide);
719
720 @override
721 Token get endToken => _rightHandSide.endToken;
722
723 @override
724 Expression get leftHandSide => _leftHandSide;
725
726 @override
727 void set leftHandSide(Expression expression) {
728 _leftHandSide = _becomeParentOf(expression);
729 }
730
731 @override
732 int get precedence => 1;
733
734 @override
735 Expression get rightHandSide => _rightHandSide;
736
737 @override
738 void set rightHandSide(Expression expression) {
739 _rightHandSide = _becomeParentOf(expression);
740 }
741
742 /**
743 * If the AST structure has been resolved, and the function being invoked is
744 * known based on propagated type information, then return the parameter
745 * element representing the parameter to which the value of the right operand
746 * will be bound. Otherwise, return `null`.
747 */
748 ParameterElement get _propagatedParameterElementForRightHandSide {
749 ExecutableElement executableElement = null;
750 if (propagatedElement != null) {
751 executableElement = propagatedElement;
752 } else {
753 if (_leftHandSide is Identifier) {
754 Identifier identifier = _leftHandSide as Identifier;
755 Element leftElement = identifier.propagatedElement;
756 if (leftElement is ExecutableElement) {
757 executableElement = leftElement;
758 }
759 }
760 if (_leftHandSide is PropertyAccess) {
761 SimpleIdentifier identifier =
762 (_leftHandSide as PropertyAccess).propertyName;
763 Element leftElement = identifier.propagatedElement;
764 if (leftElement is ExecutableElement) {
765 executableElement = leftElement;
766 }
767 }
768 }
769 if (executableElement == null) {
770 return null;
771 }
772 List<ParameterElement> parameters = executableElement.parameters;
773 if (parameters.length < 1) {
774 return null;
775 }
776 return parameters[0];
777 }
778
779 /**
780 * If the AST structure has been resolved, and the function being invoked is
781 * known based on static type information, then return the parameter element
782 * representing the parameter to which the value of the right operand will be
783 * bound. Otherwise, return `null`.
784 */
785 ParameterElement get _staticParameterElementForRightHandSide {
786 ExecutableElement executableElement = null;
787 if (staticElement != null) {
788 executableElement = staticElement;
789 } else {
790 if (_leftHandSide is Identifier) {
791 Element leftElement = (_leftHandSide as Identifier).staticElement;
792 if (leftElement is ExecutableElement) {
793 executableElement = leftElement;
794 }
795 }
796 if (_leftHandSide is PropertyAccess) {
797 Element leftElement =
798 (_leftHandSide as PropertyAccess).propertyName.staticElement;
799 if (leftElement is ExecutableElement) {
800 executableElement = leftElement;
801 }
802 }
803 }
804 if (executableElement == null) {
805 return null;
806 }
807 List<ParameterElement> parameters = executableElement.parameters;
808 if (parameters.length < 1) {
809 return null;
810 }
811 return parameters[0];
812 }
813
814 @override
815 accept(AstVisitor visitor) => visitor.visitAssignmentExpression(this);
816
817 @override
818 void visitChildren(AstVisitor visitor) {
819 _safelyVisitChild(_leftHandSide, visitor);
820 _safelyVisitChild(_rightHandSide, visitor);
821 }
822 }
823
824 /**
825 * A node in the AST structure for a Dart program.
826 */
827 abstract class AstNodeImpl implements AstNode {
828 /**
829 * The parent of the node, or `null` if the node is the root of an AST
830 * structure.
831 */
832 AstNode _parent;
833
834 /**
835 * A table mapping the names of properties to their values, or `null` if this
836 * node does not have any properties associated with it.
837 */
838 Map<String, Object> _propertyMap;
839
840 @override
841 int get end => offset + length;
842
843 @override
844 bool get isSynthetic => false;
845
846 @override
847 int get length {
848 Token beginToken = this.beginToken;
849 Token endToken = this.endToken;
850 if (beginToken == null || endToken == null) {
851 return -1;
852 }
853 return endToken.offset + endToken.length - beginToken.offset;
854 }
855
856 @override
857 int get offset {
858 Token beginToken = this.beginToken;
859 if (beginToken == null) {
860 return -1;
861 }
862 return beginToken.offset;
863 }
864
865 @override
866 AstNode get parent => _parent;
867
868 @override
869 AstNode get root {
870 AstNode root = this;
871 AstNode parent = this.parent;
872 while (parent != null) {
873 root = parent;
874 parent = root.parent;
875 }
876 return root;
877 }
878
879 @override
880 AstNode getAncestor(Predicate<AstNode> predicate) {
881 // TODO(brianwilkerson) It is a bug that this method can return `this`.
882 AstNode node = this;
883 while (node != null && !predicate(node)) {
884 node = node.parent;
885 }
886 return node;
887 }
888
889 @override
890 Object getProperty(String name) {
891 if (_propertyMap == null) {
892 return null;
893 }
894 return _propertyMap[name];
895 }
896
897 @override
898 void setProperty(String name, Object value) {
899 if (value == null) {
900 if (_propertyMap != null) {
901 _propertyMap.remove(name);
902 if (_propertyMap.isEmpty) {
903 _propertyMap = null;
904 }
905 }
906 } else {
907 if (_propertyMap == null) {
908 _propertyMap = new HashMap<String, Object>();
909 }
910 _propertyMap[name] = value;
911 }
912 }
913
914 @override
915 String toSource() {
916 PrintStringWriter writer = new PrintStringWriter();
917 accept(new ToSourceVisitor(writer));
918 return writer.toString();
919 }
920
921 @override
922 String toString() => toSource();
923
924 /**
925 * Make this node the parent of the given [child] node. Return the child node.
926 */
927 AstNode _becomeParentOf(AstNode child) {
928 if (child != null) {
929 (child as AstNodeImpl)._parent = this;
930 }
931 return child;
932 }
933
934 /**
935 * If the given [child] is not `null`, use the given [visitor] to visit it.
936 */
937 void _safelyVisitChild(AstNode child, AstVisitor visitor) {
938 if (child != null) {
939 child.accept(visitor);
940 }
941 }
942 }
943
944 /**
945 * An await expression.
946 *
947 * > awaitExpression ::=
948 * > 'await' [Expression]
949 */
950 class AwaitExpressionImpl extends ExpressionImpl implements AwaitExpression {
951 /**
952 * The 'await' keyword.
953 */
954 Token awaitKeyword;
955
956 /**
957 * The expression whose value is being waited on.
958 */
959 Expression _expression;
960
961 /**
962 * Initialize a newly created await expression.
963 */
964 AwaitExpressionImpl(this.awaitKeyword, Expression expression) {
965 _expression = _becomeParentOf(expression);
966 }
967
968 @override
969 Token get beginToken {
970 if (awaitKeyword != null) {
971 return awaitKeyword;
972 }
973 return _expression.beginToken;
974 }
975
976 @override
977 Iterable get childEntities =>
978 new ChildEntities()..add(awaitKeyword)..add(_expression);
979
980 @override
981 Token get endToken => _expression.endToken;
982
983 @override
984 Expression get expression => _expression;
985
986 @override
987 void set expression(Expression expression) {
988 _expression = _becomeParentOf(expression);
989 }
990
991 @override
992 int get precedence => 0;
993
994 @override
995 accept(AstVisitor visitor) => visitor.visitAwaitExpression(this);
996
997 @override
998 void visitChildren(AstVisitor visitor) {
999 _safelyVisitChild(_expression, visitor);
1000 }
1001 }
1002
1003 /**
1004 * A binary (infix) expression.
1005 *
1006 * > binaryExpression ::=
1007 * > [Expression] [Token] [Expression]
1008 */
1009 class BinaryExpressionImpl extends ExpressionImpl implements BinaryExpression {
1010 /**
1011 * The expression used to compute the left operand.
1012 */
1013 Expression _leftOperand;
1014
1015 /**
1016 * The binary operator being applied.
1017 */
1018 Token operator;
1019
1020 /**
1021 * The expression used to compute the right operand.
1022 */
1023 Expression _rightOperand;
1024
1025 /**
1026 * The element associated with the operator based on the static type of the
1027 * left operand, or `null` if the AST structure has not been resolved, if the
1028 * operator is not user definable, or if the operator could not be resolved.
1029 */
1030 MethodElement staticElement;
1031
1032 /**
1033 * The element associated with the operator based on the propagated type of
1034 * the left operand, or `null` if the AST structure has not been resolved, if
1035 * the operator is not user definable, or if the operator could not be
1036 * resolved.
1037 */
1038 MethodElement propagatedElement;
1039
1040 /**
1041 * Initialize a newly created binary expression.
1042 */
1043 BinaryExpressionImpl(
1044 Expression leftOperand, this.operator, Expression rightOperand) {
1045 _leftOperand = _becomeParentOf(leftOperand);
1046 _rightOperand = _becomeParentOf(rightOperand);
1047 }
1048
1049 @override
1050 Token get beginToken => _leftOperand.beginToken;
1051
1052 @override
1053 MethodElement get bestElement {
1054 MethodElement element = propagatedElement;
1055 if (element == null) {
1056 element = staticElement;
1057 }
1058 return element;
1059 }
1060
1061 @override
1062 Iterable get childEntities =>
1063 new ChildEntities()..add(_leftOperand)..add(operator)..add(_rightOperand);
1064
1065 @override
1066 Token get endToken => _rightOperand.endToken;
1067
1068 @override
1069 Expression get leftOperand => _leftOperand;
1070
1071 @override
1072 void set leftOperand(Expression expression) {
1073 _leftOperand = _becomeParentOf(expression);
1074 }
1075
1076 @override
1077 int get precedence => operator.type.precedence;
1078
1079 @override
1080 Expression get rightOperand => _rightOperand;
1081
1082 @override
1083 void set rightOperand(Expression expression) {
1084 _rightOperand = _becomeParentOf(expression);
1085 }
1086
1087 /**
1088 * If the AST structure has been resolved, and the function being invoked is
1089 * known based on propagated type information, then return the parameter
1090 * element representing the parameter to which the value of the right operand
1091 * will be bound. Otherwise, return `null`.
1092 */
1093 ParameterElement get _propagatedParameterElementForRightOperand {
1094 if (propagatedElement == null) {
1095 return null;
1096 }
1097 List<ParameterElement> parameters = propagatedElement.parameters;
1098 if (parameters.length < 1) {
1099 return null;
1100 }
1101 return parameters[0];
1102 }
1103
1104 /**
1105 * If the AST structure has been resolved, and the function being invoked is
1106 * known based on static type information, then return the parameter element
1107 * representing the parameter to which the value of the right operand will be
1108 * bound. Otherwise, return `null`.
1109 */
1110 ParameterElement get _staticParameterElementForRightOperand {
1111 if (staticElement == null) {
1112 return null;
1113 }
1114 List<ParameterElement> parameters = staticElement.parameters;
1115 if (parameters.length < 1) {
1116 return null;
1117 }
1118 return parameters[0];
1119 }
1120
1121 @override
1122 accept(AstVisitor visitor) => visitor.visitBinaryExpression(this);
1123
1124 @override
1125 void visitChildren(AstVisitor visitor) {
1126 _safelyVisitChild(_leftOperand, visitor);
1127 _safelyVisitChild(_rightOperand, visitor);
1128 }
1129 }
1130
1131 /**
1132 * A function body that consists of a block of statements.
1133 *
1134 * > blockFunctionBody ::=
1135 * > ('async' | 'async' '*' | 'sync' '*')? [Block]
1136 */
1137 class BlockFunctionBodyImpl extends FunctionBodyImpl
1138 implements BlockFunctionBody {
1139 /**
1140 * The token representing the 'async' or 'sync' keyword, or `null` if there is
1141 * no such keyword.
1142 */
1143 Token keyword;
1144
1145 /**
1146 * The star optionally following the 'async' or 'sync' keyword, or `null` if
1147 * there is wither no such keyword or no star.
1148 */
1149 Token star;
1150
1151 /**
1152 * The block representing the body of the function.
1153 */
1154 Block _block;
1155
1156 /**
1157 * Initialize a newly created function body consisting of a block of
1158 * statements. The [keyword] can be `null` if there is no keyword specified
1159 * for the block. The [star] can be `null` if there is no star following the
1160 * keyword (and must be `null` if there is no keyword).
1161 */
1162 BlockFunctionBodyImpl(this.keyword, this.star, Block block) {
1163 _block = _becomeParentOf(block);
1164 }
1165
1166 @override
1167 Token get beginToken {
1168 if (keyword != null) {
1169 return keyword;
1170 }
1171 return _block.beginToken;
1172 }
1173
1174 @override
1175 Block get block => _block;
1176
1177 @override
1178 void set block(Block block) {
1179 _block = _becomeParentOf(block);
1180 }
1181
1182 @override
1183 Iterable get childEntities =>
1184 new ChildEntities()..add(keyword)..add(star)..add(_block);
1185
1186 @override
1187 Token get endToken => _block.endToken;
1188
1189 @override
1190 bool get isAsynchronous => keyword != null && keyword.lexeme == Parser.ASYNC;
1191
1192 @override
1193 bool get isGenerator => star != null;
1194
1195 @override
1196 bool get isSynchronous => keyword == null || keyword.lexeme != Parser.ASYNC;
1197
1198 @override
1199 accept(AstVisitor visitor) => visitor.visitBlockFunctionBody(this);
1200
1201 @override
1202 void visitChildren(AstVisitor visitor) {
1203 _safelyVisitChild(_block, visitor);
1204 }
1205 }
1206
1207 /**
1208 * A sequence of statements.
1209 *
1210 * > block ::=
1211 * > '{' statement* '}'
1212 */
1213 class BlockImpl extends StatementImpl implements Block {
1214 /**
1215 * The left curly bracket.
1216 */
1217 Token leftBracket;
1218
1219 /**
1220 * The statements contained in the block.
1221 */
1222 NodeList<Statement> _statements;
1223
1224 /**
1225 * The right curly bracket.
1226 */
1227 Token rightBracket;
1228
1229 /**
1230 * Initialize a newly created block of code.
1231 */
1232 BlockImpl(this.leftBracket, List<Statement> statements, this.rightBracket) {
1233 _statements = new NodeList<Statement>(this, statements);
1234 }
1235
1236 @override
1237 Token get beginToken => leftBracket;
1238
1239 @override
1240 Iterable get childEntities => new ChildEntities()
1241 ..add(leftBracket)
1242 ..addAll(_statements)
1243 ..add(rightBracket);
1244
1245 @override
1246 Token get endToken => rightBracket;
1247
1248 @override
1249 NodeList<Statement> get statements => _statements;
1250
1251 @override
1252 accept(AstVisitor visitor) => visitor.visitBlock(this);
1253
1254 @override
1255 void visitChildren(AstVisitor visitor) {
1256 _statements.accept(visitor);
1257 }
1258 }
1259
1260 /**
1261 * A boolean literal expression.
1262 *
1263 * > booleanLiteral ::=
1264 * > 'false' | 'true'
1265 */
1266 class BooleanLiteralImpl extends LiteralImpl implements BooleanLiteral {
1267 /**
1268 * The token representing the literal.
1269 */
1270 Token literal;
1271
1272 /**
1273 * The value of the literal.
1274 */
1275 bool value = false;
1276
1277 /**
1278 * Initialize a newly created boolean literal.
1279 */
1280 BooleanLiteralImpl(this.literal, this.value);
1281
1282 @override
1283 Token get beginToken => literal;
1284
1285 @override
1286 Iterable get childEntities => new ChildEntities()..add(literal);
1287
1288 @override
1289 Token get endToken => literal;
1290
1291 @override
1292 bool get isSynthetic => literal.isSynthetic;
1293
1294 @override
1295 accept(AstVisitor visitor) => visitor.visitBooleanLiteral(this);
1296
1297 @override
1298 void visitChildren(AstVisitor visitor) {
1299 // There are no children to visit.
1300 }
1301 }
1302
1303 /**
1304 * A break statement.
1305 *
1306 * > breakStatement ::=
1307 * > 'break' [SimpleIdentifier]? ';'
1308 */
1309 class BreakStatementImpl extends StatementImpl implements BreakStatement {
1310 /**
1311 * The token representing the 'break' keyword.
1312 */
1313 Token breakKeyword;
1314
1315 /**
1316 * The label associated with the statement, or `null` if there is no label.
1317 */
1318 SimpleIdentifier _label;
1319
1320 /**
1321 * The semicolon terminating the statement.
1322 */
1323 Token semicolon;
1324
1325 /**
1326 * The AstNode which this break statement is breaking from. This will be
1327 * either a [Statement] (in the case of breaking out of a loop), a
1328 * [SwitchMember] (in the case of a labeled break statement whose label
1329 * matches a label on a switch case in an enclosing switch statement), or
1330 * `null` if the AST has not yet been resolved or if the target could not be
1331 * resolved. Note that if the source code has errors, the target might be
1332 * invalid (e.g. trying to break to a switch case).
1333 */
1334 AstNode target;
1335
1336 /**
1337 * Initialize a newly created break statement. The [label] can be `null` if
1338 * there is no label associated with the statement.
1339 */
1340 BreakStatementImpl(
1341 this.breakKeyword, SimpleIdentifier label, this.semicolon) {
1342 _label = _becomeParentOf(label);
1343 }
1344
1345 @override
1346 Token get beginToken => breakKeyword;
1347
1348 @override
1349 Iterable get childEntities =>
1350 new ChildEntities()..add(breakKeyword)..add(_label)..add(semicolon);
1351
1352 @override
1353 Token get endToken => semicolon;
1354
1355 @override
1356 SimpleIdentifier get label => _label;
1357
1358 @override
1359 void set label(SimpleIdentifier identifier) {
1360 _label = _becomeParentOf(identifier);
1361 }
1362
1363 @override
1364 accept(AstVisitor visitor) => visitor.visitBreakStatement(this);
1365
1366 @override
1367 void visitChildren(AstVisitor visitor) {
1368 _safelyVisitChild(_label, visitor);
1369 }
1370 }
1371
1372 /**
1373 * A sequence of cascaded expressions: expressions that share a common target.
1374 * There are three kinds of expressions that can be used in a cascade
1375 * expression: [IndexExpression], [MethodInvocation] and [PropertyAccess].
1376 *
1377 * > cascadeExpression ::=
1378 * > [Expression] cascadeSection*
1379 * >
1380 * > cascadeSection ::=
1381 * > '..' (cascadeSelector arguments*) (assignableSelector arguments*)*
1382 * > (assignmentOperator expressionWithoutCascade)?
1383 * >
1384 * > cascadeSelector ::=
1385 * > '[ ' expression '] '
1386 * > | identifier
1387 */
1388 class CascadeExpressionImpl extends ExpressionImpl
1389 implements CascadeExpression {
1390 /**
1391 * The target of the cascade sections.
1392 */
1393 Expression _target;
1394
1395 /**
1396 * The cascade sections sharing the common target.
1397 */
1398 NodeList<Expression> _cascadeSections;
1399
1400 /**
1401 * Initialize a newly created cascade expression. The list of
1402 * [cascadeSections] must contain at least one element.
1403 */
1404 CascadeExpressionImpl(Expression target, List<Expression> cascadeSections) {
1405 _target = _becomeParentOf(target);
1406 _cascadeSections = new NodeList<Expression>(this, cascadeSections);
1407 }
1408
1409 @override
1410 Token get beginToken => _target.beginToken;
1411
1412 @override
1413 NodeList<Expression> get cascadeSections => _cascadeSections;
1414
1415 @override
1416 Iterable get childEntities => new ChildEntities()
1417 ..add(_target)
1418 ..addAll(_cascadeSections);
1419
1420 @override
1421 Token get endToken => _cascadeSections.endToken;
1422
1423 @override
1424 int get precedence => 2;
1425
1426 @override
1427 Expression get target => _target;
1428
1429 @override
1430 void set target(Expression target) {
1431 _target = _becomeParentOf(target);
1432 }
1433
1434 @override
1435 accept(AstVisitor visitor) => visitor.visitCascadeExpression(this);
1436
1437 @override
1438 void visitChildren(AstVisitor visitor) {
1439 _safelyVisitChild(_target, visitor);
1440 _cascadeSections.accept(visitor);
1441 }
1442 }
1443
1444 /**
1445 * A catch clause within a try statement.
1446 *
1447 * > onPart ::=
1448 * > catchPart [Block]
1449 * > | 'on' type catchPart? [Block]
1450 * >
1451 * > catchPart ::=
1452 * > 'catch' '(' [SimpleIdentifier] (',' [SimpleIdentifier])? ')'
1453 */
1454 class CatchClauseImpl extends AstNodeImpl implements CatchClause {
1455 /**
1456 * The token representing the 'on' keyword, or `null` if there is no 'on'
1457 * keyword.
1458 */
1459 Token onKeyword;
1460
1461 /**
1462 * The type of exceptions caught by this catch clause, or `null` if this catch
1463 * clause catches every type of exception.
1464 */
1465 TypeName _exceptionType;
1466
1467 /**
1468 * The token representing the 'catch' keyword, or `null` if there is no
1469 * 'catch' keyword.
1470 */
1471 Token catchKeyword;
1472
1473 /**
1474 * The left parenthesis, or `null` if there is no 'catch' keyword.
1475 */
1476 Token leftParenthesis;
1477
1478 /**
1479 * The parameter whose value will be the exception that was thrown, or `null`
1480 * if there is no 'catch' keyword.
1481 */
1482 SimpleIdentifier _exceptionParameter;
1483
1484 /**
1485 * The comma separating the exception parameter from the stack trace
1486 * parameter, or `null` if there is no stack trace parameter.
1487 */
1488 Token comma;
1489
1490 /**
1491 * The parameter whose value will be the stack trace associated with the
1492 * exception, or `null` if there is no stack trace parameter.
1493 */
1494 SimpleIdentifier _stackTraceParameter;
1495
1496 /**
1497 * The right parenthesis, or `null` if there is no 'catch' keyword.
1498 */
1499 Token rightParenthesis;
1500
1501 /**
1502 * The body of the catch block.
1503 */
1504 Block _body;
1505
1506 /**
1507 * Initialize a newly created catch clause. The [onKeyword] and
1508 * [exceptionType] can be `null` if the clause will catch all exceptions. The
1509 * [comma] and [stackTraceParameter] can be `null` if the stack trace
1510 * parameter is not defined.
1511 */
1512 CatchClauseImpl(
1513 this.onKeyword,
1514 TypeName exceptionType,
1515 this.catchKeyword,
1516 this.leftParenthesis,
1517 SimpleIdentifier exceptionParameter,
1518 this.comma,
1519 SimpleIdentifier stackTraceParameter,
1520 this.rightParenthesis,
1521 Block body) {
1522 _exceptionType = _becomeParentOf(exceptionType);
1523 _exceptionParameter = _becomeParentOf(exceptionParameter);
1524 _stackTraceParameter = _becomeParentOf(stackTraceParameter);
1525 _body = _becomeParentOf(body);
1526 }
1527
1528 @override
1529 Token get beginToken {
1530 if (onKeyword != null) {
1531 return onKeyword;
1532 }
1533 return catchKeyword;
1534 }
1535
1536 @override
1537 Block get body => _body;
1538
1539 @override
1540 void set body(Block block) {
1541 _body = _becomeParentOf(block);
1542 }
1543
1544 @override
1545 Iterable get childEntities => new ChildEntities()
1546 ..add(onKeyword)
1547 ..add(_exceptionType)
1548 ..add(catchKeyword)
1549 ..add(leftParenthesis)
1550 ..add(_exceptionParameter)
1551 ..add(comma)
1552 ..add(_stackTraceParameter)
1553 ..add(rightParenthesis)
1554 ..add(_body);
1555
1556 @override
1557 Token get endToken => _body.endToken;
1558
1559 @override
1560 SimpleIdentifier get exceptionParameter => _exceptionParameter;
1561
1562 @override
1563 void set exceptionParameter(SimpleIdentifier parameter) {
1564 _exceptionParameter = _becomeParentOf(parameter);
1565 }
1566
1567 @override
1568 TypeName get exceptionType => _exceptionType;
1569
1570 @override
1571 void set exceptionType(TypeName exceptionType) {
1572 _exceptionType = _becomeParentOf(exceptionType);
1573 }
1574
1575 @override
1576 SimpleIdentifier get stackTraceParameter => _stackTraceParameter;
1577
1578 @override
1579 void set stackTraceParameter(SimpleIdentifier parameter) {
1580 _stackTraceParameter = _becomeParentOf(parameter);
1581 }
1582
1583 @override
1584 accept(AstVisitor visitor) => visitor.visitCatchClause(this);
1585
1586 @override
1587 void visitChildren(AstVisitor visitor) {
1588 _safelyVisitChild(_exceptionType, visitor);
1589 _safelyVisitChild(_exceptionParameter, visitor);
1590 _safelyVisitChild(_stackTraceParameter, visitor);
1591 _safelyVisitChild(_body, visitor);
1592 }
1593 }
1594
1595 /**
1596 * Helper class to allow iteration of child entities of an AST node.
1597 */
1598 class ChildEntities extends Object with IterableMixin implements Iterable {
1599 /**
1600 * The list of child entities to be iterated over.
1601 */
1602 List _entities = [];
1603
1604 @override
1605 Iterator get iterator => _entities.iterator;
1606
1607 /**
1608 * Add an AST node or token as the next child entity, if it is not null.
1609 */
1610 void add(entity) {
1611 if (entity != null) {
1612 assert(entity is Token || entity is AstNode);
1613 _entities.add(entity);
1614 }
1615 }
1616
1617 /**
1618 * Add the given items as the next child entities, if [items] is not null.
1619 */
1620 void addAll(Iterable items) {
1621 if (items != null) {
1622 _entities.addAll(items);
1623 }
1624 }
1625 }
1626
1627 /**
1628 * The declaration of a class.
1629 *
1630 * > classDeclaration ::=
1631 * > 'abstract'? 'class' [SimpleIdentifier] [TypeParameterList]?
1632 * > ([ExtendsClause] [WithClause]?)?
1633 * > [ImplementsClause]?
1634 * > '{' [ClassMember]* '}'
1635 */
1636 class ClassDeclarationImpl extends NamedCompilationUnitMemberImpl
1637 implements ClassDeclaration {
1638 /**
1639 * The 'abstract' keyword, or `null` if the keyword was absent.
1640 */
1641 Token abstractKeyword;
1642
1643 /**
1644 * The token representing the 'class' keyword.
1645 */
1646 Token classKeyword;
1647
1648 /**
1649 * The type parameters for the class, or `null` if the class does not have any
1650 * type parameters.
1651 */
1652 TypeParameterList _typeParameters;
1653
1654 /**
1655 * The extends clause for the class, or `null` if the class does not extend
1656 * any other class.
1657 */
1658 ExtendsClause _extendsClause;
1659
1660 /**
1661 * The with clause for the class, or `null` if the class does not have a with
1662 * clause.
1663 */
1664 WithClause _withClause;
1665
1666 /**
1667 * The implements clause for the class, or `null` if the class does not
1668 * implement any interfaces.
1669 */
1670 ImplementsClause _implementsClause;
1671
1672 /**
1673 * The native clause for the class, or `null` if the class does not have a
1674 * native clause.
1675 */
1676 NativeClause _nativeClause;
1677
1678 /**
1679 * The left curly bracket.
1680 */
1681 Token leftBracket;
1682
1683 /**
1684 * The members defined by the class.
1685 */
1686 NodeList<ClassMember> _members;
1687
1688 /**
1689 * The right curly bracket.
1690 */
1691 Token rightBracket;
1692
1693 /**
1694 * Initialize a newly created class declaration. Either or both of the
1695 * [comment] and [metadata] can be `null` if the class does not have the
1696 * corresponding attribute. The [abstractKeyword] can be `null` if the class
1697 * is not abstract. The [typeParameters] can be `null` if the class does not
1698 * have any type parameters. Any or all of the [extendsClause], [withClause],
1699 * and [implementsClause] can be `null` if the class does not have the
1700 * corresponding clause. The list of [members] can be `null` if the class does
1701 * not have any members.
1702 */
1703 ClassDeclarationImpl(
1704 Comment comment,
1705 List<Annotation> metadata,
1706 this.abstractKeyword,
1707 this.classKeyword,
1708 SimpleIdentifier name,
1709 TypeParameterList typeParameters,
1710 ExtendsClause extendsClause,
1711 WithClause withClause,
1712 ImplementsClause implementsClause,
1713 this.leftBracket,
1714 List<ClassMember> members,
1715 this.rightBracket)
1716 : super(comment, metadata, name) {
1717 _typeParameters = _becomeParentOf(typeParameters);
1718 _extendsClause = _becomeParentOf(extendsClause);
1719 _withClause = _becomeParentOf(withClause);
1720 _implementsClause = _becomeParentOf(implementsClause);
1721 _members = new NodeList<ClassMember>(this, members);
1722 }
1723
1724 @override
1725 Iterable get childEntities => super._childEntities
1726 ..add(abstractKeyword)
1727 ..add(classKeyword)
1728 ..add(_name)
1729 ..add(_typeParameters)
1730 ..add(_extendsClause)
1731 ..add(_withClause)
1732 ..add(_implementsClause)
1733 ..add(_nativeClause)
1734 ..add(leftBracket)
1735 ..addAll(members)
1736 ..add(rightBracket);
1737
1738 @override
1739 ClassElement get element =>
1740 _name != null ? (_name.staticElement as ClassElement) : null;
1741
1742 @override
1743 Token get endToken => rightBracket;
1744
1745 @override
1746 ExtendsClause get extendsClause => _extendsClause;
1747
1748 @override
1749 void set extendsClause(ExtendsClause extendsClause) {
1750 _extendsClause = _becomeParentOf(extendsClause);
1751 }
1752
1753 @override
1754 Token get firstTokenAfterCommentAndMetadata {
1755 if (abstractKeyword != null) {
1756 return abstractKeyword;
1757 }
1758 return classKeyword;
1759 }
1760
1761 @override
1762 ImplementsClause get implementsClause => _implementsClause;
1763
1764 @override
1765 void set implementsClause(ImplementsClause implementsClause) {
1766 _implementsClause = _becomeParentOf(implementsClause);
1767 }
1768
1769 @override
1770 bool get isAbstract => abstractKeyword != null;
1771
1772 @override
1773 NodeList<ClassMember> get members => _members;
1774
1775 @override
1776 NativeClause get nativeClause => _nativeClause;
1777
1778 @override
1779 void set nativeClause(NativeClause nativeClause) {
1780 _nativeClause = _becomeParentOf(nativeClause);
1781 }
1782
1783 @override
1784 TypeParameterList get typeParameters => _typeParameters;
1785
1786 @override
1787 void set typeParameters(TypeParameterList typeParameters) {
1788 _typeParameters = _becomeParentOf(typeParameters);
1789 }
1790
1791 @override
1792 WithClause get withClause => _withClause;
1793
1794 @override
1795 void set withClause(WithClause withClause) {
1796 _withClause = _becomeParentOf(withClause);
1797 }
1798
1799 @override
1800 accept(AstVisitor visitor) => visitor.visitClassDeclaration(this);
1801
1802 @override
1803 ConstructorDeclaration getConstructor(String name) {
1804 for (ClassMember classMember in _members) {
1805 if (classMember is ConstructorDeclaration) {
1806 ConstructorDeclaration constructor = classMember;
1807 SimpleIdentifier constructorName = constructor.name;
1808 if (name == null && constructorName == null) {
1809 return constructor;
1810 }
1811 if (constructorName != null && constructorName.name == name) {
1812 return constructor;
1813 }
1814 }
1815 }
1816 return null;
1817 }
1818
1819 @override
1820 VariableDeclaration getField(String name) {
1821 for (ClassMember classMember in _members) {
1822 if (classMember is FieldDeclaration) {
1823 FieldDeclaration fieldDeclaration = classMember;
1824 NodeList<VariableDeclaration> fields =
1825 fieldDeclaration.fields.variables;
1826 for (VariableDeclaration field in fields) {
1827 SimpleIdentifier fieldName = field.name;
1828 if (fieldName != null && name == fieldName.name) {
1829 return field;
1830 }
1831 }
1832 }
1833 }
1834 return null;
1835 }
1836
1837 @override
1838 MethodDeclaration getMethod(String name) {
1839 for (ClassMember classMember in _members) {
1840 if (classMember is MethodDeclaration) {
1841 MethodDeclaration method = classMember;
1842 SimpleIdentifier methodName = method.name;
1843 if (methodName != null && name == methodName.name) {
1844 return method;
1845 }
1846 }
1847 }
1848 return null;
1849 }
1850
1851 @override
1852 void visitChildren(AstVisitor visitor) {
1853 super.visitChildren(visitor);
1854 _safelyVisitChild(_name, visitor);
1855 _safelyVisitChild(_typeParameters, visitor);
1856 _safelyVisitChild(_extendsClause, visitor);
1857 _safelyVisitChild(_withClause, visitor);
1858 _safelyVisitChild(_implementsClause, visitor);
1859 _safelyVisitChild(_nativeClause, visitor);
1860 members.accept(visitor);
1861 }
1862 }
1863
1864 /**
1865 * A node that declares a name within the scope of a class.
1866 */
1867 abstract class ClassMemberImpl extends DeclarationImpl implements ClassMember {
1868 /**
1869 * Initialize a newly created member of a class. Either or both of the
1870 * [comment] and [metadata] can be `null` if the member does not have the
1871 * corresponding attribute.
1872 */
1873 ClassMemberImpl(Comment comment, List<Annotation> metadata)
1874 : super(comment, metadata);
1875 }
1876
1877 /**
1878 * A class type alias.
1879 *
1880 * > classTypeAlias ::=
1881 * > [SimpleIdentifier] [TypeParameterList]? '=' 'abstract'? mixinApplicatio n
1882 * >
1883 * > mixinApplication ::=
1884 * > [TypeName] [WithClause] [ImplementsClause]? ';'
1885 */
1886 class ClassTypeAliasImpl extends TypeAliasImpl implements ClassTypeAlias {
1887 /**
1888 * The type parameters for the class, or `null` if the class does not have any
1889 * type parameters.
1890 */
1891 TypeParameterList _typeParameters;
1892
1893 /**
1894 * The token for the '=' separating the name from the definition.
1895 */
1896 Token equals;
1897
1898 /**
1899 * The token for the 'abstract' keyword, or `null` if this is not defining an
1900 * abstract class.
1901 */
1902 Token abstractKeyword;
1903
1904 /**
1905 * The name of the superclass of the class being declared.
1906 */
1907 TypeName _superclass;
1908
1909 /**
1910 * The with clause for this class.
1911 */
1912 WithClause _withClause;
1913
1914 /**
1915 * The implements clause for this class, or `null` if there is no implements
1916 * clause.
1917 */
1918 ImplementsClause _implementsClause;
1919
1920 /**
1921 * Initialize a newly created class type alias. Either or both of the
1922 * [comment] and [metadata] can be `null` if the class type alias does not
1923 * have the corresponding attribute. The [typeParameters] can be `null` if the
1924 * class does not have any type parameters. The [abstractKeyword] can be
1925 * `null` if the class is not abstract. The [implementsClause] can be `null`
1926 * if the class does not implement any interfaces.
1927 */
1928 ClassTypeAliasImpl(
1929 Comment comment,
1930 List<Annotation> metadata,
1931 Token keyword,
1932 SimpleIdentifier name,
1933 TypeParameterList typeParameters,
1934 this.equals,
1935 this.abstractKeyword,
1936 TypeName superclass,
1937 WithClause withClause,
1938 ImplementsClause implementsClause,
1939 Token semicolon)
1940 : super(comment, metadata, keyword, name, semicolon) {
1941 _typeParameters = _becomeParentOf(typeParameters);
1942 _superclass = _becomeParentOf(superclass);
1943 _withClause = _becomeParentOf(withClause);
1944 _implementsClause = _becomeParentOf(implementsClause);
1945 }
1946
1947 @override
1948 Iterable get childEntities => super._childEntities
1949 ..add(typedefKeyword)
1950 ..add(_name)
1951 ..add(_typeParameters)
1952 ..add(equals)
1953 ..add(abstractKeyword)
1954 ..add(_superclass)
1955 ..add(_withClause)
1956 ..add(_implementsClause)
1957 ..add(semicolon);
1958
1959 @override
1960 ClassElement get element =>
1961 _name != null ? (_name.staticElement as ClassElement) : null;
1962
1963 @override
1964 ImplementsClause get implementsClause => _implementsClause;
1965
1966 @override
1967 void set implementsClause(ImplementsClause implementsClause) {
1968 _implementsClause = _becomeParentOf(implementsClause);
1969 }
1970
1971 @override
1972 bool get isAbstract => abstractKeyword != null;
1973
1974 @override
1975 TypeName get superclass => _superclass;
1976
1977 @override
1978 void set superclass(TypeName superclass) {
1979 _superclass = _becomeParentOf(superclass);
1980 }
1981
1982 @override
1983 TypeParameterList get typeParameters => _typeParameters;
1984
1985 @override
1986 void set typeParameters(TypeParameterList typeParameters) {
1987 _typeParameters = _becomeParentOf(typeParameters);
1988 }
1989
1990 @override
1991 WithClause get withClause => _withClause;
1992
1993 @override
1994 void set withClause(WithClause withClause) {
1995 _withClause = _becomeParentOf(withClause);
1996 }
1997
1998 @override
1999 accept(AstVisitor visitor) => visitor.visitClassTypeAlias(this);
2000
2001 @override
2002 void visitChildren(AstVisitor visitor) {
2003 super.visitChildren(visitor);
2004 _safelyVisitChild(_name, visitor);
2005 _safelyVisitChild(_typeParameters, visitor);
2006 _safelyVisitChild(_superclass, visitor);
2007 _safelyVisitChild(_withClause, visitor);
2008 _safelyVisitChild(_implementsClause, visitor);
2009 }
2010 }
2011
2012 /**
2013 * A combinator associated with an import or export directive.
2014 *
2015 * > combinator ::=
2016 * > [HideCombinator]
2017 * > | [ShowCombinator]
2018 */
2019 abstract class CombinatorImpl extends AstNodeImpl implements Combinator {
2020 /**
2021 * The 'hide' or 'show' keyword specifying what kind of processing is to be
2022 * done on the names.
2023 */
2024 Token keyword;
2025
2026 /**
2027 * Initialize a newly created combinator.
2028 */
2029 CombinatorImpl(this.keyword);
2030
2031 @override
2032 Token get beginToken => keyword;
2033 }
2034
2035 /**
2036 * A comment within the source code.
2037 *
2038 * > comment ::=
2039 * > endOfLineComment
2040 * > | blockComment
2041 * > | documentationComment
2042 * >
2043 * > endOfLineComment ::=
2044 * > '//' (CHARACTER - EOL)* EOL
2045 * >
2046 * > blockComment ::=
2047 * > '/ *' CHARACTER* '&#42;/'
2048 * >
2049 * > documentationComment ::=
2050 * > '/ **' (CHARACTER | [CommentReference])* '&#42;/'
2051 * > | ('///' (CHARACTER - EOL)* EOL)+
2052 */
2053 class CommentImpl extends AstNodeImpl implements Comment {
2054 /**
2055 * The tokens representing the comment.
2056 */
2057 final List<Token> tokens;
2058
2059 /**
2060 * The type of the comment.
2061 */
2062 final CommentType _type;
2063
2064 /**
2065 * The references embedded within the documentation comment. This list will be
2066 * empty unless this is a documentation comment that has references embedded
2067 * within it.
2068 */
2069 NodeList<CommentReference> _references;
2070
2071 /**
2072 * Initialize a newly created comment. The list of [tokens] must contain at
2073 * least one token. The [type] is the type of the comment. The list of
2074 * [references] can be empty if the comment does not contain any embedded
2075 * references.
2076 */
2077 CommentImpl(this.tokens, this._type, List<CommentReference> references) {
2078 _references = new NodeList<CommentReference>(this, references);
2079 }
2080
2081 @override
2082 Token get beginToken => tokens[0];
2083
2084 @override
2085 Iterable get childEntities => new ChildEntities()..addAll(tokens);
2086
2087 @override
2088 Token get endToken => tokens[tokens.length - 1];
2089
2090 @override
2091 bool get isBlock => _type == CommentType.BLOCK;
2092
2093 @override
2094 bool get isDocumentation => _type == CommentType.DOCUMENTATION;
2095
2096 @override
2097 bool get isEndOfLine => _type == CommentType.END_OF_LINE;
2098
2099 @override
2100 NodeList<CommentReference> get references => _references;
2101
2102 @override
2103 accept(AstVisitor visitor) => visitor.visitComment(this);
2104
2105 @override
2106 void visitChildren(AstVisitor visitor) {
2107 _references.accept(visitor);
2108 }
2109
2110 /**
2111 * Create a block comment consisting of the given [tokens].
2112 */
2113 static Comment createBlockComment(List<Token> tokens) =>
2114 new CommentImpl(tokens, CommentType.BLOCK, null);
2115
2116 /**
2117 * Create a documentation comment consisting of the given [tokens].
2118 */
2119 static Comment createDocumentationComment(List<Token> tokens) =>
2120 new CommentImpl(
2121 tokens, CommentType.DOCUMENTATION, new List<CommentReference>());
2122
2123 /**
2124 * Create a documentation comment consisting of the given [tokens] and having
2125 * the given [references] embedded within it.
2126 */
2127 static Comment createDocumentationCommentWithReferences(
2128 List<Token> tokens, List<CommentReference> references) =>
2129 new CommentImpl(tokens, CommentType.DOCUMENTATION, references);
2130
2131 /**
2132 * Create an end-of-line comment consisting of the given [tokens].
2133 */
2134 static Comment createEndOfLineComment(List<Token> tokens) =>
2135 new CommentImpl(tokens, CommentType.END_OF_LINE, null);
2136 }
2137
2138 /**
2139 * A reference to a Dart element that is found within a documentation comment.
2140 *
2141 * > commentReference ::=
2142 * > '[' 'new'? [Identifier] ']'
2143 */
2144 class CommentReferenceImpl extends AstNodeImpl implements CommentReference {
2145 /**
2146 * The token representing the 'new' keyword, or `null` if there was no 'new'
2147 * keyword.
2148 */
2149 Token newKeyword;
2150
2151 /**
2152 * The identifier being referenced.
2153 */
2154 Identifier _identifier;
2155
2156 /**
2157 * Initialize a newly created reference to a Dart element. The [newKeyword]
2158 * can be `null` if the reference is not to a constructor.
2159 */
2160 CommentReferenceImpl(this.newKeyword, Identifier identifier) {
2161 _identifier = _becomeParentOf(identifier);
2162 }
2163
2164 @override
2165 Token get beginToken => _identifier.beginToken;
2166
2167 @override
2168 Iterable get childEntities =>
2169 new ChildEntities()..add(newKeyword)..add(_identifier);
2170
2171 @override
2172 Token get endToken => _identifier.endToken;
2173
2174 @override
2175 Identifier get identifier => _identifier;
2176
2177 @override
2178 void set identifier(Identifier identifier) {
2179 _identifier = _becomeParentOf(identifier);
2180 }
2181
2182 @override
2183 accept(AstVisitor visitor) => visitor.visitCommentReference(this);
2184
2185 @override
2186 void visitChildren(AstVisitor visitor) {
2187 _safelyVisitChild(_identifier, visitor);
2188 }
2189 }
2190
2191 /**
2192 * The possible types of comments that are recognized by the parser.
2193 */
2194 class CommentType {
2195 /**
2196 * A block comment.
2197 */
2198 static const CommentType BLOCK = const CommentType('BLOCK');
2199
2200 /**
2201 * A documentation comment.
2202 */
2203 static const CommentType DOCUMENTATION = const CommentType('DOCUMENTATION');
2204
2205 /**
2206 * An end-of-line comment.
2207 */
2208 static const CommentType END_OF_LINE = const CommentType('END_OF_LINE');
2209
2210 /**
2211 * The name of the comment type.
2212 */
2213 final String name;
2214
2215 /**
2216 * Initialize a newly created comment type to have the given [name].
2217 */
2218 const CommentType(this.name);
2219
2220 @override
2221 String toString() => name;
2222 }
2223
2224 /**
2225 * A compilation unit.
2226 *
2227 * While the grammar restricts the order of the directives and declarations
2228 * within a compilation unit, this class does not enforce those restrictions.
2229 * In particular, the children of a compilation unit will be visited in lexical
2230 * order even if lexical order does not conform to the restrictions of the
2231 * grammar.
2232 *
2233 * > compilationUnit ::=
2234 * > directives declarations
2235 * >
2236 * > directives ::=
2237 * > [ScriptTag]? [LibraryDirective]? namespaceDirective* [PartDirective]*
2238 * > | [PartOfDirective]
2239 * >
2240 * > namespaceDirective ::=
2241 * > [ImportDirective]
2242 * > | [ExportDirective]
2243 * >
2244 * > declarations ::=
2245 * > [CompilationUnitMember]*
2246 */
2247 class CompilationUnitImpl extends AstNodeImpl implements CompilationUnit {
2248 /**
2249 * The first token in the token stream that was parsed to form this
2250 * compilation unit.
2251 */
2252 Token beginToken;
2253
2254 /**
2255 * The script tag at the beginning of the compilation unit, or `null` if there
2256 * is no script tag in this compilation unit.
2257 */
2258 ScriptTag _scriptTag;
2259
2260 /**
2261 * The directives contained in this compilation unit.
2262 */
2263 NodeList<Directive> _directives;
2264
2265 /**
2266 * The declarations contained in this compilation unit.
2267 */
2268 NodeList<CompilationUnitMember> _declarations;
2269
2270 /**
2271 * The last token in the token stream that was parsed to form this compilation
2272 * unit. This token should always have a type of [TokenType.EOF].
2273 */
2274 Token endToken;
2275
2276 /**
2277 * The element associated with this compilation unit, or `null` if the AST
2278 * structure has not been resolved.
2279 */
2280 CompilationUnitElement element;
2281
2282 /**
2283 * The line information for this compilation unit.
2284 */
2285 LineInfo lineInfo;
2286
2287 /**
2288 * Initialize a newly created compilation unit to have the given directives
2289 * and declarations. The [scriptTag] can be `null` if there is no script tag
2290 * in the compilation unit. The list of [directives] can be `null` if there
2291 * are no directives in the compilation unit. The list of [declarations] can
2292 * be `null` if there are no declarations in the compilation unit.
2293 */
2294 CompilationUnitImpl(
2295 this.beginToken,
2296 ScriptTag scriptTag,
2297 List<Directive> directives,
2298 List<CompilationUnitMember> declarations,
2299 this.endToken) {
2300 _scriptTag = _becomeParentOf(scriptTag);
2301 _directives = new NodeList<Directive>(this, directives);
2302 _declarations = new NodeList<CompilationUnitMember>(this, declarations);
2303 }
2304
2305 @override
2306 Iterable get childEntities {
2307 ChildEntities result = new ChildEntities()..add(_scriptTag);
2308 if (_directivesAreBeforeDeclarations) {
2309 result..addAll(_directives)..addAll(_declarations);
2310 } else {
2311 result.addAll(sortedDirectivesAndDeclarations);
2312 }
2313 return result;
2314 }
2315
2316 @override
2317 NodeList<CompilationUnitMember> get declarations => _declarations;
2318
2319 @override
2320 NodeList<Directive> get directives => _directives;
2321
2322 @override
2323 int get length {
2324 Token endToken = this.endToken;
2325 if (endToken == null) {
2326 return 0;
2327 }
2328 return endToken.offset + endToken.length;
2329 }
2330
2331 @override
2332 int get offset => 0;
2333
2334 @override
2335 ScriptTag get scriptTag => _scriptTag;
2336
2337 @override
2338 void set scriptTag(ScriptTag scriptTag) {
2339 _scriptTag = _becomeParentOf(scriptTag);
2340 }
2341
2342 @override
2343 List<AstNode> get sortedDirectivesAndDeclarations {
2344 return <AstNode>[]
2345 ..addAll(_directives)
2346 ..addAll(_declarations)
2347 ..sort(AstNode.LEXICAL_ORDER);
2348 }
2349
2350 /**
2351 * Return `true` if all of the directives are lexically before any
2352 * declarations.
2353 */
2354 bool get _directivesAreBeforeDeclarations {
2355 if (_directives.isEmpty || _declarations.isEmpty) {
2356 return true;
2357 }
2358 Directive lastDirective = _directives[_directives.length - 1];
2359 CompilationUnitMember firstDeclaration = _declarations[0];
2360 return lastDirective.offset < firstDeclaration.offset;
2361 }
2362
2363 @override
2364 accept(AstVisitor visitor) => visitor.visitCompilationUnit(this);
2365
2366 @override
2367 void visitChildren(AstVisitor visitor) {
2368 _safelyVisitChild(_scriptTag, visitor);
2369 if (_directivesAreBeforeDeclarations) {
2370 _directives.accept(visitor);
2371 _declarations.accept(visitor);
2372 } else {
2373 for (AstNode child in sortedDirectivesAndDeclarations) {
2374 child.accept(visitor);
2375 }
2376 }
2377 }
2378 }
2379
2380 /**
2381 * A node that declares one or more names within the scope of a compilation
2382 * unit.
2383 *
2384 * > compilationUnitMember ::=
2385 * > [ClassDeclaration]
2386 * > | [TypeAlias]
2387 * > | [FunctionDeclaration]
2388 * > | [MethodDeclaration]
2389 * > | [VariableDeclaration]
2390 * > | [VariableDeclaration]
2391 */
2392 abstract class CompilationUnitMemberImpl extends DeclarationImpl
2393 implements CompilationUnitMember {
2394 /**
2395 * Initialize a newly created generic compilation unit member. Either or both
2396 * of the [comment] and [metadata] can be `null` if the member does not have
2397 * the corresponding attribute.
2398 */
2399 CompilationUnitMemberImpl(Comment comment, List<Annotation> metadata)
2400 : super(comment, metadata);
2401 }
2402
2403 /**
2404 * A conditional expression.
2405 *
2406 * > conditionalExpression ::=
2407 * > [Expression] '?' [Expression] ':' [Expression]
2408 */
2409 class ConditionalExpressionImpl extends ExpressionImpl
2410 implements ConditionalExpression {
2411 /**
2412 * The condition used to determine which of the expressions is executed next.
2413 */
2414 Expression _condition;
2415
2416 /**
2417 * The token used to separate the condition from the then expression.
2418 */
2419 Token question;
2420
2421 /**
2422 * The expression that is executed if the condition evaluates to `true`.
2423 */
2424 Expression _thenExpression;
2425
2426 /**
2427 * The token used to separate the then expression from the else expression.
2428 */
2429 Token colon;
2430
2431 /**
2432 * The expression that is executed if the condition evaluates to `false`.
2433 */
2434 Expression _elseExpression;
2435
2436 /**
2437 * Initialize a newly created conditional expression.
2438 */
2439 ConditionalExpressionImpl(Expression condition, this.question,
2440 Expression thenExpression, this.colon, Expression elseExpression) {
2441 _condition = _becomeParentOf(condition);
2442 _thenExpression = _becomeParentOf(thenExpression);
2443 _elseExpression = _becomeParentOf(elseExpression);
2444 }
2445
2446 @override
2447 Token get beginToken => _condition.beginToken;
2448
2449 @override
2450 Iterable get childEntities => new ChildEntities()
2451 ..add(_condition)
2452 ..add(question)
2453 ..add(_thenExpression)
2454 ..add(colon)
2455 ..add(_elseExpression);
2456
2457 @override
2458 Expression get condition => _condition;
2459
2460 @override
2461 void set condition(Expression expression) {
2462 _condition = _becomeParentOf(expression);
2463 }
2464
2465 @override
2466 Expression get elseExpression => _elseExpression;
2467
2468 @override
2469 void set elseExpression(Expression expression) {
2470 _elseExpression = _becomeParentOf(expression);
2471 }
2472
2473 @override
2474 Token get endToken => _elseExpression.endToken;
2475
2476 @override
2477 int get precedence => 3;
2478
2479 @override
2480 Expression get thenExpression => _thenExpression;
2481
2482 @override
2483 void set thenExpression(Expression expression) {
2484 _thenExpression = _becomeParentOf(expression);
2485 }
2486
2487 @override
2488 accept(AstVisitor visitor) => visitor.visitConditionalExpression(this);
2489
2490 @override
2491 void visitChildren(AstVisitor visitor) {
2492 _safelyVisitChild(_condition, visitor);
2493 _safelyVisitChild(_thenExpression, visitor);
2494 _safelyVisitChild(_elseExpression, visitor);
2495 }
2496 }
2497
2498 /**
2499 * A configuration in either an import or export directive.
2500 *
2501 * configuration ::=
2502 * 'if' '(' test ')' uri
2503 *
2504 * test ::=
2505 * dottedName ('==' stringLiteral)?
2506 *
2507 * dottedName ::=
2508 * identifier ('.' identifier)*
2509 */
2510 class ConfigurationImpl extends AstNodeImpl implements Configuration {
2511 Token ifKeyword;
2512 Token leftParenthesis;
2513 DottedName _name;
2514 Token equalToken;
2515 StringLiteral _value;
2516 Token rightParenthesis;
2517 StringLiteral _libraryUri;
2518
2519 ConfigurationImpl(
2520 this.ifKeyword,
2521 this.leftParenthesis,
2522 DottedName name,
2523 this.equalToken,
2524 StringLiteral value,
2525 this.rightParenthesis,
2526 StringLiteral libraryUri) {
2527 _name = _becomeParentOf(name);
2528 _value = _becomeParentOf(value);
2529 _libraryUri = _becomeParentOf(libraryUri);
2530 }
2531
2532 @override
2533 Token get beginToken => ifKeyword;
2534
2535 @override
2536 Iterable get childEntities => new ChildEntities()
2537 ..add(ifKeyword)
2538 ..add(leftParenthesis)
2539 ..add(_name)
2540 ..add(equalToken)
2541 ..add(_value)
2542 ..add(rightParenthesis)
2543 ..add(_libraryUri);
2544
2545 @override
2546 Token get endToken => _libraryUri.endToken;
2547
2548 @override
2549 StringLiteral get libraryUri => _libraryUri;
2550
2551 @override
2552 void set libraryUri(StringLiteral libraryUri) {
2553 _libraryUri = _becomeParentOf(libraryUri);
2554 }
2555
2556 @override
2557 DottedName get name => _name;
2558
2559 @override
2560 void set name(DottedName name) {
2561 _name = _becomeParentOf(name);
2562 }
2563
2564 @override
2565 StringLiteral get value => _value;
2566
2567 @override
2568 void set value(StringLiteral value) {
2569 _value = _becomeParentOf(value);
2570 }
2571
2572 @override
2573 accept(AstVisitor visitor) => visitor.visitConfiguration(this);
2574
2575 @override
2576 void visitChildren(AstVisitor visitor) {
2577 _safelyVisitChild(_name, visitor);
2578 _safelyVisitChild(_value, visitor);
2579 _safelyVisitChild(_libraryUri, visitor);
2580 }
2581 }
2582
2583 /**
2584 * A constructor declaration.
2585 *
2586 * > constructorDeclaration ::=
2587 * > constructorSignature [FunctionBody]?
2588 * > | constructorName formalParameterList ':' 'this' ('.' [SimpleIdentifier]) ? arguments
2589 * >
2590 * > constructorSignature ::=
2591 * > 'external'? constructorName formalParameterList initializerList?
2592 * > | 'external'? 'factory' factoryName formalParameterList initializerList?
2593 * > | 'external'? 'const' constructorName formalParameterList initializerLis t?
2594 * >
2595 * > constructorName ::=
2596 * > [SimpleIdentifier] ('.' [SimpleIdentifier])?
2597 * >
2598 * > factoryName ::=
2599 * > [Identifier] ('.' [SimpleIdentifier])?
2600 * >
2601 * > initializerList ::=
2602 * > ':' [ConstructorInitializer] (',' [ConstructorInitializer])*
2603 */
2604 class ConstructorDeclarationImpl extends ClassMemberImpl
2605 implements ConstructorDeclaration {
2606 /**
2607 * The token for the 'external' keyword, or `null` if the constructor is not
2608 * external.
2609 */
2610 Token externalKeyword;
2611
2612 /**
2613 * The token for the 'const' keyword, or `null` if the constructor is not a
2614 * const constructor.
2615 */
2616 Token constKeyword;
2617
2618 /**
2619 * The token for the 'factory' keyword, or `null` if the constructor is not a
2620 * factory constructor.
2621 */
2622 Token factoryKeyword;
2623
2624 /**
2625 * The type of object being created. This can be different than the type in
2626 * which the constructor is being declared if the constructor is the
2627 * implementation of a factory constructor.
2628 */
2629 Identifier _returnType;
2630
2631 /**
2632 * The token for the period before the constructor name, or `null` if the
2633 * constructor being declared is unnamed.
2634 */
2635 Token period;
2636
2637 /**
2638 * The name of the constructor, or `null` if the constructor being declared is
2639 * unnamed.
2640 */
2641 SimpleIdentifier _name;
2642
2643 /**
2644 * The parameters associated with the constructor.
2645 */
2646 FormalParameterList _parameters;
2647
2648 /**
2649 * The token for the separator (colon or equals) before the initializer list
2650 * or redirection, or `null` if there are no initializers.
2651 */
2652 Token separator;
2653
2654 /**
2655 * The initializers associated with the constructor.
2656 */
2657 NodeList<ConstructorInitializer> _initializers;
2658
2659 /**
2660 * The name of the constructor to which this constructor will be redirected,
2661 * or `null` if this is not a redirecting factory constructor.
2662 */
2663 ConstructorName _redirectedConstructor;
2664
2665 /**
2666 * The body of the constructor, or `null` if the constructor does not have a
2667 * body.
2668 */
2669 FunctionBody _body;
2670
2671 /**
2672 * The element associated with this constructor, or `null` if the AST
2673 * structure has not been resolved or if this constructor could not be
2674 * resolved.
2675 */
2676 ConstructorElement element;
2677
2678 /**
2679 * Initialize a newly created constructor declaration. The [externalKeyword]
2680 * can be `null` if the constructor is not external. Either or both of the
2681 * [comment] and [metadata] can be `null` if the constructor does not have the
2682 * corresponding attribute. The [constKeyword] can be `null` if the
2683 * constructor cannot be used to create a constant. The [factoryKeyword] can
2684 * be `null` if the constructor is not a factory. The [period] and [name] can
2685 * both be `null` if the constructor is not a named constructor. The
2686 * [separator] can be `null` if the constructor does not have any initializers
2687 * and does not redirect to a different constructor. The list of
2688 * [initializers] can be `null` if the constructor does not have any
2689 * initializers. The [redirectedConstructor] can be `null` if the constructor
2690 * does not redirect to a different constructor. The [body] can be `null` if
2691 * the constructor does not have a body.
2692 */
2693 ConstructorDeclarationImpl(
2694 Comment comment,
2695 List<Annotation> metadata,
2696 this.externalKeyword,
2697 this.constKeyword,
2698 this.factoryKeyword,
2699 Identifier returnType,
2700 this.period,
2701 SimpleIdentifier name,
2702 FormalParameterList parameters,
2703 this.separator,
2704 List<ConstructorInitializer> initializers,
2705 ConstructorName redirectedConstructor,
2706 FunctionBody body)
2707 : super(comment, metadata) {
2708 _returnType = _becomeParentOf(returnType);
2709 _name = _becomeParentOf(name);
2710 _parameters = _becomeParentOf(parameters);
2711 _initializers = new NodeList<ConstructorInitializer>(this, initializers);
2712 _redirectedConstructor = _becomeParentOf(redirectedConstructor);
2713 _body = _becomeParentOf(body);
2714 }
2715
2716 @override
2717 FunctionBody get body => _body;
2718
2719 @override
2720 void set body(FunctionBody functionBody) {
2721 _body = _becomeParentOf(functionBody);
2722 }
2723
2724 @override
2725 Iterable get childEntities => super._childEntities
2726 ..add(externalKeyword)
2727 ..add(constKeyword)
2728 ..add(factoryKeyword)
2729 ..add(_returnType)
2730 ..add(period)
2731 ..add(_name)
2732 ..add(_parameters)
2733 ..add(separator)
2734 ..addAll(initializers)
2735 ..add(_redirectedConstructor)
2736 ..add(_body);
2737
2738 @override
2739 Token get endToken {
2740 if (_body != null) {
2741 return _body.endToken;
2742 } else if (!_initializers.isEmpty) {
2743 return _initializers.endToken;
2744 }
2745 return _parameters.endToken;
2746 }
2747
2748 @override
2749 Token get firstTokenAfterCommentAndMetadata {
2750 Token leftMost =
2751 Token.lexicallyFirst([externalKeyword, constKeyword, factoryKeyword]);
2752 if (leftMost != null) {
2753 return leftMost;
2754 }
2755 return _returnType.beginToken;
2756 }
2757
2758 @override
2759 NodeList<ConstructorInitializer> get initializers => _initializers;
2760
2761 @override
2762 SimpleIdentifier get name => _name;
2763
2764 @override
2765 void set name(SimpleIdentifier identifier) {
2766 _name = _becomeParentOf(identifier);
2767 }
2768
2769 @override
2770 FormalParameterList get parameters => _parameters;
2771
2772 @override
2773 void set parameters(FormalParameterList parameters) {
2774 _parameters = _becomeParentOf(parameters);
2775 }
2776
2777 @override
2778 ConstructorName get redirectedConstructor => _redirectedConstructor;
2779
2780 @override
2781 void set redirectedConstructor(ConstructorName redirectedConstructor) {
2782 _redirectedConstructor = _becomeParentOf(redirectedConstructor);
2783 }
2784
2785 @override
2786 Identifier get returnType => _returnType;
2787
2788 @override
2789 void set returnType(Identifier typeName) {
2790 _returnType = _becomeParentOf(typeName);
2791 }
2792
2793 @override
2794 accept(AstVisitor visitor) => visitor.visitConstructorDeclaration(this);
2795
2796 @override
2797 void visitChildren(AstVisitor visitor) {
2798 super.visitChildren(visitor);
2799 _safelyVisitChild(_returnType, visitor);
2800 _safelyVisitChild(_name, visitor);
2801 _safelyVisitChild(_parameters, visitor);
2802 _initializers.accept(visitor);
2803 _safelyVisitChild(_redirectedConstructor, visitor);
2804 _safelyVisitChild(_body, visitor);
2805 }
2806 }
2807
2808 /**
2809 * The initialization of a field within a constructor's initialization list.
2810 *
2811 * > fieldInitializer ::=
2812 * > ('this' '.')? [SimpleIdentifier] '=' [Expression]
2813 */
2814 class ConstructorFieldInitializerImpl extends ConstructorInitializerImpl
2815 implements ConstructorFieldInitializer {
2816 /**
2817 * The token for the 'this' keyword, or `null` if there is no 'this' keyword.
2818 */
2819 Token thisKeyword;
2820
2821 /**
2822 * The token for the period after the 'this' keyword, or `null` if there is no
2823 * 'this' keyword.
2824 */
2825 Token period;
2826
2827 /**
2828 * The name of the field being initialized.
2829 */
2830 SimpleIdentifier _fieldName;
2831
2832 /**
2833 * The token for the equal sign between the field name and the expression.
2834 */
2835 Token equals;
2836
2837 /**
2838 * The expression computing the value to which the field will be initialized.
2839 */
2840 Expression _expression;
2841
2842 /**
2843 * Initialize a newly created field initializer to initialize the field with
2844 * the given name to the value of the given expression. The [thisKeyword] and
2845 * [period] can be `null` if the 'this' keyword was not specified.
2846 */
2847 ConstructorFieldInitializerImpl(this.thisKeyword, this.period,
2848 SimpleIdentifier fieldName, this.equals, Expression expression) {
2849 _fieldName = _becomeParentOf(fieldName);
2850 _expression = _becomeParentOf(expression);
2851 }
2852
2853 @override
2854 Token get beginToken {
2855 if (thisKeyword != null) {
2856 return thisKeyword;
2857 }
2858 return _fieldName.beginToken;
2859 }
2860
2861 @override
2862 Iterable get childEntities => new ChildEntities()
2863 ..add(thisKeyword)
2864 ..add(period)
2865 ..add(_fieldName)
2866 ..add(equals)
2867 ..add(_expression);
2868
2869 @override
2870 Token get endToken => _expression.endToken;
2871
2872 @override
2873 Expression get expression => _expression;
2874
2875 @override
2876 void set expression(Expression expression) {
2877 _expression = _becomeParentOf(expression);
2878 }
2879
2880 @override
2881 SimpleIdentifier get fieldName => _fieldName;
2882
2883 @override
2884 void set fieldName(SimpleIdentifier identifier) {
2885 _fieldName = _becomeParentOf(identifier);
2886 }
2887
2888 @override
2889 accept(AstVisitor visitor) => visitor.visitConstructorFieldInitializer(this);
2890
2891 @override
2892 void visitChildren(AstVisitor visitor) {
2893 _safelyVisitChild(_fieldName, visitor);
2894 _safelyVisitChild(_expression, visitor);
2895 }
2896 }
2897
2898 /**
2899 * A node that can occur in the initializer list of a constructor declaration.
2900 *
2901 * > constructorInitializer ::=
2902 * > [SuperConstructorInvocation]
2903 * > | [ConstructorFieldInitializer]
2904 * > | [RedirectingConstructorInvocation]
2905 */
2906 abstract class ConstructorInitializerImpl extends AstNodeImpl
2907 implements ConstructorInitializer {}
2908
2909 /**
2910 * The name of the constructor.
2911 *
2912 * > constructorName ::=
2913 * > type ('.' identifier)?
2914 */
2915 class ConstructorNameImpl extends AstNodeImpl implements ConstructorName {
2916 /**
2917 * The name of the type defining the constructor.
2918 */
2919 TypeName _type;
2920
2921 /**
2922 * The token for the period before the constructor name, or `null` if the
2923 * specified constructor is the unnamed constructor.
2924 */
2925 Token period;
2926
2927 /**
2928 * The name of the constructor, or `null` if the specified constructor is the
2929 * unnamed constructor.
2930 */
2931 SimpleIdentifier _name;
2932
2933 /**
2934 * The element associated with this constructor name based on static type
2935 * information, or `null` if the AST structure has not been resolved or if
2936 * this constructor name could not be resolved.
2937 */
2938 ConstructorElement staticElement;
2939
2940 /**
2941 * Initialize a newly created constructor name. The [period] and [name] can be
2942 * `null` if the constructor being named is the unnamed constructor.
2943 */
2944 ConstructorNameImpl(TypeName type, this.period, SimpleIdentifier name) {
2945 _type = _becomeParentOf(type);
2946 _name = _becomeParentOf(name);
2947 }
2948
2949 @override
2950 Token get beginToken => _type.beginToken;
2951
2952 @override
2953 Iterable get childEntities =>
2954 new ChildEntities()..add(_type)..add(period)..add(_name);
2955
2956 @override
2957 Token get endToken {
2958 if (_name != null) {
2959 return _name.endToken;
2960 }
2961 return _type.endToken;
2962 }
2963
2964 @override
2965 SimpleIdentifier get name => _name;
2966
2967 @override
2968 void set name(SimpleIdentifier name) {
2969 _name = _becomeParentOf(name);
2970 }
2971
2972 @override
2973 TypeName get type => _type;
2974
2975 @override
2976 void set type(TypeName type) {
2977 _type = _becomeParentOf(type);
2978 }
2979
2980 @override
2981 accept(AstVisitor visitor) => visitor.visitConstructorName(this);
2982
2983 @override
2984 void visitChildren(AstVisitor visitor) {
2985 _safelyVisitChild(_type, visitor);
2986 _safelyVisitChild(_name, visitor);
2987 }
2988 }
2989
2990 /**
2991 * A continue statement.
2992 *
2993 * > continueStatement ::=
2994 * > 'continue' [SimpleIdentifier]? ';'
2995 */
2996 class ContinueStatementImpl extends StatementImpl implements ContinueStatement {
2997 /**
2998 * The token representing the 'continue' keyword.
2999 */
3000 Token continueKeyword;
3001
3002 /**
3003 * The label associated with the statement, or `null` if there is no label.
3004 */
3005 SimpleIdentifier _label;
3006
3007 /**
3008 * The semicolon terminating the statement.
3009 */
3010 Token semicolon;
3011
3012 /**
3013 * The AstNode which this continue statement is continuing to. This will be
3014 * either a Statement (in the case of continuing a loop) or a SwitchMember
3015 * (in the case of continuing from one switch case to another). Null if the
3016 * AST has not yet been resolved or if the target could not be resolved.
3017 * Note that if the source code has errors, the target may be invalid (e.g.
3018 * the target may be in an enclosing function).
3019 */
3020 AstNode target;
3021
3022 /**
3023 * Initialize a newly created continue statement. The [label] can be `null` if
3024 * there is no label associated with the statement.
3025 */
3026 ContinueStatementImpl(
3027 this.continueKeyword, SimpleIdentifier label, this.semicolon) {
3028 _label = _becomeParentOf(label);
3029 }
3030
3031 @override
3032 Token get beginToken => continueKeyword;
3033
3034 @override
3035 Iterable get childEntities =>
3036 new ChildEntities()..add(continueKeyword)..add(_label)..add(semicolon);
3037
3038 @override
3039 Token get endToken => semicolon;
3040
3041 @override
3042 SimpleIdentifier get label => _label;
3043
3044 @override
3045 void set label(SimpleIdentifier identifier) {
3046 _label = _becomeParentOf(identifier);
3047 }
3048
3049 @override
3050 accept(AstVisitor visitor) => visitor.visitContinueStatement(this);
3051
3052 @override
3053 void visitChildren(AstVisitor visitor) {
3054 _safelyVisitChild(_label, visitor);
3055 }
3056 }
3057
3058 /**
3059 * A node that represents the declaration of one or more names. Each declared
3060 * name is visible within a name scope.
3061 */
3062 abstract class DeclarationImpl extends AnnotatedNodeImpl
3063 implements Declaration {
3064 /**
3065 * Initialize a newly created declaration. Either or both of the [comment] and
3066 * [metadata] can be `null` if the declaration does not have the corresponding
3067 * attribute.
3068 */
3069 DeclarationImpl(Comment comment, List<Annotation> metadata)
3070 : super(comment, metadata);
3071 }
3072
3073 /**
3074 * The declaration of a single identifier.
3075 *
3076 * > declaredIdentifier ::=
3077 * > [Annotation] finalConstVarOrType [SimpleIdentifier]
3078 */
3079 class DeclaredIdentifierImpl extends DeclarationImpl
3080 implements DeclaredIdentifier {
3081 /**
3082 * The token representing either the 'final', 'const' or 'var' keyword, or
3083 * `null` if no keyword was used.
3084 */
3085 Token keyword;
3086
3087 /**
3088 * The name of the declared type of the parameter, or `null` if the parameter
3089 * does not have a declared type.
3090 */
3091 TypeName _type;
3092
3093 /**
3094 * The name of the variable being declared.
3095 */
3096 SimpleIdentifier _identifier;
3097
3098 /**
3099 * Initialize a newly created formal parameter. Either or both of the
3100 * [comment] and [metadata] can be `null` if the declaration does not have the
3101 * corresponding attribute. The [keyword] can be `null` if a type name is
3102 * given. The [type] must be `null` if the keyword is 'var'.
3103 */
3104 DeclaredIdentifierImpl(Comment comment, List<Annotation> metadata,
3105 this.keyword, TypeName type, SimpleIdentifier identifier)
3106 : super(comment, metadata) {
3107 _type = _becomeParentOf(type);
3108 _identifier = _becomeParentOf(identifier);
3109 }
3110
3111 @override
3112 Iterable get childEntities =>
3113 super._childEntities..add(keyword)..add(_type)..add(_identifier);
3114
3115 @override
3116 LocalVariableElement get element {
3117 if (_identifier == null) {
3118 return null;
3119 }
3120 return _identifier.staticElement as LocalVariableElement;
3121 }
3122
3123 @override
3124 Token get endToken => _identifier.endToken;
3125
3126 @override
3127 Token get firstTokenAfterCommentAndMetadata {
3128 if (keyword != null) {
3129 return keyword;
3130 } else if (_type != null) {
3131 return _type.beginToken;
3132 }
3133 return _identifier.beginToken;
3134 }
3135
3136 @override
3137 SimpleIdentifier get identifier => _identifier;
3138
3139 @override
3140 void set identifier(SimpleIdentifier identifier) {
3141 _identifier = _becomeParentOf(identifier);
3142 }
3143
3144 @override
3145 bool get isConst =>
3146 (keyword is KeywordToken) &&
3147 (keyword as KeywordToken).keyword == Keyword.CONST;
3148
3149 @override
3150 bool get isFinal =>
3151 (keyword is KeywordToken) &&
3152 (keyword as KeywordToken).keyword == Keyword.FINAL;
3153
3154 @override
3155 TypeName get type => _type;
3156
3157 @override
3158 void set type(TypeName typeName) {
3159 _type = _becomeParentOf(typeName);
3160 }
3161
3162 @override
3163 accept(AstVisitor visitor) => visitor.visitDeclaredIdentifier(this);
3164
3165 @override
3166 void visitChildren(AstVisitor visitor) {
3167 super.visitChildren(visitor);
3168 _safelyVisitChild(_type, visitor);
3169 _safelyVisitChild(_identifier, visitor);
3170 }
3171 }
3172
3173 /**
3174 * A formal parameter with a default value. There are two kinds of parameters
3175 * that are both represented by this class: named formal parameters and
3176 * positional formal parameters.
3177 *
3178 * > defaultFormalParameter ::=
3179 * > [NormalFormalParameter] ('=' [Expression])?
3180 * >
3181 * > defaultNamedParameter ::=
3182 * > [NormalFormalParameter] (':' [Expression])?
3183 */
3184 class DefaultFormalParameterImpl extends FormalParameterImpl
3185 implements DefaultFormalParameter {
3186 /**
3187 * The formal parameter with which the default value is associated.
3188 */
3189 NormalFormalParameter _parameter;
3190
3191 /**
3192 * The kind of this parameter.
3193 */
3194 ParameterKind kind;
3195
3196 /**
3197 * The token separating the parameter from the default value, or `null` if
3198 * there is no default value.
3199 */
3200 Token separator;
3201
3202 /**
3203 * The expression computing the default value for the parameter, or `null` if
3204 * there is no default value.
3205 */
3206 Expression _defaultValue;
3207
3208 /**
3209 * Initialize a newly created default formal parameter. The [separator] and
3210 * [defaultValue] can be `null` if there is no default value.
3211 */
3212 DefaultFormalParameterImpl(NormalFormalParameter parameter, this.kind,
3213 this.separator, Expression defaultValue) {
3214 _parameter = _becomeParentOf(parameter);
3215 _defaultValue = _becomeParentOf(defaultValue);
3216 }
3217
3218 @override
3219 Token get beginToken => _parameter.beginToken;
3220
3221 @override
3222 Iterable get childEntities =>
3223 new ChildEntities()..add(_parameter)..add(separator)..add(_defaultValue);
3224
3225 @override
3226 Expression get defaultValue => _defaultValue;
3227
3228 @override
3229 void set defaultValue(Expression expression) {
3230 _defaultValue = _becomeParentOf(expression);
3231 }
3232
3233 @override
3234 Token get endToken {
3235 if (_defaultValue != null) {
3236 return _defaultValue.endToken;
3237 }
3238 return _parameter.endToken;
3239 }
3240
3241 @override
3242 SimpleIdentifier get identifier => _parameter.identifier;
3243
3244 @override
3245 bool get isConst => _parameter != null && _parameter.isConst;
3246
3247 @override
3248 bool get isFinal => _parameter != null && _parameter.isFinal;
3249
3250 @override
3251 NodeList<Annotation> get metadata => _parameter.metadata;
3252
3253 @override
3254 NormalFormalParameter get parameter => _parameter;
3255
3256 @override
3257 void set parameter(NormalFormalParameter formalParameter) {
3258 _parameter = _becomeParentOf(formalParameter);
3259 }
3260
3261 @override
3262 accept(AstVisitor visitor) => visitor.visitDefaultFormalParameter(this);
3263
3264 @override
3265 void visitChildren(AstVisitor visitor) {
3266 _safelyVisitChild(_parameter, visitor);
3267 _safelyVisitChild(_defaultValue, visitor);
3268 }
3269 }
3270
3271 /**
3272 * A node that represents a directive.
3273 *
3274 * > directive ::=
3275 * > [ExportDirective]
3276 * > | [ImportDirective]
3277 * > | [LibraryDirective]
3278 * > | [PartDirective]
3279 * > | [PartOfDirective]
3280 */
3281 abstract class DirectiveImpl extends AnnotatedNodeImpl implements Directive {
3282 /**
3283 * The element associated with this directive, or `null` if the AST structure
3284 * has not been resolved or if this directive could not be resolved.
3285 */
3286 Element element;
3287
3288 /**
3289 * Initialize a newly create directive. Either or both of the [comment] and
3290 * [metadata] can be `null` if the directive does not have the corresponding
3291 * attribute.
3292 */
3293 DirectiveImpl(Comment comment, List<Annotation> metadata)
3294 : super(comment, metadata);
3295 }
3296
3297 /**
3298 * A do statement.
3299 *
3300 * > doStatement ::=
3301 * > 'do' [Statement] 'while' '(' [Expression] ')' ';'
3302 */
3303 class DoStatementImpl extends StatementImpl implements DoStatement {
3304 /**
3305 * The token representing the 'do' keyword.
3306 */
3307 Token doKeyword;
3308
3309 /**
3310 * The body of the loop.
3311 */
3312 Statement _body;
3313
3314 /**
3315 * The token representing the 'while' keyword.
3316 */
3317 Token whileKeyword;
3318
3319 /**
3320 * The left parenthesis.
3321 */
3322 Token leftParenthesis;
3323
3324 /**
3325 * The condition that determines when the loop will terminate.
3326 */
3327 Expression _condition;
3328
3329 /**
3330 * The right parenthesis.
3331 */
3332 Token rightParenthesis;
3333
3334 /**
3335 * The semicolon terminating the statement.
3336 */
3337 Token semicolon;
3338
3339 /**
3340 * Initialize a newly created do loop.
3341 */
3342 DoStatementImpl(
3343 this.doKeyword,
3344 Statement body,
3345 this.whileKeyword,
3346 this.leftParenthesis,
3347 Expression condition,
3348 this.rightParenthesis,
3349 this.semicolon) {
3350 _body = _becomeParentOf(body);
3351 _condition = _becomeParentOf(condition);
3352 }
3353
3354 @override
3355 Token get beginToken => doKeyword;
3356
3357 @override
3358 Statement get body => _body;
3359
3360 @override
3361 void set body(Statement statement) {
3362 _body = _becomeParentOf(statement);
3363 }
3364
3365 @override
3366 Iterable get childEntities => new ChildEntities()
3367 ..add(doKeyword)
3368 ..add(_body)
3369 ..add(whileKeyword)
3370 ..add(leftParenthesis)
3371 ..add(_condition)
3372 ..add(rightParenthesis)
3373 ..add(semicolon);
3374
3375 @override
3376 Expression get condition => _condition;
3377
3378 @override
3379 void set condition(Expression expression) {
3380 _condition = _becomeParentOf(expression);
3381 }
3382
3383 @override
3384 Token get endToken => semicolon;
3385
3386 @override
3387 accept(AstVisitor visitor) => visitor.visitDoStatement(this);
3388
3389 @override
3390 void visitChildren(AstVisitor visitor) {
3391 _safelyVisitChild(_body, visitor);
3392 _safelyVisitChild(_condition, visitor);
3393 }
3394 }
3395
3396 /**
3397 * A dotted name, used in a configuration within an import or export directive.
3398 *
3399 * > dottedName ::=
3400 * > [SimpleIdentifier] ('.' [SimpleIdentifier])*
3401 */
3402 class DottedNameImpl extends AstNodeImpl implements DottedName {
3403 /**
3404 * The components of the identifier.
3405 */
3406 NodeList<SimpleIdentifier> _components;
3407
3408 /**
3409 * Initialize a newly created dotted name.
3410 */
3411 DottedNameImpl(List<SimpleIdentifier> components) {
3412 _components = new NodeList<SimpleIdentifier>(this, components);
3413 }
3414
3415 @override
3416 Token get beginToken => _components.beginToken;
3417
3418 @override
3419 // TODO(paulberry): add "." tokens.
3420 Iterable get childEntities => new ChildEntities()..addAll(_components);
3421
3422 @override
3423 NodeList<SimpleIdentifier> get components => _components;
3424
3425 @override
3426 Token get endToken => _components.endToken;
3427
3428 @override
3429 accept(AstVisitor visitor) => visitor.visitDottedName(this);
3430
3431 @override
3432 void visitChildren(AstVisitor visitor) {
3433 _components.accept(visitor);
3434 }
3435 }
3436
3437 /**
3438 * A floating point literal expression.
3439 *
3440 * > doubleLiteral ::=
3441 * > decimalDigit+ ('.' decimalDigit*)? exponent?
3442 * > | '.' decimalDigit+ exponent?
3443 * >
3444 * > exponent ::=
3445 * > ('e' | 'E') ('+' | '-')? decimalDigit+
3446 */
3447 class DoubleLiteralImpl extends LiteralImpl implements DoubleLiteral {
3448 /**
3449 * The token representing the literal.
3450 */
3451 Token literal;
3452
3453 /**
3454 * The value of the literal.
3455 */
3456 double value;
3457
3458 /**
3459 * Initialize a newly created floating point literal.
3460 */
3461 DoubleLiteralImpl(this.literal, this.value);
3462
3463 @override
3464 Token get beginToken => literal;
3465
3466 @override
3467 Iterable get childEntities => new ChildEntities()..add(literal);
3468
3469 @override
3470 Token get endToken => literal;
3471
3472 @override
3473 accept(AstVisitor visitor) => visitor.visitDoubleLiteral(this);
3474
3475 @override
3476 void visitChildren(AstVisitor visitor) {
3477 // There are no children to visit.
3478 }
3479 }
3480
3481 /**
3482 * An empty function body, which can only appear in constructors or abstract
3483 * methods.
3484 *
3485 * > emptyFunctionBody ::=
3486 * > ';'
3487 */
3488 class EmptyFunctionBodyImpl extends FunctionBodyImpl
3489 implements EmptyFunctionBody {
3490 /**
3491 * The token representing the semicolon that marks the end of the function
3492 * body.
3493 */
3494 Token semicolon;
3495
3496 /**
3497 * Initialize a newly created function body.
3498 */
3499 EmptyFunctionBodyImpl(this.semicolon);
3500
3501 @override
3502 Token get beginToken => semicolon;
3503
3504 @override
3505 Iterable get childEntities => new ChildEntities()..add(semicolon);
3506
3507 @override
3508 Token get endToken => semicolon;
3509
3510 @override
3511 accept(AstVisitor visitor) => visitor.visitEmptyFunctionBody(this);
3512
3513 @override
3514 void visitChildren(AstVisitor visitor) {
3515 // Empty function bodies have no children.
3516 }
3517 }
3518
3519 /**
3520 * An empty statement.
3521 *
3522 * > emptyStatement ::=
3523 * > ';'
3524 */
3525 class EmptyStatementImpl extends StatementImpl implements EmptyStatement {
3526 /**
3527 * The semicolon terminating the statement.
3528 */
3529 Token semicolon;
3530
3531 /**
3532 * Initialize a newly created empty statement.
3533 */
3534 EmptyStatementImpl(this.semicolon);
3535
3536 @override
3537 Token get beginToken => semicolon;
3538
3539 @override
3540 Iterable get childEntities => new ChildEntities()..add(semicolon);
3541
3542 @override
3543 Token get endToken => semicolon;
3544
3545 @override
3546 accept(AstVisitor visitor) => visitor.visitEmptyStatement(this);
3547
3548 @override
3549 void visitChildren(AstVisitor visitor) {
3550 // There are no children to visit.
3551 }
3552 }
3553
3554 /**
3555 * The declaration of an enum constant.
3556 */
3557 class EnumConstantDeclarationImpl extends DeclarationImpl
3558 implements EnumConstantDeclaration {
3559 /**
3560 * The name of the constant.
3561 */
3562 SimpleIdentifier _name;
3563
3564 /**
3565 * Initialize a newly created enum constant declaration. Either or both of the
3566 * [comment] and [metadata] can be `null` if the constant does not have the
3567 * corresponding attribute. (Technically, enum constants cannot have metadata,
3568 * but we allow it for consistency.)
3569 */
3570 EnumConstantDeclarationImpl(
3571 Comment comment, List<Annotation> metadata, SimpleIdentifier name)
3572 : super(comment, metadata) {
3573 _name = _becomeParentOf(name);
3574 }
3575
3576 @override
3577 Iterable get childEntities => super._childEntities..add(_name);
3578
3579 @override
3580 FieldElement get element =>
3581 _name == null ? null : (_name.staticElement as FieldElement);
3582
3583 @override
3584 Token get endToken => _name.endToken;
3585
3586 @override
3587 Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
3588
3589 @override
3590 SimpleIdentifier get name => _name;
3591
3592 @override
3593 void set name(SimpleIdentifier name) {
3594 _name = _becomeParentOf(name);
3595 }
3596
3597 @override
3598 accept(AstVisitor visitor) => visitor.visitEnumConstantDeclaration(this);
3599
3600 @override
3601 void visitChildren(AstVisitor visitor) {
3602 super.visitChildren(visitor);
3603 _safelyVisitChild(_name, visitor);
3604 }
3605 }
3606
3607 /**
3608 * The declaration of an enumeration.
3609 *
3610 * > enumType ::=
3611 * > metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier] (',' [SimpleI dentifier])* (',')? '}'
3612 */
3613 class EnumDeclarationImpl extends NamedCompilationUnitMemberImpl
3614 implements EnumDeclaration {
3615 /**
3616 * The 'enum' keyword.
3617 */
3618 Token enumKeyword;
3619
3620 /**
3621 * The left curly bracket.
3622 */
3623 Token leftBracket;
3624
3625 /**
3626 * The enumeration constants being declared.
3627 */
3628 NodeList<EnumConstantDeclaration> _constants;
3629
3630 /**
3631 * The right curly bracket.
3632 */
3633 Token rightBracket;
3634
3635 /**
3636 * Initialize a newly created enumeration declaration. Either or both of the
3637 * [comment] and [metadata] can be `null` if the declaration does not have the
3638 * corresponding attribute. The list of [constants] must contain at least one
3639 * value.
3640 */
3641 EnumDeclarationImpl(
3642 Comment comment,
3643 List<Annotation> metadata,
3644 this.enumKeyword,
3645 SimpleIdentifier name,
3646 this.leftBracket,
3647 List<EnumConstantDeclaration> constants,
3648 this.rightBracket)
3649 : super(comment, metadata, name) {
3650 _constants = new NodeList<EnumConstantDeclaration>(this, constants);
3651 }
3652
3653 @override
3654 // TODO(brianwilkerson) Add commas?
3655 Iterable get childEntities => super._childEntities
3656 ..add(enumKeyword)
3657 ..add(_name)
3658 ..add(leftBracket)
3659 ..addAll(_constants)
3660 ..add(rightBracket);
3661
3662 @override
3663 NodeList<EnumConstantDeclaration> get constants => _constants;
3664
3665 @override
3666 ClassElement get element =>
3667 _name != null ? (_name.staticElement as ClassElement) : null;
3668
3669 @override
3670 Token get endToken => rightBracket;
3671
3672 @override
3673 Token get firstTokenAfterCommentAndMetadata => enumKeyword;
3674
3675 @override
3676 accept(AstVisitor visitor) => visitor.visitEnumDeclaration(this);
3677
3678 @override
3679 void visitChildren(AstVisitor visitor) {
3680 super.visitChildren(visitor);
3681 _safelyVisitChild(_name, visitor);
3682 _constants.accept(visitor);
3683 }
3684 }
3685
3686 /**
3687 * Ephemeral identifiers are created as needed to mimic the presence of an empty
3688 * identifier.
3689 */
3690 class EphemeralIdentifier extends SimpleIdentifierImpl {
3691 EphemeralIdentifier(AstNode parent, int location)
3692 : super(new StringToken(TokenType.IDENTIFIER, "", location)) {
3693 (parent as AstNodeImpl)._becomeParentOf(this);
3694 }
3695 }
3696
3697 /**
3698 * An export directive.
3699 *
3700 * > exportDirective ::=
3701 * > [Annotation] 'export' [StringLiteral] [Combinator]* ';'
3702 */
3703 class ExportDirectiveImpl extends NamespaceDirectiveImpl
3704 implements ExportDirective {
3705 /**
3706 * Initialize a newly created export directive. Either or both of the
3707 * [comment] and [metadata] can be `null` if the directive does not have the
3708 * corresponding attribute. The list of [combinators] can be `null` if there
3709 * are no combinators.
3710 */
3711 ExportDirectiveImpl(
3712 Comment comment,
3713 List<Annotation> metadata,
3714 Token keyword,
3715 StringLiteral libraryUri,
3716 List<Configuration> configurations,
3717 List<Combinator> combinators,
3718 Token semicolon)
3719 : super(comment, metadata, keyword, libraryUri, configurations,
3720 combinators, semicolon);
3721
3722 @override
3723 Iterable get childEntities => super._childEntities
3724 ..add(_uri)
3725 ..addAll(combinators)
3726 ..add(semicolon);
3727
3728 @override
3729 ExportElement get element => super.element as ExportElement;
3730
3731 @override
3732 LibraryElement get uriElement {
3733 if (element != null) {
3734 return element.exportedLibrary;
3735 }
3736 return null;
3737 }
3738
3739 @override
3740 accept(AstVisitor visitor) => visitor.visitExportDirective(this);
3741
3742 @override
3743 void visitChildren(AstVisitor visitor) {
3744 super.visitChildren(visitor);
3745 combinators.accept(visitor);
3746 }
3747 }
3748
3749 /**
3750 * A function body consisting of a single expression.
3751 *
3752 * > expressionFunctionBody ::=
3753 * > 'async'? '=>' [Expression] ';'
3754 */
3755 class ExpressionFunctionBodyImpl extends FunctionBodyImpl
3756 implements ExpressionFunctionBody {
3757 /**
3758 * The token representing the 'async' keyword, or `null` if there is no such
3759 * keyword.
3760 */
3761 Token keyword;
3762
3763 /**
3764 * The token introducing the expression that represents the body of the
3765 * function.
3766 */
3767 Token functionDefinition;
3768
3769 /**
3770 * The expression representing the body of the function.
3771 */
3772 Expression _expression;
3773
3774 /**
3775 * The semicolon terminating the statement.
3776 */
3777 Token semicolon;
3778
3779 /**
3780 * Initialize a newly created function body consisting of a block of
3781 * statements. The [keyword] can be `null` if the function body is not an
3782 * async function body.
3783 */
3784 ExpressionFunctionBodyImpl(this.keyword, this.functionDefinition,
3785 Expression expression, this.semicolon) {
3786 _expression = _becomeParentOf(expression);
3787 }
3788
3789 @override
3790 Token get beginToken {
3791 if (keyword != null) {
3792 return keyword;
3793 }
3794 return functionDefinition;
3795 }
3796
3797 @override
3798 Iterable get childEntities => new ChildEntities()
3799 ..add(keyword)
3800 ..add(functionDefinition)
3801 ..add(_expression)
3802 ..add(semicolon);
3803
3804 @override
3805 Token get endToken {
3806 if (semicolon != null) {
3807 return semicolon;
3808 }
3809 return _expression.endToken;
3810 }
3811
3812 @override
3813 Expression get expression => _expression;
3814
3815 @override
3816 void set expression(Expression expression) {
3817 _expression = _becomeParentOf(expression);
3818 }
3819
3820 @override
3821 bool get isAsynchronous => keyword != null;
3822
3823 @override
3824 bool get isSynchronous => keyword == null;
3825
3826 @override
3827 accept(AstVisitor visitor) => visitor.visitExpressionFunctionBody(this);
3828
3829 @override
3830 void visitChildren(AstVisitor visitor) {
3831 _safelyVisitChild(_expression, visitor);
3832 }
3833 }
3834
3835 /**
3836 * A node that represents an expression.
3837 *
3838 * > expression ::=
3839 * > [AssignmentExpression]
3840 * > | [ConditionalExpression] cascadeSection*
3841 * > | [ThrowExpression]
3842 */
3843 abstract class ExpressionImpl extends AstNodeImpl implements Expression {
3844 /**
3845 * The static type of this expression, or `null` if the AST structure has not
3846 * been resolved.
3847 */
3848 DartType staticType;
3849
3850 /**
3851 * The propagated type of this expression, or `null` if type propagation has
3852 * not been performed on the AST structure.
3853 */
3854 DartType propagatedType;
3855
3856 /**
3857 * Return the best parameter element information available for this
3858 * expression. If type propagation was able to find a better parameter element
3859 * than static analysis, that type will be returned. Otherwise, the result of
3860 * static analysis will be returned.
3861 */
3862 ParameterElement get bestParameterElement {
3863 ParameterElement propagatedElement = propagatedParameterElement;
3864 if (propagatedElement != null) {
3865 return propagatedElement;
3866 }
3867 return staticParameterElement;
3868 }
3869
3870 @override
3871 DartType get bestType {
3872 if (propagatedType != null) {
3873 return propagatedType;
3874 } else if (staticType != null) {
3875 return staticType;
3876 }
3877 return DynamicTypeImpl.instance;
3878 }
3879
3880 @override
3881 bool get isAssignable => false;
3882
3883 @override
3884 ParameterElement get propagatedParameterElement {
3885 AstNode parent = this.parent;
3886 if (parent is ArgumentListImpl) {
3887 return parent._getPropagatedParameterElementFor(this);
3888 } else if (parent is IndexExpressionImpl) {
3889 if (identical(parent.index, this)) {
3890 return parent._propagatedParameterElementForIndex;
3891 }
3892 } else if (parent is BinaryExpressionImpl) {
3893 if (identical(parent.rightOperand, this)) {
3894 return parent._propagatedParameterElementForRightOperand;
3895 }
3896 } else if (parent is AssignmentExpressionImpl) {
3897 if (identical(parent.rightHandSide, this)) {
3898 return parent._propagatedParameterElementForRightHandSide;
3899 }
3900 } else if (parent is PrefixExpressionImpl) {
3901 return parent._propagatedParameterElementForOperand;
3902 } else if (parent is PostfixExpressionImpl) {
3903 return parent._propagatedParameterElementForOperand;
3904 }
3905 return null;
3906 }
3907
3908 @override
3909 ParameterElement get staticParameterElement {
3910 AstNode parent = this.parent;
3911 if (parent is ArgumentListImpl) {
3912 return parent._getStaticParameterElementFor(this);
3913 } else if (parent is IndexExpressionImpl) {
3914 if (identical(parent.index, this)) {
3915 return parent._staticParameterElementForIndex;
3916 }
3917 } else if (parent is BinaryExpressionImpl) {
3918 if (identical(parent.rightOperand, this)) {
3919 return parent._staticParameterElementForRightOperand;
3920 }
3921 } else if (parent is AssignmentExpressionImpl) {
3922 if (identical(parent.rightHandSide, this)) {
3923 return parent._staticParameterElementForRightHandSide;
3924 }
3925 } else if (parent is PrefixExpressionImpl) {
3926 return parent._staticParameterElementForOperand;
3927 } else if (parent is PostfixExpressionImpl) {
3928 return parent._staticParameterElementForOperand;
3929 }
3930 return null;
3931 }
3932 }
3933
3934 /**
3935 * An expression used as a statement.
3936 *
3937 * > expressionStatement ::=
3938 * > [Expression]? ';'
3939 */
3940 class ExpressionStatementImpl extends StatementImpl
3941 implements ExpressionStatement {
3942 /**
3943 * The expression that comprises the statement.
3944 */
3945 Expression _expression;
3946
3947 /**
3948 * The semicolon terminating the statement, or `null` if the expression is a
3949 * function expression and therefore isn't followed by a semicolon.
3950 */
3951 Token semicolon;
3952
3953 /**
3954 * Initialize a newly created expression statement.
3955 */
3956 ExpressionStatementImpl(Expression expression, this.semicolon) {
3957 _expression = _becomeParentOf(expression);
3958 }
3959
3960 @override
3961 Token get beginToken => _expression.beginToken;
3962
3963 @override
3964 Iterable get childEntities =>
3965 new ChildEntities()..add(_expression)..add(semicolon);
3966
3967 @override
3968 Token get endToken {
3969 if (semicolon != null) {
3970 return semicolon;
3971 }
3972 return _expression.endToken;
3973 }
3974
3975 @override
3976 Expression get expression => _expression;
3977
3978 @override
3979 void set expression(Expression expression) {
3980 _expression = _becomeParentOf(expression);
3981 }
3982
3983 @override
3984 bool get isSynthetic => _expression.isSynthetic && semicolon.isSynthetic;
3985
3986 @override
3987 accept(AstVisitor visitor) => visitor.visitExpressionStatement(this);
3988
3989 @override
3990 void visitChildren(AstVisitor visitor) {
3991 _safelyVisitChild(_expression, visitor);
3992 }
3993 }
3994
3995 /**
3996 * The "extends" clause in a class declaration.
3997 *
3998 * > extendsClause ::=
3999 * > 'extends' [TypeName]
4000 */
4001 class ExtendsClauseImpl extends AstNodeImpl implements ExtendsClause {
4002 /**
4003 * The token representing the 'extends' keyword.
4004 */
4005 Token extendsKeyword;
4006
4007 /**
4008 * The name of the class that is being extended.
4009 */
4010 TypeName _superclass;
4011
4012 /**
4013 * Initialize a newly created extends clause.
4014 */
4015 ExtendsClauseImpl(this.extendsKeyword, TypeName superclass) {
4016 _superclass = _becomeParentOf(superclass);
4017 }
4018
4019 @override
4020 Token get beginToken => extendsKeyword;
4021
4022 @override
4023 Iterable get childEntities =>
4024 new ChildEntities()..add(extendsKeyword)..add(_superclass);
4025
4026 @override
4027 Token get endToken => _superclass.endToken;
4028
4029 @override
4030 TypeName get superclass => _superclass;
4031
4032 @override
4033 void set superclass(TypeName name) {
4034 _superclass = _becomeParentOf(name);
4035 }
4036
4037 @override
4038 accept(AstVisitor visitor) => visitor.visitExtendsClause(this);
4039
4040 @override
4041 void visitChildren(AstVisitor visitor) {
4042 _safelyVisitChild(_superclass, visitor);
4043 }
4044 }
4045
4046 /**
4047 * The declaration of one or more fields of the same type.
4048 *
4049 * > fieldDeclaration ::=
4050 * > 'static'? [VariableDeclarationList] ';'
4051 */
4052 class FieldDeclarationImpl extends ClassMemberImpl implements FieldDeclaration {
4053 /**
4054 * The token representing the 'static' keyword, or `null` if the fields are
4055 * not static.
4056 */
4057 Token staticKeyword;
4058
4059 /**
4060 * The fields being declared.
4061 */
4062 VariableDeclarationList _fieldList;
4063
4064 /**
4065 * The semicolon terminating the declaration.
4066 */
4067 Token semicolon;
4068
4069 /**
4070 * Initialize a newly created field declaration. Either or both of the
4071 * [comment] and [metadata] can be `null` if the declaration does not have the
4072 * corresponding attribute. The [staticKeyword] can be `null` if the field is
4073 * not a static field.
4074 */
4075 FieldDeclarationImpl(Comment comment, List<Annotation> metadata,
4076 this.staticKeyword, VariableDeclarationList fieldList, this.semicolon)
4077 : super(comment, metadata) {
4078 _fieldList = _becomeParentOf(fieldList);
4079 }
4080
4081 @override
4082 Iterable get childEntities =>
4083 super._childEntities..add(staticKeyword)..add(_fieldList)..add(semicolon);
4084
4085 @override
4086 Element get element => null;
4087
4088 @override
4089 Token get endToken => semicolon;
4090
4091 @override
4092 VariableDeclarationList get fields => _fieldList;
4093
4094 @override
4095 void set fields(VariableDeclarationList fields) {
4096 _fieldList = _becomeParentOf(fields);
4097 }
4098
4099 @override
4100 Token get firstTokenAfterCommentAndMetadata {
4101 if (staticKeyword != null) {
4102 return staticKeyword;
4103 }
4104 return _fieldList.beginToken;
4105 }
4106
4107 @override
4108 bool get isStatic => staticKeyword != null;
4109
4110 @override
4111 accept(AstVisitor visitor) => visitor.visitFieldDeclaration(this);
4112
4113 @override
4114 void visitChildren(AstVisitor visitor) {
4115 super.visitChildren(visitor);
4116 _safelyVisitChild(_fieldList, visitor);
4117 }
4118 }
4119
4120 /**
4121 * A field formal parameter.
4122 *
4123 * > fieldFormalParameter ::=
4124 * > ('final' [TypeName] | 'const' [TypeName] | 'var' | [TypeName])?
4125 * > 'this' '.' [SimpleIdentifier] ([TypeParameterList]? [FormalParameterLis t])?
4126 */
4127 class FieldFormalParameterImpl extends NormalFormalParameterImpl
4128 implements FieldFormalParameter {
4129 /**
4130 * The token representing either the 'final', 'const' or 'var' keyword, or
4131 * `null` if no keyword was used.
4132 */
4133 Token keyword;
4134
4135 /**
4136 * The name of the declared type of the parameter, or `null` if the parameter
4137 * does not have a declared type.
4138 */
4139 TypeName _type;
4140
4141 /**
4142 * The token representing the 'this' keyword.
4143 */
4144 Token thisKeyword;
4145
4146 /**
4147 * The token representing the period.
4148 */
4149 Token period;
4150
4151 /**
4152 * The type parameters associated with the method, or `null` if the method is
4153 * not a generic method.
4154 */
4155 TypeParameterList _typeParameters;
4156
4157 /**
4158 * The parameters of the function-typed parameter, or `null` if this is not a
4159 * function-typed field formal parameter.
4160 */
4161 FormalParameterList _parameters;
4162
4163 /**
4164 * Initialize a newly created formal parameter. Either or both of the
4165 * [comment] and [metadata] can be `null` if the parameter does not have the
4166 * corresponding attribute. The [keyword] can be `null` if there is a type.
4167 * The [type] must be `null` if the keyword is 'var'. The [thisKeyword] and
4168 * [period] can be `null` if the keyword 'this' was not provided. The
4169 * [parameters] can be `null` if this is not a function-typed field formal
4170 * parameter.
4171 */
4172 FieldFormalParameterImpl(
4173 Comment comment,
4174 List<Annotation> metadata,
4175 this.keyword,
4176 TypeName type,
4177 this.thisKeyword,
4178 this.period,
4179 SimpleIdentifier identifier,
4180 TypeParameterList typeParameters,
4181 FormalParameterList parameters)
4182 : super(comment, metadata, identifier) {
4183 _type = _becomeParentOf(type);
4184 _typeParameters = _becomeParentOf(typeParameters);
4185 _parameters = _becomeParentOf(parameters);
4186 }
4187
4188 @override
4189 Token get beginToken {
4190 if (keyword != null) {
4191 return keyword;
4192 } else if (_type != null) {
4193 return _type.beginToken;
4194 }
4195 return thisKeyword;
4196 }
4197
4198 @override
4199 Iterable get childEntities => super._childEntities
4200 ..add(keyword)
4201 ..add(_type)
4202 ..add(thisKeyword)
4203 ..add(period)
4204 ..add(identifier)
4205 ..add(_parameters);
4206
4207 @override
4208 Token get endToken {
4209 if (_parameters != null) {
4210 return _parameters.endToken;
4211 }
4212 return identifier.endToken;
4213 }
4214
4215 @override
4216 bool get isConst =>
4217 (keyword is KeywordToken) &&
4218 (keyword as KeywordToken).keyword == Keyword.CONST;
4219
4220 @override
4221 bool get isFinal =>
4222 (keyword is KeywordToken) &&
4223 (keyword as KeywordToken).keyword == Keyword.FINAL;
4224
4225 @override
4226 FormalParameterList get parameters => _parameters;
4227
4228 @override
4229 void set parameters(FormalParameterList parameters) {
4230 _parameters = _becomeParentOf(parameters);
4231 }
4232
4233 @override
4234 TypeName get type => _type;
4235
4236 @override
4237 void set type(TypeName typeName) {
4238 _type = _becomeParentOf(typeName);
4239 }
4240
4241 @override
4242 TypeParameterList get typeParameters => _typeParameters;
4243
4244 @override
4245 void set typeParameters(TypeParameterList typeParameters) {
4246 _typeParameters = _becomeParentOf(typeParameters);
4247 }
4248
4249 @override
4250 accept(AstVisitor visitor) => visitor.visitFieldFormalParameter(this);
4251
4252 @override
4253 void visitChildren(AstVisitor visitor) {
4254 super.visitChildren(visitor);
4255 _safelyVisitChild(_type, visitor);
4256 _safelyVisitChild(identifier, visitor);
4257 _safelyVisitChild(_typeParameters, visitor);
4258 _safelyVisitChild(_parameters, visitor);
4259 }
4260 }
4261
4262 /**
4263 * A for-each statement.
4264 *
4265 * > forEachStatement ::=
4266 * > 'await'? 'for' '(' [DeclaredIdentifier] 'in' [Expression] ')' [Block]
4267 * > | 'await'? 'for' '(' [SimpleIdentifier] 'in' [Expression] ')' [Block]
4268 */
4269 class ForEachStatementImpl extends StatementImpl implements ForEachStatement {
4270 /**
4271 * The token representing the 'await' keyword, or `null` if there is no
4272 * 'await' keyword.
4273 */
4274 Token awaitKeyword;
4275
4276 /**
4277 * The token representing the 'for' keyword.
4278 */
4279 Token forKeyword;
4280
4281 /**
4282 * The left parenthesis.
4283 */
4284 Token leftParenthesis;
4285
4286 /**
4287 * The declaration of the loop variable, or `null` if the loop variable is a
4288 * simple identifier.
4289 */
4290 DeclaredIdentifier _loopVariable;
4291
4292 /**
4293 * The loop variable, or `null` if the loop variable is declared in the 'for'.
4294 */
4295 SimpleIdentifier _identifier;
4296
4297 /**
4298 * The token representing the 'in' keyword.
4299 */
4300 Token inKeyword;
4301
4302 /**
4303 * The expression evaluated to produce the iterator.
4304 */
4305 Expression _iterable;
4306
4307 /**
4308 * The right parenthesis.
4309 */
4310 Token rightParenthesis;
4311
4312 /**
4313 * The body of the loop.
4314 */
4315 Statement _body;
4316
4317 /**
4318 * Initialize a newly created for-each statement whose loop control variable
4319 * is declared internally (in the for-loop part). The [awaitKeyword] can be
4320 * `null` if this is not an asynchronous for loop.
4321 */
4322 ForEachStatementImpl.withDeclaration(
4323 this.awaitKeyword,
4324 this.forKeyword,
4325 this.leftParenthesis,
4326 DeclaredIdentifier loopVariable,
4327 this.inKeyword,
4328 Expression iterator,
4329 this.rightParenthesis,
4330 Statement body) {
4331 _loopVariable = _becomeParentOf(loopVariable);
4332 _iterable = _becomeParentOf(iterator);
4333 _body = _becomeParentOf(body);
4334 }
4335
4336 /**
4337 * Initialize a newly created for-each statement whose loop control variable
4338 * is declared outside the for loop. The [awaitKeyword] can be `null` if this
4339 * is not an asynchronous for loop.
4340 */
4341 ForEachStatementImpl.withReference(
4342 this.awaitKeyword,
4343 this.forKeyword,
4344 this.leftParenthesis,
4345 SimpleIdentifier identifier,
4346 this.inKeyword,
4347 Expression iterator,
4348 this.rightParenthesis,
4349 Statement body) {
4350 _identifier = _becomeParentOf(identifier);
4351 _iterable = _becomeParentOf(iterator);
4352 _body = _becomeParentOf(body);
4353 }
4354
4355 @override
4356 Token get beginToken => forKeyword;
4357
4358 @override
4359 Statement get body => _body;
4360
4361 @override
4362 void set body(Statement statement) {
4363 _body = _becomeParentOf(statement);
4364 }
4365
4366 @override
4367 Iterable get childEntities => new ChildEntities()
4368 ..add(awaitKeyword)
4369 ..add(forKeyword)
4370 ..add(leftParenthesis)
4371 ..add(_loopVariable)
4372 ..add(_identifier)
4373 ..add(inKeyword)
4374 ..add(_iterable)
4375 ..add(rightParenthesis)
4376 ..add(_body);
4377
4378 @override
4379 Token get endToken => _body.endToken;
4380
4381 @override
4382 SimpleIdentifier get identifier => _identifier;
4383
4384 @override
4385 void set identifier(SimpleIdentifier identifier) {
4386 _identifier = _becomeParentOf(identifier);
4387 }
4388
4389 @override
4390 Expression get iterable => _iterable;
4391
4392 @override
4393 void set iterable(Expression expression) {
4394 _iterable = _becomeParentOf(expression);
4395 }
4396
4397 @override
4398 DeclaredIdentifier get loopVariable => _loopVariable;
4399
4400 @override
4401 void set loopVariable(DeclaredIdentifier variable) {
4402 _loopVariable = _becomeParentOf(variable);
4403 }
4404
4405 @override
4406 accept(AstVisitor visitor) => visitor.visitForEachStatement(this);
4407
4408 @override
4409 void visitChildren(AstVisitor visitor) {
4410 _safelyVisitChild(_loopVariable, visitor);
4411 _safelyVisitChild(_identifier, visitor);
4412 _safelyVisitChild(_iterable, visitor);
4413 _safelyVisitChild(_body, visitor);
4414 }
4415 }
4416
4417 /**
4418 * A node representing a parameter to a function.
4419 *
4420 * > formalParameter ::=
4421 * > [NormalFormalParameter]
4422 * > | [DefaultFormalParameter]
4423 */
4424 abstract class FormalParameterImpl extends AstNodeImpl
4425 implements FormalParameter {
4426 @override
4427 ParameterElement get element {
4428 SimpleIdentifier identifier = this.identifier;
4429 if (identifier == null) {
4430 return null;
4431 }
4432 return identifier.staticElement as ParameterElement;
4433 }
4434 }
4435
4436 /**
4437 * The formal parameter list of a method declaration, function declaration, or
4438 * function type alias.
4439 *
4440 * While the grammar requires all optional formal parameters to follow all of
4441 * the normal formal parameters and at most one grouping of optional formal
4442 * parameters, this class does not enforce those constraints. All parameters are
4443 * flattened into a single list, which can have any or all kinds of parameters
4444 * (normal, named, and positional) in any order.
4445 *
4446 * > formalParameterList ::=
4447 * > '(' ')'
4448 * > | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
4449 * > | '(' optionalFormalParameters ')'
4450 * >
4451 * > normalFormalParameters ::=
4452 * > [NormalFormalParameter] (',' [NormalFormalParameter])*
4453 * >
4454 * > optionalFormalParameters ::=
4455 * > optionalPositionalFormalParameters
4456 * > | namedFormalParameters
4457 * >
4458 * > optionalPositionalFormalParameters ::=
4459 * > '[' [DefaultFormalParameter] (',' [DefaultFormalParameter])* ']'
4460 * >
4461 * > namedFormalParameters ::=
4462 * > '{' [DefaultFormalParameter] (',' [DefaultFormalParameter])* '}'
4463 */
4464 class FormalParameterListImpl extends AstNodeImpl
4465 implements FormalParameterList {
4466 /**
4467 * The left parenthesis.
4468 */
4469 Token leftParenthesis;
4470
4471 /**
4472 * The parameters associated with the method.
4473 */
4474 NodeList<FormalParameter> _parameters;
4475
4476 /**
4477 * The left square bracket ('[') or left curly brace ('{') introducing the
4478 * optional parameters, or `null` if there are no optional parameters.
4479 */
4480 Token leftDelimiter;
4481
4482 /**
4483 * The right square bracket (']') or right curly brace ('}') terminating the
4484 * optional parameters, or `null` if there are no optional parameters.
4485 */
4486 Token rightDelimiter;
4487
4488 /**
4489 * The right parenthesis.
4490 */
4491 Token rightParenthesis;
4492
4493 /**
4494 * Initialize a newly created parameter list. The list of [parameters] can be
4495 * `null` if there are no parameters. The [leftDelimiter] and [rightDelimiter]
4496 * can be `null` if there are no optional parameters.
4497 */
4498 FormalParameterListImpl(
4499 this.leftParenthesis,
4500 List<FormalParameter> parameters,
4501 this.leftDelimiter,
4502 this.rightDelimiter,
4503 this.rightParenthesis) {
4504 _parameters = new NodeList<FormalParameter>(this, parameters);
4505 }
4506
4507 @override
4508 Token get beginToken => leftParenthesis;
4509
4510 @override
4511 Iterable get childEntities {
4512 // TODO(paulberry): include commas.
4513 ChildEntities result = new ChildEntities()..add(leftParenthesis);
4514 bool leftDelimiterNeeded = leftDelimiter != null;
4515 for (FormalParameter parameter in _parameters) {
4516 if (leftDelimiterNeeded && leftDelimiter.offset < parameter.offset) {
4517 result.add(leftDelimiter);
4518 leftDelimiterNeeded = false;
4519 }
4520 result.add(parameter);
4521 }
4522 return result..add(rightDelimiter)..add(rightParenthesis);
4523 }
4524
4525 @override
4526 Token get endToken => rightParenthesis;
4527
4528 @override
4529 List<ParameterElement> get parameterElements {
4530 int count = _parameters.length;
4531 List<ParameterElement> types = new List<ParameterElement>(count);
4532 for (int i = 0; i < count; i++) {
4533 types[i] = _parameters[i].element;
4534 }
4535 return types;
4536 }
4537
4538 @override
4539 NodeList<FormalParameter> get parameters => _parameters;
4540
4541 @override
4542 accept(AstVisitor visitor) => visitor.visitFormalParameterList(this);
4543
4544 @override
4545 void visitChildren(AstVisitor visitor) {
4546 _parameters.accept(visitor);
4547 }
4548 }
4549
4550 /**
4551 * A for statement.
4552 *
4553 * > forStatement ::=
4554 * > 'for' '(' forLoopParts ')' [Statement]
4555 * >
4556 * > forLoopParts ::=
4557 * > forInitializerStatement ';' [Expression]? ';' [Expression]?
4558 * >
4559 * > forInitializerStatement ::=
4560 * > [DefaultFormalParameter]
4561 * > | [Expression]?
4562 */
4563 class ForStatementImpl extends StatementImpl implements ForStatement {
4564 /**
4565 * The token representing the 'for' keyword.
4566 */
4567 Token forKeyword;
4568
4569 /**
4570 * The left parenthesis.
4571 */
4572 Token leftParenthesis;
4573
4574 /**
4575 * The declaration of the loop variables, or `null` if there are no variables.
4576 * Note that a for statement cannot have both a variable list and an
4577 * initialization expression, but can validly have neither.
4578 */
4579 VariableDeclarationList _variableList;
4580
4581 /**
4582 * The initialization expression, or `null` if there is no initialization
4583 * expression. Note that a for statement cannot have both a variable list and
4584 * an initialization expression, but can validly have neither.
4585 */
4586 Expression _initialization;
4587
4588 /**
4589 * The semicolon separating the initializer and the condition.
4590 */
4591 Token leftSeparator;
4592
4593 /**
4594 * The condition used to determine when to terminate the loop, or `null` if
4595 * there is no condition.
4596 */
4597 Expression _condition;
4598
4599 /**
4600 * The semicolon separating the condition and the updater.
4601 */
4602 Token rightSeparator;
4603
4604 /**
4605 * The list of expressions run after each execution of the loop body.
4606 */
4607 NodeList<Expression> _updaters;
4608
4609 /**
4610 * The right parenthesis.
4611 */
4612 Token rightParenthesis;
4613
4614 /**
4615 * The body of the loop.
4616 */
4617 Statement _body;
4618
4619 /**
4620 * Initialize a newly created for statement. Either the [variableList] or the
4621 * [initialization] must be `null`. Either the [condition] and the list of
4622 * [updaters] can be `null` if the loop does not have the corresponding
4623 * attribute.
4624 */
4625 ForStatementImpl(
4626 this.forKeyword,
4627 this.leftParenthesis,
4628 VariableDeclarationList variableList,
4629 Expression initialization,
4630 this.leftSeparator,
4631 Expression condition,
4632 this.rightSeparator,
4633 List<Expression> updaters,
4634 this.rightParenthesis,
4635 Statement body) {
4636 _variableList = _becomeParentOf(variableList);
4637 _initialization = _becomeParentOf(initialization);
4638 _condition = _becomeParentOf(condition);
4639 _updaters = new NodeList<Expression>(this, updaters);
4640 _body = _becomeParentOf(body);
4641 }
4642
4643 @override
4644 Token get beginToken => forKeyword;
4645
4646 @override
4647 Statement get body => _body;
4648
4649 @override
4650 void set body(Statement statement) {
4651 _body = _becomeParentOf(statement);
4652 }
4653
4654 @override
4655 Iterable get childEntities => new ChildEntities()
4656 ..add(forKeyword)
4657 ..add(leftParenthesis)
4658 ..add(_variableList)
4659 ..add(_initialization)
4660 ..add(leftSeparator)
4661 ..add(_condition)
4662 ..add(rightSeparator)
4663 ..addAll(_updaters)
4664 ..add(rightParenthesis)
4665 ..add(_body);
4666
4667 @override
4668 Expression get condition => _condition;
4669
4670 @override
4671 void set condition(Expression expression) {
4672 _condition = _becomeParentOf(expression);
4673 }
4674
4675 @override
4676 Token get endToken => _body.endToken;
4677
4678 @override
4679 Expression get initialization => _initialization;
4680
4681 @override
4682 void set initialization(Expression initialization) {
4683 _initialization = _becomeParentOf(initialization);
4684 }
4685
4686 @override
4687 NodeList<Expression> get updaters => _updaters;
4688
4689 @override
4690 VariableDeclarationList get variables => _variableList;
4691
4692 @override
4693 void set variables(VariableDeclarationList variableList) {
4694 _variableList = _becomeParentOf(variableList);
4695 }
4696
4697 @override
4698 accept(AstVisitor visitor) => visitor.visitForStatement(this);
4699
4700 @override
4701 void visitChildren(AstVisitor visitor) {
4702 _safelyVisitChild(_variableList, visitor);
4703 _safelyVisitChild(_initialization, visitor);
4704 _safelyVisitChild(_condition, visitor);
4705 _updaters.accept(visitor);
4706 _safelyVisitChild(_body, visitor);
4707 }
4708 }
4709
4710 /**
4711 * A node representing the body of a function or method.
4712 *
4713 * > functionBody ::=
4714 * > [BlockFunctionBody]
4715 * > | [EmptyFunctionBody]
4716 * > | [ExpressionFunctionBody]
4717 */
4718 abstract class FunctionBodyImpl extends AstNodeImpl implements FunctionBody {
4719 /**
4720 * Return `true` if this function body is asynchronous.
4721 */
4722 bool get isAsynchronous => false;
4723
4724 /**
4725 * Return `true` if this function body is a generator.
4726 */
4727 bool get isGenerator => false;
4728
4729 /**
4730 * Return `true` if this function body is synchronous.
4731 */
4732 bool get isSynchronous => true;
4733
4734 /**
4735 * Return the token representing the 'async' or 'sync' keyword, or `null` if
4736 * there is no such keyword.
4737 */
4738 Token get keyword => null;
4739
4740 /**
4741 * Return the star following the 'async' or 'sync' keyword, or `null` if there
4742 * is no star.
4743 */
4744 Token get star => null;
4745 }
4746
4747 /**
4748 * A top-level declaration.
4749 *
4750 * > functionDeclaration ::=
4751 * > 'external' functionSignature
4752 * > | functionSignature [FunctionBody]
4753 * >
4754 * > functionSignature ::=
4755 * > [Type]? ('get' | 'set')? [SimpleIdentifier] [FormalParameterList]
4756 */
4757 class FunctionDeclarationImpl extends NamedCompilationUnitMemberImpl
4758 implements FunctionDeclaration {
4759 /**
4760 * The token representing the 'external' keyword, or `null` if this is not an
4761 * external function.
4762 */
4763 Token externalKeyword;
4764
4765 /**
4766 * The return type of the function, or `null` if no return type was declared.
4767 */
4768 TypeName _returnType;
4769
4770 /**
4771 * The token representing the 'get' or 'set' keyword, or `null` if this is a
4772 * function declaration rather than a property declaration.
4773 */
4774 Token propertyKeyword;
4775
4776 /**
4777 * The function expression being wrapped.
4778 */
4779 FunctionExpression _functionExpression;
4780
4781 /**
4782 * Initialize a newly created function declaration. Either or both of the
4783 * [comment] and [metadata] can be `null` if the function does not have the
4784 * corresponding attribute. The [externalKeyword] can be `null` if the
4785 * function is not an external function. The [returnType] can be `null` if no
4786 * return type was specified. The [propertyKeyword] can be `null` if the
4787 * function is neither a getter or a setter.
4788 */
4789 FunctionDeclarationImpl(
4790 Comment comment,
4791 List<Annotation> metadata,
4792 this.externalKeyword,
4793 TypeName returnType,
4794 this.propertyKeyword,
4795 SimpleIdentifier name,
4796 FunctionExpression functionExpression)
4797 : super(comment, metadata, name) {
4798 _returnType = _becomeParentOf(returnType);
4799 _functionExpression = _becomeParentOf(functionExpression);
4800 }
4801
4802 @override
4803 Iterable get childEntities => super._childEntities
4804 ..add(externalKeyword)
4805 ..add(_returnType)
4806 ..add(propertyKeyword)
4807 ..add(_name)
4808 ..add(_functionExpression);
4809
4810 @override
4811 ExecutableElement get element =>
4812 _name != null ? (_name.staticElement as ExecutableElement) : null;
4813
4814 @override
4815 Token get endToken => _functionExpression.endToken;
4816
4817 @override
4818 Token get firstTokenAfterCommentAndMetadata {
4819 if (externalKeyword != null) {
4820 return externalKeyword;
4821 } else if (_returnType != null) {
4822 return _returnType.beginToken;
4823 } else if (propertyKeyword != null) {
4824 return propertyKeyword;
4825 } else if (_name != null) {
4826 return _name.beginToken;
4827 }
4828 return _functionExpression.beginToken;
4829 }
4830
4831 @override
4832 FunctionExpression get functionExpression => _functionExpression;
4833
4834 @override
4835 void set functionExpression(FunctionExpression functionExpression) {
4836 _functionExpression = _becomeParentOf(functionExpression);
4837 }
4838
4839 @override
4840 bool get isGetter =>
4841 propertyKeyword != null &&
4842 (propertyKeyword as KeywordToken).keyword == Keyword.GET;
4843
4844 @override
4845 bool get isSetter =>
4846 propertyKeyword != null &&
4847 (propertyKeyword as KeywordToken).keyword == Keyword.SET;
4848
4849 @override
4850 TypeName get returnType => _returnType;
4851
4852 @override
4853 void set returnType(TypeName returnType) {
4854 _returnType = _becomeParentOf(returnType);
4855 }
4856
4857 @override
4858 accept(AstVisitor visitor) => visitor.visitFunctionDeclaration(this);
4859
4860 @override
4861 void visitChildren(AstVisitor visitor) {
4862 super.visitChildren(visitor);
4863 _safelyVisitChild(_returnType, visitor);
4864 _safelyVisitChild(_name, visitor);
4865 _safelyVisitChild(_functionExpression, visitor);
4866 }
4867 }
4868
4869 /**
4870 * A [FunctionDeclaration] used as a statement.
4871 */
4872 class FunctionDeclarationStatementImpl extends StatementImpl
4873 implements FunctionDeclarationStatement {
4874 /**
4875 * The function declaration being wrapped.
4876 */
4877 FunctionDeclaration _functionDeclaration;
4878
4879 /**
4880 * Initialize a newly created function declaration statement.
4881 */
4882 FunctionDeclarationStatementImpl(FunctionDeclaration functionDeclaration) {
4883 _functionDeclaration = _becomeParentOf(functionDeclaration);
4884 }
4885
4886 @override
4887 Token get beginToken => _functionDeclaration.beginToken;
4888
4889 @override
4890 Iterable get childEntities => new ChildEntities()..add(_functionDeclaration);
4891
4892 @override
4893 Token get endToken => _functionDeclaration.endToken;
4894
4895 @override
4896 FunctionDeclaration get functionDeclaration => _functionDeclaration;
4897
4898 @override
4899 void set functionDeclaration(FunctionDeclaration functionDeclaration) {
4900 _functionDeclaration = _becomeParentOf(functionDeclaration);
4901 }
4902
4903 @override
4904 accept(AstVisitor visitor) => visitor.visitFunctionDeclarationStatement(this);
4905
4906 @override
4907 void visitChildren(AstVisitor visitor) {
4908 _safelyVisitChild(_functionDeclaration, visitor);
4909 }
4910 }
4911
4912 /**
4913 * A function expression.
4914 *
4915 * > functionExpression ::=
4916 * > [TypeParameterList]? [FormalParameterList] [FunctionBody]
4917 */
4918 class FunctionExpressionImpl extends ExpressionImpl
4919 implements FunctionExpression {
4920 /**
4921 * The type parameters associated with the method, or `null` if the method is
4922 * not a generic method.
4923 */
4924 TypeParameterList _typeParameters;
4925
4926 /**
4927 * The parameters associated with the function.
4928 */
4929 FormalParameterList _parameters;
4930
4931 /**
4932 * The body of the function, or `null` if this is an external function.
4933 */
4934 FunctionBody _body;
4935
4936 /**
4937 * The element associated with the function, or `null` if the AST structure
4938 * has not been resolved.
4939 */
4940 ExecutableElement element;
4941
4942 /**
4943 * Initialize a newly created function declaration.
4944 */
4945 FunctionExpressionImpl(TypeParameterList typeParameters,
4946 FormalParameterList parameters, FunctionBody body) {
4947 _typeParameters = _becomeParentOf(typeParameters);
4948 _parameters = _becomeParentOf(parameters);
4949 _body = _becomeParentOf(body);
4950 }
4951
4952 @override
4953 Token get beginToken {
4954 if (_typeParameters != null) {
4955 return _typeParameters.beginToken;
4956 } else if (_parameters != null) {
4957 return _parameters.beginToken;
4958 } else if (_body != null) {
4959 return _body.beginToken;
4960 }
4961 // This should never be reached because external functions must be named,
4962 // hence either the body or the name should be non-null.
4963 throw new IllegalStateException("Non-external functions must have a body");
4964 }
4965
4966 @override
4967 FunctionBody get body => _body;
4968
4969 @override
4970 void set body(FunctionBody functionBody) {
4971 _body = _becomeParentOf(functionBody);
4972 }
4973
4974 @override
4975 Iterable get childEntities =>
4976 new ChildEntities()..add(_parameters)..add(_body);
4977
4978 @override
4979 Token get endToken {
4980 if (_body != null) {
4981 return _body.endToken;
4982 } else if (_parameters != null) {
4983 return _parameters.endToken;
4984 }
4985 // This should never be reached because external functions must be named,
4986 // hence either the body or the name should be non-null.
4987 throw new IllegalStateException("Non-external functions must have a body");
4988 }
4989
4990 @override
4991 FormalParameterList get parameters => _parameters;
4992
4993 @override
4994 void set parameters(FormalParameterList parameters) {
4995 _parameters = _becomeParentOf(parameters);
4996 }
4997
4998 @override
4999 int get precedence => 16;
5000
5001 @override
5002 TypeParameterList get typeParameters => _typeParameters;
5003
5004 @override
5005 void set typeParameters(TypeParameterList typeParameters) {
5006 _typeParameters = _becomeParentOf(typeParameters);
5007 }
5008
5009 @override
5010 accept(AstVisitor visitor) => visitor.visitFunctionExpression(this);
5011
5012 @override
5013 void visitChildren(AstVisitor visitor) {
5014 _safelyVisitChild(_typeParameters, visitor);
5015 _safelyVisitChild(_parameters, visitor);
5016 _safelyVisitChild(_body, visitor);
5017 }
5018 }
5019
5020 /**
5021 * The invocation of a function resulting from evaluating an expression.
5022 * Invocations of methods and other forms of functions are represented by
5023 * [MethodInvocation] nodes. Invocations of getters and setters are represented
5024 * by either [PrefixedIdentifier] or [PropertyAccess] nodes.
5025 *
5026 * > functionExpressionInvocation ::=
5027 * > [Expression] [TypeArgumentList]? [ArgumentList]
5028 */
5029 class FunctionExpressionInvocationImpl extends ExpressionImpl
5030 implements FunctionExpressionInvocation {
5031 /**
5032 * The expression producing the function being invoked.
5033 */
5034 Expression _function;
5035
5036 /**
5037 * The type arguments to be applied to the method being invoked, or `null` if
5038 * no type arguments were provided.
5039 */
5040 TypeArgumentList _typeArguments;
5041
5042 /**
5043 * The list of arguments to the function.
5044 */
5045 ArgumentList _argumentList;
5046
5047 /**
5048 * The element associated with the function being invoked based on static type
5049 * information, or `null` if the AST structure has not been resolved or the
5050 * function could not be resolved.
5051 */
5052 ExecutableElement staticElement;
5053
5054 /**
5055 * The function type of the method invocation, or `null` if the AST
5056 * structure has not been resolved, or if the invoke could not be resolved.
5057 *
5058 * This will usually be a [FunctionType], but it can also be an
5059 * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
5060 * interface type that implements `Function`.
5061 */
5062 DartType staticInvokeType;
5063
5064 /**
5065 * The element associated with the function being invoked based on propagated
5066 * type information, or `null` if the AST structure has not been resolved or
5067 * the function could not be resolved.
5068 */
5069 ExecutableElement propagatedElement;
5070
5071 /**
5072 * Like [staticInvokeType], but reflects propagated type information.
5073 */
5074 DartType propagatedInvokeType;
5075
5076 /**
5077 * Initialize a newly created function expression invocation.
5078 */
5079 FunctionExpressionInvocationImpl(Expression function,
5080 TypeArgumentList typeArguments, ArgumentList argumentList) {
5081 _function = _becomeParentOf(function);
5082 _typeArguments = _becomeParentOf(typeArguments);
5083 _argumentList = _becomeParentOf(argumentList);
5084 }
5085
5086 @override
5087 ArgumentList get argumentList => _argumentList;
5088
5089 @override
5090 void set argumentList(ArgumentList argumentList) {
5091 _argumentList = _becomeParentOf(argumentList);
5092 }
5093
5094 @override
5095 Token get beginToken => _function.beginToken;
5096
5097 @override
5098 ExecutableElement get bestElement {
5099 ExecutableElement element = propagatedElement;
5100 if (element == null) {
5101 element = staticElement;
5102 }
5103 return element;
5104 }
5105
5106 @override
5107 Iterable get childEntities =>
5108 new ChildEntities()..add(_function)..add(_argumentList);
5109
5110 @override
5111 Token get endToken => _argumentList.endToken;
5112
5113 @override
5114 Expression get function => _function;
5115
5116 @override
5117 void set function(Expression expression) {
5118 _function = _becomeParentOf(expression);
5119 }
5120
5121 @override
5122 int get precedence => 15;
5123
5124 @override
5125 TypeArgumentList get typeArguments => _typeArguments;
5126
5127 @override
5128 void set typeArguments(TypeArgumentList typeArguments) {
5129 _typeArguments = _becomeParentOf(typeArguments);
5130 }
5131
5132 @override
5133 accept(AstVisitor visitor) => visitor.visitFunctionExpressionInvocation(this);
5134
5135 @override
5136 void visitChildren(AstVisitor visitor) {
5137 _safelyVisitChild(_function, visitor);
5138 _safelyVisitChild(_typeArguments, visitor);
5139 _safelyVisitChild(_argumentList, visitor);
5140 }
5141 }
5142
5143 /**
5144 * A function type alias.
5145 *
5146 * > functionTypeAlias ::=
5147 * > functionPrefix [TypeParameterList]? [FormalParameterList] ';'
5148 * >
5149 * > functionPrefix ::=
5150 * > [TypeName]? [SimpleIdentifier]
5151 */
5152 class FunctionTypeAliasImpl extends TypeAliasImpl implements FunctionTypeAlias {
5153 /**
5154 * The name of the return type of the function type being defined, or `null`
5155 * if no return type was given.
5156 */
5157 TypeName _returnType;
5158
5159 /**
5160 * The type parameters for the function type, or `null` if the function type
5161 * does not have any type parameters.
5162 */
5163 TypeParameterList _typeParameters;
5164
5165 /**
5166 * The parameters associated with the function type.
5167 */
5168 FormalParameterList _parameters;
5169
5170 /**
5171 * Initialize a newly created function type alias. Either or both of the
5172 * [comment] and [metadata] can be `null` if the function does not have the
5173 * corresponding attribute. The [returnType] can be `null` if no return type
5174 * was specified. The [typeParameters] can be `null` if the function has no
5175 * type parameters.
5176 */
5177 FunctionTypeAliasImpl(
5178 Comment comment,
5179 List<Annotation> metadata,
5180 Token keyword,
5181 TypeName returnType,
5182 SimpleIdentifier name,
5183 TypeParameterList typeParameters,
5184 FormalParameterList parameters,
5185 Token semicolon)
5186 : super(comment, metadata, keyword, name, semicolon) {
5187 _returnType = _becomeParentOf(returnType);
5188 _typeParameters = _becomeParentOf(typeParameters);
5189 _parameters = _becomeParentOf(parameters);
5190 }
5191
5192 @override
5193 Iterable get childEntities => super._childEntities
5194 ..add(typedefKeyword)
5195 ..add(_returnType)
5196 ..add(_name)
5197 ..add(_typeParameters)
5198 ..add(_parameters)
5199 ..add(semicolon);
5200
5201 @override
5202 FunctionTypeAliasElement get element =>
5203 _name != null ? (_name.staticElement as FunctionTypeAliasElement) : null;
5204
5205 @override
5206 FormalParameterList get parameters => _parameters;
5207
5208 @override
5209 void set parameters(FormalParameterList parameters) {
5210 _parameters = _becomeParentOf(parameters);
5211 }
5212
5213 @override
5214 TypeName get returnType => _returnType;
5215
5216 @override
5217 void set returnType(TypeName typeName) {
5218 _returnType = _becomeParentOf(typeName);
5219 }
5220
5221 @override
5222 TypeParameterList get typeParameters => _typeParameters;
5223
5224 @override
5225 void set typeParameters(TypeParameterList typeParameters) {
5226 _typeParameters = _becomeParentOf(typeParameters);
5227 }
5228
5229 @override
5230 accept(AstVisitor visitor) => visitor.visitFunctionTypeAlias(this);
5231
5232 @override
5233 void visitChildren(AstVisitor visitor) {
5234 super.visitChildren(visitor);
5235 _safelyVisitChild(_returnType, visitor);
5236 _safelyVisitChild(_name, visitor);
5237 _safelyVisitChild(_typeParameters, visitor);
5238 _safelyVisitChild(_parameters, visitor);
5239 }
5240 }
5241
5242 /**
5243 * A function-typed formal parameter.
5244 *
5245 * > functionSignature ::=
5246 * > [TypeName]? [SimpleIdentifier] [TypeParameterList]? [FormalParameterLis t]
5247 */
5248 class FunctionTypedFormalParameterImpl extends NormalFormalParameterImpl
5249 implements FunctionTypedFormalParameter {
5250 /**
5251 * The return type of the function, or `null` if the function does not have a
5252 * return type.
5253 */
5254 TypeName _returnType;
5255
5256 /**
5257 * The type parameters associated with the function, or `null` if the function
5258 * is not a generic function.
5259 */
5260 TypeParameterList _typeParameters;
5261
5262 /**
5263 * The parameters of the function-typed parameter.
5264 */
5265 FormalParameterList _parameters;
5266
5267 /**
5268 * Initialize a newly created formal parameter. Either or both of the
5269 * [comment] and [metadata] can be `null` if the parameter does not have the
5270 * corresponding attribute. The [returnType] can be `null` if no return type
5271 * was specified.
5272 */
5273 FunctionTypedFormalParameterImpl(
5274 Comment comment,
5275 List<Annotation> metadata,
5276 TypeName returnType,
5277 SimpleIdentifier identifier,
5278 TypeParameterList typeParameters,
5279 FormalParameterList parameters)
5280 : super(comment, metadata, identifier) {
5281 _returnType = _becomeParentOf(returnType);
5282 _typeParameters = _becomeParentOf(typeParameters);
5283 _parameters = _becomeParentOf(parameters);
5284 }
5285
5286 @override
5287 Token get beginToken {
5288 if (_returnType != null) {
5289 return _returnType.beginToken;
5290 }
5291 return identifier.beginToken;
5292 }
5293
5294 @override
5295 Iterable get childEntities =>
5296 super._childEntities..add(_returnType)..add(identifier)..add(parameters);
5297
5298 @override
5299 Token get endToken => _parameters.endToken;
5300
5301 @override
5302 bool get isConst => false;
5303
5304 @override
5305 bool get isFinal => false;
5306
5307 @override
5308 FormalParameterList get parameters => _parameters;
5309
5310 @override
5311 void set parameters(FormalParameterList parameters) {
5312 _parameters = _becomeParentOf(parameters);
5313 }
5314
5315 @override
5316 TypeName get returnType => _returnType;
5317
5318 @override
5319 void set returnType(TypeName type) {
5320 _returnType = _becomeParentOf(type);
5321 }
5322
5323 @override
5324 TypeParameterList get typeParameters => _typeParameters;
5325
5326 @override
5327 void set typeParameters(TypeParameterList typeParameters) {
5328 _typeParameters = _becomeParentOf(typeParameters);
5329 }
5330
5331 @override
5332 accept(AstVisitor visitor) => visitor.visitFunctionTypedFormalParameter(this);
5333
5334 @override
5335 void visitChildren(AstVisitor visitor) {
5336 super.visitChildren(visitor);
5337 _safelyVisitChild(_returnType, visitor);
5338 _safelyVisitChild(identifier, visitor);
5339 _safelyVisitChild(_typeParameters, visitor);
5340 _safelyVisitChild(_parameters, visitor);
5341 }
5342 }
5343
5344 /**
5345 * A combinator that restricts the names being imported to those that are not in
5346 * a given list.
5347 *
5348 * > hideCombinator ::=
5349 * > 'hide' [SimpleIdentifier] (',' [SimpleIdentifier])*
5350 */
5351 class HideCombinatorImpl extends CombinatorImpl implements HideCombinator {
5352 /**
5353 * The list of names from the library that are hidden by this combinator.
5354 */
5355 NodeList<SimpleIdentifier> _hiddenNames;
5356
5357 /**
5358 * Initialize a newly created import show combinator.
5359 */
5360 HideCombinatorImpl(Token keyword, List<SimpleIdentifier> hiddenNames)
5361 : super(keyword) {
5362 _hiddenNames = new NodeList<SimpleIdentifier>(this, hiddenNames);
5363 }
5364
5365 @override
5366 Iterable get childEntities => new ChildEntities()
5367 ..add(keyword)
5368 ..addAll(_hiddenNames);
5369
5370 @override
5371 Token get endToken => _hiddenNames.endToken;
5372
5373 @override
5374 NodeList<SimpleIdentifier> get hiddenNames => _hiddenNames;
5375
5376 @override
5377 accept(AstVisitor visitor) => visitor.visitHideCombinator(this);
5378
5379 @override
5380 void visitChildren(AstVisitor visitor) {
5381 _hiddenNames.accept(visitor);
5382 }
5383 }
5384
5385 /**
5386 * A node that represents an identifier.
5387 *
5388 * > identifier ::=
5389 * > [SimpleIdentifier]
5390 * > | [PrefixedIdentifier]
5391 */
5392 abstract class IdentifierImpl extends ExpressionImpl implements Identifier {
5393 /**
5394 * Return the best element available for this operator. If resolution was able
5395 * to find a better element based on type propagation, that element will be
5396 * returned. Otherwise, the element found using the result of static analysis
5397 * will be returned. If resolution has not been performed, then `null` will be
5398 * returned.
5399 */
5400 Element get bestElement;
5401
5402 @override
5403 bool get isAssignable => true;
5404 }
5405
5406 /**
5407 * An if statement.
5408 *
5409 * > ifStatement ::=
5410 * > 'if' '(' [Expression] ')' [Statement] ('else' [Statement])?
5411 */
5412 class IfStatementImpl extends StatementImpl implements IfStatement {
5413 /**
5414 * The token representing the 'if' keyword.
5415 */
5416 Token ifKeyword;
5417
5418 /**
5419 * The left parenthesis.
5420 */
5421 Token leftParenthesis;
5422
5423 /**
5424 * The condition used to determine which of the statements is executed next.
5425 */
5426 Expression _condition;
5427
5428 /**
5429 * The right parenthesis.
5430 */
5431 Token rightParenthesis;
5432
5433 /**
5434 * The statement that is executed if the condition evaluates to `true`.
5435 */
5436 Statement _thenStatement;
5437
5438 /**
5439 * The token representing the 'else' keyword, or `null` if there is no else
5440 * statement.
5441 */
5442 Token elseKeyword;
5443
5444 /**
5445 * The statement that is executed if the condition evaluates to `false`, or
5446 * `null` if there is no else statement.
5447 */
5448 Statement _elseStatement;
5449
5450 /**
5451 * Initialize a newly created if statement. The [elseKeyword] and
5452 * [elseStatement] can be `null` if there is no else clause.
5453 */
5454 IfStatementImpl(
5455 this.ifKeyword,
5456 this.leftParenthesis,
5457 Expression condition,
5458 this.rightParenthesis,
5459 Statement thenStatement,
5460 this.elseKeyword,
5461 Statement elseStatement) {
5462 _condition = _becomeParentOf(condition);
5463 _thenStatement = _becomeParentOf(thenStatement);
5464 _elseStatement = _becomeParentOf(elseStatement);
5465 }
5466
5467 @override
5468 Token get beginToken => ifKeyword;
5469
5470 @override
5471 Iterable get childEntities => new ChildEntities()
5472 ..add(ifKeyword)
5473 ..add(leftParenthesis)
5474 ..add(_condition)
5475 ..add(rightParenthesis)
5476 ..add(_thenStatement)
5477 ..add(elseKeyword)
5478 ..add(_elseStatement);
5479
5480 @override
5481 Expression get condition => _condition;
5482
5483 @override
5484 void set condition(Expression expression) {
5485 _condition = _becomeParentOf(expression);
5486 }
5487
5488 @override
5489 Statement get elseStatement => _elseStatement;
5490
5491 @override
5492 void set elseStatement(Statement statement) {
5493 _elseStatement = _becomeParentOf(statement);
5494 }
5495
5496 @override
5497 Token get endToken {
5498 if (_elseStatement != null) {
5499 return _elseStatement.endToken;
5500 }
5501 return _thenStatement.endToken;
5502 }
5503
5504 @override
5505 Statement get thenStatement => _thenStatement;
5506
5507 @override
5508 void set thenStatement(Statement statement) {
5509 _thenStatement = _becomeParentOf(statement);
5510 }
5511
5512 @override
5513 accept(AstVisitor visitor) => visitor.visitIfStatement(this);
5514
5515 @override
5516 void visitChildren(AstVisitor visitor) {
5517 _safelyVisitChild(_condition, visitor);
5518 _safelyVisitChild(_thenStatement, visitor);
5519 _safelyVisitChild(_elseStatement, visitor);
5520 }
5521 }
5522
5523 /**
5524 * The "implements" clause in an class declaration.
5525 *
5526 * > implementsClause ::=
5527 * > 'implements' [TypeName] (',' [TypeName])*
5528 */
5529 class ImplementsClauseImpl extends AstNodeImpl implements ImplementsClause {
5530 /**
5531 * The token representing the 'implements' keyword.
5532 */
5533 Token implementsKeyword;
5534
5535 /**
5536 * The interfaces that are being implemented.
5537 */
5538 NodeList<TypeName> _interfaces;
5539
5540 /**
5541 * Initialize a newly created implements clause.
5542 */
5543 ImplementsClauseImpl(this.implementsKeyword, List<TypeName> interfaces) {
5544 _interfaces = new NodeList<TypeName>(this, interfaces);
5545 }
5546
5547 @override
5548 Token get beginToken => implementsKeyword;
5549
5550 @override
5551 // TODO(paulberry): add commas.
5552 Iterable get childEntities => new ChildEntities()
5553 ..add(implementsKeyword)
5554 ..addAll(interfaces);
5555
5556 @override
5557 Token get endToken => _interfaces.endToken;
5558
5559 @override
5560 NodeList<TypeName> get interfaces => _interfaces;
5561
5562 @override
5563 accept(AstVisitor visitor) => visitor.visitImplementsClause(this);
5564
5565 @override
5566 void visitChildren(AstVisitor visitor) {
5567 _interfaces.accept(visitor);
5568 }
5569 }
5570
5571 /**
5572 * An import directive.
5573 *
5574 * > importDirective ::=
5575 * > [Annotation] 'import' [StringLiteral] ('as' identifier)? [Combinator]* ';'
5576 * > | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier [Combi nator]* ';'
5577 */
5578 class ImportDirectiveImpl extends NamespaceDirectiveImpl
5579 implements ImportDirective {
5580 /**
5581 * The token representing the 'deferred' keyword, or `null` if the imported is
5582 * not deferred.
5583 */
5584 Token deferredKeyword;
5585
5586 /**
5587 * The token representing the 'as' keyword, or `null` if the imported names ar e
5588 * not prefixed.
5589 */
5590 Token asKeyword;
5591
5592 /**
5593 * The prefix to be used with the imported names, or `null` if the imported
5594 * names are not prefixed.
5595 */
5596 SimpleIdentifier _prefix;
5597
5598 /**
5599 * Initialize a newly created import directive. Either or both of the
5600 * [comment] and [metadata] can be `null` if the function does not have the
5601 * corresponding attribute. The [deferredKeyword] can be `null` if the import
5602 * is not deferred. The [asKeyword] and [prefix] can be `null` if the import
5603 * does not specify a prefix. The list of [combinators] can be `null` if there
5604 * are no combinators.
5605 */
5606 ImportDirectiveImpl(
5607 Comment comment,
5608 List<Annotation> metadata,
5609 Token keyword,
5610 StringLiteral libraryUri,
5611 List<Configuration> configurations,
5612 this.deferredKeyword,
5613 this.asKeyword,
5614 SimpleIdentifier prefix,
5615 List<Combinator> combinators,
5616 Token semicolon)
5617 : super(comment, metadata, keyword, libraryUri, configurations,
5618 combinators, semicolon) {
5619 _prefix = _becomeParentOf(prefix);
5620 }
5621
5622 @override
5623 Iterable get childEntities => super._childEntities
5624 ..add(_uri)
5625 ..add(deferredKeyword)
5626 ..add(asKeyword)
5627 ..add(_prefix)
5628 ..addAll(combinators)
5629 ..add(semicolon);
5630
5631 @override
5632 ImportElement get element => super.element as ImportElement;
5633
5634 @override
5635 SimpleIdentifier get prefix => _prefix;
5636
5637 @override
5638 void set prefix(SimpleIdentifier identifier) {
5639 _prefix = _becomeParentOf(identifier);
5640 }
5641
5642 @override
5643 LibraryElement get uriElement {
5644 ImportElement element = this.element;
5645 if (element == null) {
5646 return null;
5647 }
5648 return element.importedLibrary;
5649 }
5650
5651 @override
5652 accept(AstVisitor visitor) => visitor.visitImportDirective(this);
5653
5654 @override
5655 void visitChildren(AstVisitor visitor) {
5656 super.visitChildren(visitor);
5657 _safelyVisitChild(_prefix, visitor);
5658 combinators.accept(visitor);
5659 }
5660 }
5661
5662 /**
5663 * An index expression.
5664 *
5665 * > indexExpression ::=
5666 * > [Expression] '[' [Expression] ']'
5667 */
5668 class IndexExpressionImpl extends ExpressionImpl implements IndexExpression {
5669 /**
5670 * The expression used to compute the object being indexed, or `null` if this
5671 * index expression is part of a cascade expression.
5672 */
5673 Expression _target;
5674
5675 /**
5676 * The period ("..") before a cascaded index expression, or `null` if this
5677 * index expression is not part of a cascade expression.
5678 */
5679 Token period;
5680
5681 /**
5682 * The left square bracket.
5683 */
5684 Token leftBracket;
5685
5686 /**
5687 * The expression used to compute the index.
5688 */
5689 Expression _index;
5690
5691 /**
5692 * The right square bracket.
5693 */
5694 Token rightBracket;
5695
5696 /**
5697 * The element associated with the operator based on the static type of the
5698 * target, or `null` if the AST structure has not been resolved or if the
5699 * operator could not be resolved.
5700 */
5701 MethodElement staticElement;
5702
5703 /**
5704 * The element associated with the operator based on the propagated type of
5705 * the target, or `null` if the AST structure has not been resolved or if the
5706 * operator could not be resolved.
5707 */
5708 MethodElement propagatedElement;
5709
5710 /**
5711 * If this expression is both in a getter and setter context, the
5712 * [AuxiliaryElements] will be set to hold onto the static and propagated
5713 * information. The auxiliary element will hold onto the elements from the
5714 * getter context.
5715 */
5716 AuxiliaryElements auxiliaryElements = null;
5717
5718 /**
5719 * Initialize a newly created index expression.
5720 */
5721 IndexExpressionImpl.forCascade(
5722 this.period, this.leftBracket, Expression index, this.rightBracket) {
5723 _index = _becomeParentOf(index);
5724 }
5725
5726 /**
5727 * Initialize a newly created index expression.
5728 */
5729 IndexExpressionImpl.forTarget(Expression target, this.leftBracket,
5730 Expression index, this.rightBracket) {
5731 _target = _becomeParentOf(target);
5732 _index = _becomeParentOf(index);
5733 }
5734
5735 @override
5736 Token get beginToken {
5737 if (_target != null) {
5738 return _target.beginToken;
5739 }
5740 return period;
5741 }
5742
5743 @override
5744 MethodElement get bestElement {
5745 MethodElement element = propagatedElement;
5746 if (element == null) {
5747 element = staticElement;
5748 }
5749 return element;
5750 }
5751
5752 @override
5753 Iterable get childEntities => new ChildEntities()
5754 ..add(_target)
5755 ..add(period)
5756 ..add(leftBracket)
5757 ..add(_index)
5758 ..add(rightBracket);
5759
5760 @override
5761 Token get endToken => rightBracket;
5762
5763 @override
5764 Expression get index => _index;
5765
5766 @override
5767 void set index(Expression expression) {
5768 _index = _becomeParentOf(expression);
5769 }
5770
5771 @override
5772 bool get isAssignable => true;
5773
5774 @override
5775 bool get isCascaded => period != null;
5776
5777 @override
5778 int get precedence => 15;
5779
5780 @override
5781 Expression get realTarget {
5782 if (isCascaded) {
5783 AstNode ancestor = parent;
5784 while (ancestor is! CascadeExpression) {
5785 if (ancestor == null) {
5786 return _target;
5787 }
5788 ancestor = ancestor.parent;
5789 }
5790 return (ancestor as CascadeExpression).target;
5791 }
5792 return _target;
5793 }
5794
5795 @override
5796 Expression get target => _target;
5797
5798 @override
5799 void set target(Expression expression) {
5800 _target = _becomeParentOf(expression);
5801 }
5802
5803 /**
5804 * If the AST structure has been resolved, and the function being invoked is
5805 * known based on propagated type information, then return the parameter
5806 * element representing the parameter to which the value of the index
5807 * expression will be bound. Otherwise, return `null`.
5808 */
5809 ParameterElement get _propagatedParameterElementForIndex {
5810 if (propagatedElement == null) {
5811 return null;
5812 }
5813 List<ParameterElement> parameters = propagatedElement.parameters;
5814 if (parameters.length < 1) {
5815 return null;
5816 }
5817 return parameters[0];
5818 }
5819
5820 /**
5821 * If the AST structure has been resolved, and the function being invoked is
5822 * known based on static type information, then return the parameter element
5823 * representing the parameter to which the value of the index expression will
5824 * be bound. Otherwise, return `null`.
5825 */
5826 ParameterElement get _staticParameterElementForIndex {
5827 if (staticElement == null) {
5828 return null;
5829 }
5830 List<ParameterElement> parameters = staticElement.parameters;
5831 if (parameters.length < 1) {
5832 return null;
5833 }
5834 return parameters[0];
5835 }
5836
5837 @override
5838 accept(AstVisitor visitor) => visitor.visitIndexExpression(this);
5839
5840 @override
5841 bool inGetterContext() {
5842 // TODO(brianwilkerson) Convert this to a getter.
5843 AstNode parent = this.parent;
5844 if (parent is AssignmentExpression) {
5845 AssignmentExpression assignment = parent;
5846 if (identical(assignment.leftHandSide, this) &&
5847 assignment.operator.type == TokenType.EQ) {
5848 return false;
5849 }
5850 }
5851 return true;
5852 }
5853
5854 @override
5855 bool inSetterContext() {
5856 // TODO(brianwilkerson) Convert this to a getter.
5857 AstNode parent = this.parent;
5858 if (parent is PrefixExpression) {
5859 return parent.operator.type.isIncrementOperator;
5860 } else if (parent is PostfixExpression) {
5861 return true;
5862 } else if (parent is AssignmentExpression) {
5863 return identical(parent.leftHandSide, this);
5864 }
5865 return false;
5866 }
5867
5868 @override
5869 void visitChildren(AstVisitor visitor) {
5870 _safelyVisitChild(_target, visitor);
5871 _safelyVisitChild(_index, visitor);
5872 }
5873 }
5874
5875 /**
5876 * An instance creation expression.
5877 *
5878 * > newExpression ::=
5879 * > ('new' | 'const') [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]
5880 */
5881 class InstanceCreationExpressionImpl extends ExpressionImpl
5882 implements InstanceCreationExpression {
5883 /**
5884 * The 'new' or 'const' keyword used to indicate how an object should be
5885 * created.
5886 */
5887 Token keyword;
5888
5889 /**
5890 * The name of the constructor to be invoked.
5891 */
5892 ConstructorName _constructorName;
5893
5894 /**
5895 * The list of arguments to the constructor.
5896 */
5897 ArgumentList _argumentList;
5898
5899 /**
5900 * The element associated with the constructor based on static type
5901 * information, or `null` if the AST structure has not been resolved or if the
5902 * constructor could not be resolved.
5903 */
5904 ConstructorElement staticElement;
5905
5906 /**
5907 * Initialize a newly created instance creation expression.
5908 */
5909 InstanceCreationExpressionImpl(this.keyword, ConstructorName constructorName,
5910 ArgumentList argumentList) {
5911 _constructorName = _becomeParentOf(constructorName);
5912 _argumentList = _becomeParentOf(argumentList);
5913 }
5914
5915 @override
5916 ArgumentList get argumentList => _argumentList;
5917
5918 @override
5919 void set argumentList(ArgumentList argumentList) {
5920 _argumentList = _becomeParentOf(argumentList);
5921 }
5922
5923 @override
5924 Token get beginToken => keyword;
5925
5926 @override
5927 Iterable get childEntities => new ChildEntities()
5928 ..add(keyword)
5929 ..add(_constructorName)
5930 ..add(_argumentList);
5931
5932 @override
5933 ConstructorName get constructorName => _constructorName;
5934
5935 @override
5936 void set constructorName(ConstructorName name) {
5937 _constructorName = _becomeParentOf(name);
5938 }
5939
5940 @override
5941 Token get endToken => _argumentList.endToken;
5942
5943 @override
5944 bool get isConst =>
5945 keyword is KeywordToken &&
5946 (keyword as KeywordToken).keyword == Keyword.CONST;
5947
5948 @override
5949 int get precedence => 16;
5950
5951 @override
5952 accept(AstVisitor visitor) => visitor.visitInstanceCreationExpression(this);
5953
5954 @override
5955 void visitChildren(AstVisitor visitor) {
5956 _safelyVisitChild(_constructorName, visitor);
5957 _safelyVisitChild(_argumentList, visitor);
5958 }
5959 }
5960
5961 /**
5962 * An integer literal expression.
5963 *
5964 * > integerLiteral ::=
5965 * > decimalIntegerLiteral
5966 * > | hexadecimalIntegerLiteral
5967 * >
5968 * > decimalIntegerLiteral ::=
5969 * > decimalDigit+
5970 * >
5971 * > hexadecimalIntegerLiteral ::=
5972 * > '0x' hexadecimalDigit+
5973 * > | '0X' hexadecimalDigit+
5974 */
5975 class IntegerLiteralImpl extends LiteralImpl implements IntegerLiteral {
5976 /**
5977 * The token representing the literal.
5978 */
5979 Token literal;
5980
5981 /**
5982 * The value of the literal.
5983 */
5984 int value = 0;
5985
5986 /**
5987 * Initialize a newly created integer literal.
5988 */
5989 IntegerLiteralImpl(this.literal, this.value);
5990
5991 @override
5992 Token get beginToken => literal;
5993
5994 @override
5995 Iterable get childEntities => new ChildEntities()..add(literal);
5996
5997 @override
5998 Token get endToken => literal;
5999
6000 @override
6001 accept(AstVisitor visitor) => visitor.visitIntegerLiteral(this);
6002
6003 @override
6004 void visitChildren(AstVisitor visitor) {
6005 // There are no children to visit.
6006 }
6007 }
6008
6009 /**
6010 * A node within a [StringInterpolation].
6011 *
6012 * > interpolationElement ::=
6013 * > [InterpolationExpression]
6014 * > | [InterpolationString]
6015 */
6016 abstract class InterpolationElementImpl extends AstNodeImpl
6017 implements InterpolationElement {}
6018
6019 /**
6020 * An expression embedded in a string interpolation.
6021 *
6022 * > interpolationExpression ::=
6023 * > '$' [SimpleIdentifier]
6024 * > | '$' '{' [Expression] '}'
6025 */
6026 class InterpolationExpressionImpl extends InterpolationElementImpl
6027 implements InterpolationExpression {
6028 /**
6029 * The token used to introduce the interpolation expression; either '$' if the
6030 * expression is a simple identifier or '${' if the expression is a full
6031 * expression.
6032 */
6033 Token leftBracket;
6034
6035 /**
6036 * The expression to be evaluated for the value to be converted into a string.
6037 */
6038 Expression _expression;
6039
6040 /**
6041 * The right curly bracket, or `null` if the expression is an identifier
6042 * without brackets.
6043 */
6044 Token rightBracket;
6045
6046 /**
6047 * Initialize a newly created interpolation expression.
6048 */
6049 InterpolationExpressionImpl(
6050 this.leftBracket, Expression expression, this.rightBracket) {
6051 _expression = _becomeParentOf(expression);
6052 }
6053
6054 @override
6055 Token get beginToken => leftBracket;
6056
6057 @override
6058 Iterable get childEntities => new ChildEntities()
6059 ..add(leftBracket)
6060 ..add(_expression)
6061 ..add(rightBracket);
6062
6063 @override
6064 Token get endToken {
6065 if (rightBracket != null) {
6066 return rightBracket;
6067 }
6068 return _expression.endToken;
6069 }
6070
6071 @override
6072 Expression get expression => _expression;
6073
6074 @override
6075 void set expression(Expression expression) {
6076 _expression = _becomeParentOf(expression);
6077 }
6078
6079 @override
6080 accept(AstVisitor visitor) => visitor.visitInterpolationExpression(this);
6081
6082 @override
6083 void visitChildren(AstVisitor visitor) {
6084 _safelyVisitChild(_expression, visitor);
6085 }
6086 }
6087
6088 /**
6089 * A non-empty substring of an interpolated string.
6090 *
6091 * > interpolationString ::=
6092 * > characters
6093 */
6094 class InterpolationStringImpl extends InterpolationElementImpl
6095 implements InterpolationString {
6096 /**
6097 * The characters that will be added to the string.
6098 */
6099 Token contents;
6100
6101 /**
6102 * The value of the literal.
6103 */
6104 String value;
6105
6106 /**
6107 * Initialize a newly created string of characters that are part of a string
6108 * interpolation.
6109 */
6110 InterpolationStringImpl(this.contents, this.value);
6111
6112 @override
6113 Token get beginToken => contents;
6114
6115 @override
6116 Iterable get childEntities => new ChildEntities()..add(contents);
6117
6118 @override
6119 int get contentsEnd {
6120 String lexeme = contents.lexeme;
6121 return offset + new StringLexemeHelper(lexeme, true, true).end;
6122 }
6123
6124 @override
6125 int get contentsOffset {
6126 int offset = contents.offset;
6127 String lexeme = contents.lexeme;
6128 return offset + new StringLexemeHelper(lexeme, true, true).start;
6129 }
6130
6131 @override
6132 Token get endToken => contents;
6133
6134 @override
6135 accept(AstVisitor visitor) => visitor.visitInterpolationString(this);
6136
6137 @override
6138 void visitChildren(AstVisitor visitor) {}
6139 }
6140
6141 /**
6142 * An is expression.
6143 *
6144 * > isExpression ::=
6145 * > [Expression] 'is' '!'? [TypeName]
6146 */
6147 class IsExpressionImpl extends ExpressionImpl implements IsExpression {
6148 /**
6149 * The expression used to compute the value whose type is being tested.
6150 */
6151 Expression _expression;
6152
6153 /**
6154 * The is operator.
6155 */
6156 Token isOperator;
6157
6158 /**
6159 * The not operator, or `null` if the sense of the test is not negated.
6160 */
6161 Token notOperator;
6162
6163 /**
6164 * The name of the type being tested for.
6165 */
6166 TypeName _type;
6167
6168 /**
6169 * Initialize a newly created is expression. The [notOperator] can be `null`
6170 * if the sense of the test is not negated.
6171 */
6172 IsExpressionImpl(
6173 Expression expression, this.isOperator, this.notOperator, TypeName type) {
6174 _expression = _becomeParentOf(expression);
6175 _type = _becomeParentOf(type);
6176 }
6177
6178 @override
6179 Token get beginToken => _expression.beginToken;
6180
6181 @override
6182 Iterable get childEntities => new ChildEntities()
6183 ..add(_expression)
6184 ..add(isOperator)
6185 ..add(notOperator)
6186 ..add(_type);
6187
6188 @override
6189 Token get endToken => _type.endToken;
6190
6191 @override
6192 Expression get expression => _expression;
6193
6194 @override
6195 void set expression(Expression expression) {
6196 _expression = _becomeParentOf(expression);
6197 }
6198
6199 @override
6200 int get precedence => 7;
6201
6202 @override
6203 TypeName get type => _type;
6204
6205 @override
6206 void set type(TypeName name) {
6207 _type = _becomeParentOf(name);
6208 }
6209
6210 @override
6211 accept(AstVisitor visitor) => visitor.visitIsExpression(this);
6212
6213 @override
6214 void visitChildren(AstVisitor visitor) {
6215 _safelyVisitChild(_expression, visitor);
6216 _safelyVisitChild(_type, visitor);
6217 }
6218 }
6219
6220 /**
6221 * A statement that has a label associated with them.
6222 *
6223 * > labeledStatement ::=
6224 * > [Label]+ [Statement]
6225 */
6226 class LabeledStatementImpl extends StatementImpl implements LabeledStatement {
6227 /**
6228 * The labels being associated with the statement.
6229 */
6230 NodeList<Label> _labels;
6231
6232 /**
6233 * The statement with which the labels are being associated.
6234 */
6235 Statement _statement;
6236
6237 /**
6238 * Initialize a newly created labeled statement.
6239 */
6240 LabeledStatementImpl(List<Label> labels, Statement statement) {
6241 _labels = new NodeList<Label>(this, labels);
6242 _statement = _becomeParentOf(statement);
6243 }
6244
6245 @override
6246 Token get beginToken {
6247 if (!_labels.isEmpty) {
6248 return _labels.beginToken;
6249 }
6250 return _statement.beginToken;
6251 }
6252
6253 @override
6254 Iterable get childEntities => new ChildEntities()
6255 ..addAll(_labels)
6256 ..add(_statement);
6257
6258 @override
6259 Token get endToken => _statement.endToken;
6260
6261 @override
6262 NodeList<Label> get labels => _labels;
6263
6264 @override
6265 Statement get statement => _statement;
6266
6267 @override
6268 void set statement(Statement statement) {
6269 _statement = _becomeParentOf(statement);
6270 }
6271
6272 @override
6273 Statement get unlabeled => _statement.unlabeled;
6274
6275 @override
6276 accept(AstVisitor visitor) => visitor.visitLabeledStatement(this);
6277
6278 @override
6279 void visitChildren(AstVisitor visitor) {
6280 _labels.accept(visitor);
6281 _safelyVisitChild(_statement, visitor);
6282 }
6283 }
6284
6285 /**
6286 * A label on either a [LabeledStatement] or a [NamedExpression].
6287 *
6288 * > label ::=
6289 * > [SimpleIdentifier] ':'
6290 */
6291 class LabelImpl extends AstNodeImpl implements Label {
6292 /**
6293 * The label being associated with the statement.
6294 */
6295 SimpleIdentifier _label;
6296
6297 /**
6298 * The colon that separates the label from the statement.
6299 */
6300 Token colon;
6301
6302 /**
6303 * Initialize a newly created label.
6304 */
6305 LabelImpl(SimpleIdentifier label, this.colon) {
6306 _label = _becomeParentOf(label);
6307 }
6308
6309 @override
6310 Token get beginToken => _label.beginToken;
6311
6312 @override
6313 Iterable get childEntities => new ChildEntities()..add(_label)..add(colon);
6314
6315 @override
6316 Token get endToken => colon;
6317
6318 @override
6319 SimpleIdentifier get label => _label;
6320
6321 @override
6322 void set label(SimpleIdentifier label) {
6323 _label = _becomeParentOf(label);
6324 }
6325
6326 @override
6327 accept(AstVisitor visitor) => visitor.visitLabel(this);
6328
6329 @override
6330 void visitChildren(AstVisitor visitor) {
6331 _safelyVisitChild(_label, visitor);
6332 }
6333 }
6334
6335 /**
6336 * A library directive.
6337 *
6338 * > libraryDirective ::=
6339 * > [Annotation] 'library' [Identifier] ';'
6340 */
6341 class LibraryDirectiveImpl extends DirectiveImpl implements LibraryDirective {
6342 /**
6343 * The token representing the 'library' keyword.
6344 */
6345 Token libraryKeyword;
6346
6347 /**
6348 * The name of the library being defined.
6349 */
6350 LibraryIdentifier _name;
6351
6352 /**
6353 * The semicolon terminating the directive.
6354 */
6355 Token semicolon;
6356
6357 /**
6358 * Initialize a newly created library directive. Either or both of the
6359 * [comment] and [metadata] can be `null` if the directive does not have the
6360 * corresponding attribute.
6361 */
6362 LibraryDirectiveImpl(Comment comment, List<Annotation> metadata,
6363 this.libraryKeyword, LibraryIdentifier name, this.semicolon)
6364 : super(comment, metadata) {
6365 _name = _becomeParentOf(name);
6366 }
6367
6368 @override
6369 Iterable get childEntities =>
6370 super._childEntities..add(libraryKeyword)..add(_name)..add(semicolon);
6371
6372 @override
6373 Token get endToken => semicolon;
6374
6375 @override
6376 Token get firstTokenAfterCommentAndMetadata => libraryKeyword;
6377
6378 @override
6379 Token get keyword => libraryKeyword;
6380
6381 @override
6382 LibraryIdentifier get name => _name;
6383
6384 @override
6385 void set name(LibraryIdentifier name) {
6386 _name = _becomeParentOf(name);
6387 }
6388
6389 @override
6390 accept(AstVisitor visitor) => visitor.visitLibraryDirective(this);
6391
6392 @override
6393 void visitChildren(AstVisitor visitor) {
6394 super.visitChildren(visitor);
6395 _safelyVisitChild(_name, visitor);
6396 }
6397 }
6398
6399 /**
6400 * The identifier for a library.
6401 *
6402 * > libraryIdentifier ::=
6403 * > [SimpleIdentifier] ('.' [SimpleIdentifier])*
6404 */
6405 class LibraryIdentifierImpl extends IdentifierImpl
6406 implements LibraryIdentifier {
6407 /**
6408 * The components of the identifier.
6409 */
6410 NodeList<SimpleIdentifier> _components;
6411
6412 /**
6413 * Initialize a newly created prefixed identifier.
6414 */
6415 LibraryIdentifierImpl(List<SimpleIdentifier> components) {
6416 _components = new NodeList<SimpleIdentifier>(this, components);
6417 }
6418
6419 @override
6420 Token get beginToken => _components.beginToken;
6421
6422 @override
6423 Element get bestElement => staticElement;
6424
6425 @override
6426 // TODO(paulberry): add "." tokens.
6427 Iterable get childEntities => new ChildEntities()..addAll(_components);
6428
6429 @override
6430 NodeList<SimpleIdentifier> get components => _components;
6431
6432 @override
6433 Token get endToken => _components.endToken;
6434
6435 @override
6436 String get name {
6437 StringBuffer buffer = new StringBuffer();
6438 bool needsPeriod = false;
6439 for (SimpleIdentifier identifier in _components) {
6440 if (needsPeriod) {
6441 buffer.write(".");
6442 } else {
6443 needsPeriod = true;
6444 }
6445 buffer.write(identifier.name);
6446 }
6447 return buffer.toString();
6448 }
6449
6450 @override
6451 int get precedence => 15;
6452
6453 @override
6454 Element get propagatedElement => null;
6455
6456 @override
6457 Element get staticElement => null;
6458
6459 @override
6460 accept(AstVisitor visitor) => visitor.visitLibraryIdentifier(this);
6461
6462 @override
6463 void visitChildren(AstVisitor visitor) {
6464 _components.accept(visitor);
6465 }
6466 }
6467
6468 /**
6469 * A list literal.
6470 *
6471 * > listLiteral ::=
6472 * > 'const'? ('<' [TypeName] '>')? '[' ([Expression] ','?)? ']'
6473 */
6474 class ListLiteralImpl extends TypedLiteralImpl implements ListLiteral {
6475 /**
6476 * The left square bracket.
6477 */
6478 Token leftBracket;
6479
6480 /**
6481 * The expressions used to compute the elements of the list.
6482 */
6483 NodeList<Expression> _elements;
6484
6485 /**
6486 * The right square bracket.
6487 */
6488 Token rightBracket;
6489
6490 /**
6491 * Initialize a newly created list literal. The [constKeyword] can be `null`
6492 * if the literal is not a constant. The [typeArguments] can be `null` if no
6493 * type arguments were declared. The list of [elements] can be `null` if the
6494 * list is empty.
6495 */
6496 ListLiteralImpl(Token constKeyword, TypeArgumentList typeArguments,
6497 this.leftBracket, List<Expression> elements, this.rightBracket)
6498 : super(constKeyword, typeArguments) {
6499 _elements = new NodeList<Expression>(this, elements);
6500 }
6501
6502 @override
6503 Token get beginToken {
6504 if (constKeyword != null) {
6505 return constKeyword;
6506 }
6507 TypeArgumentList typeArguments = this.typeArguments;
6508 if (typeArguments != null) {
6509 return typeArguments.beginToken;
6510 }
6511 return leftBracket;
6512 }
6513
6514 @override
6515 // TODO(paulberry): add commas.
6516 Iterable get childEntities => super._childEntities
6517 ..add(leftBracket)
6518 ..addAll(_elements)
6519 ..add(rightBracket);
6520
6521 @override
6522 NodeList<Expression> get elements => _elements;
6523
6524 @override
6525 Token get endToken => rightBracket;
6526
6527 @override
6528 accept(AstVisitor visitor) => visitor.visitListLiteral(this);
6529
6530 @override
6531 void visitChildren(AstVisitor visitor) {
6532 super.visitChildren(visitor);
6533 _elements.accept(visitor);
6534 }
6535 }
6536
6537 /**
6538 * A node that represents a literal expression.
6539 *
6540 * > literal ::=
6541 * > [BooleanLiteral]
6542 * > | [DoubleLiteral]
6543 * > | [IntegerLiteral]
6544 * > | [ListLiteral]
6545 * > | [MapLiteral]
6546 * > | [NullLiteral]
6547 * > | [StringLiteral]
6548 */
6549 abstract class LiteralImpl extends ExpressionImpl implements Literal {
6550 @override
6551 int get precedence => 16;
6552 }
6553
6554 /**
6555 * A single key/value pair in a map literal.
6556 *
6557 * > mapLiteralEntry ::=
6558 * > [Expression] ':' [Expression]
6559 */
6560 class MapLiteralEntryImpl extends AstNodeImpl implements MapLiteralEntry {
6561 /**
6562 * The expression computing the key with which the value will be associated.
6563 */
6564 Expression _key;
6565
6566 /**
6567 * The colon that separates the key from the value.
6568 */
6569 Token separator;
6570
6571 /**
6572 * The expression computing the value that will be associated with the key.
6573 */
6574 Expression _value;
6575
6576 /**
6577 * Initialize a newly created map literal entry.
6578 */
6579 MapLiteralEntryImpl(Expression key, this.separator, Expression value) {
6580 _key = _becomeParentOf(key);
6581 _value = _becomeParentOf(value);
6582 }
6583
6584 @override
6585 Token get beginToken => _key.beginToken;
6586
6587 @override
6588 Iterable get childEntities =>
6589 new ChildEntities()..add(_key)..add(separator)..add(_value);
6590
6591 @override
6592 Token get endToken => _value.endToken;
6593
6594 @override
6595 Expression get key => _key;
6596
6597 @override
6598 void set key(Expression string) {
6599 _key = _becomeParentOf(string);
6600 }
6601
6602 @override
6603 Expression get value => _value;
6604
6605 @override
6606 void set value(Expression expression) {
6607 _value = _becomeParentOf(expression);
6608 }
6609
6610 @override
6611 accept(AstVisitor visitor) => visitor.visitMapLiteralEntry(this);
6612
6613 @override
6614 void visitChildren(AstVisitor visitor) {
6615 _safelyVisitChild(_key, visitor);
6616 _safelyVisitChild(_value, visitor);
6617 }
6618 }
6619
6620 /**
6621 * A literal map.
6622 *
6623 * > mapLiteral ::=
6624 * > 'const'? ('<' [TypeName] (',' [TypeName])* '>')?
6625 * > '{' ([MapLiteralEntry] (',' [MapLiteralEntry])* ','?)? '}'
6626 */
6627 class MapLiteralImpl extends TypedLiteralImpl implements MapLiteral {
6628 /**
6629 * The left curly bracket.
6630 */
6631 Token leftBracket;
6632
6633 /**
6634 * The entries in the map.
6635 */
6636 NodeList<MapLiteralEntry> _entries;
6637
6638 /**
6639 * The right curly bracket.
6640 */
6641 Token rightBracket;
6642
6643 /**
6644 * Initialize a newly created map literal. The [constKeyword] can be `null` if
6645 * the literal is not a constant. The [typeArguments] can be `null` if no type
6646 * arguments were declared. The [entries] can be `null` if the map is empty.
6647 */
6648 MapLiteralImpl(Token constKeyword, TypeArgumentList typeArguments,
6649 this.leftBracket, List<MapLiteralEntry> entries, this.rightBracket)
6650 : super(constKeyword, typeArguments) {
6651 _entries = new NodeList<MapLiteralEntry>(this, entries);
6652 }
6653
6654 @override
6655 Token get beginToken {
6656 if (constKeyword != null) {
6657 return constKeyword;
6658 }
6659 TypeArgumentList typeArguments = this.typeArguments;
6660 if (typeArguments != null) {
6661 return typeArguments.beginToken;
6662 }
6663 return leftBracket;
6664 }
6665
6666 @override
6667 // TODO(paulberry): add commas.
6668 Iterable get childEntities => super._childEntities
6669 ..add(leftBracket)
6670 ..addAll(entries)
6671 ..add(rightBracket);
6672
6673 @override
6674 Token get endToken => rightBracket;
6675
6676 @override
6677 NodeList<MapLiteralEntry> get entries => _entries;
6678
6679 @override
6680 accept(AstVisitor visitor) => visitor.visitMapLiteral(this);
6681
6682 @override
6683 void visitChildren(AstVisitor visitor) {
6684 super.visitChildren(visitor);
6685 _entries.accept(visitor);
6686 }
6687 }
6688
6689 /**
6690 * A method declaration.
6691 *
6692 * > methodDeclaration ::=
6693 * > methodSignature [FunctionBody]
6694 * >
6695 * > methodSignature ::=
6696 * > 'external'? ('abstract' | 'static')? [Type]? ('get' | 'set')?
6697 * > methodName [TypeParameterList] [FormalParameterList]
6698 * >
6699 * > methodName ::=
6700 * > [SimpleIdentifier]
6701 * > | 'operator' [SimpleIdentifier]
6702 */
6703 class MethodDeclarationImpl extends ClassMemberImpl
6704 implements MethodDeclaration {
6705 /**
6706 * The token for the 'external' keyword, or `null` if the constructor is not
6707 * external.
6708 */
6709 Token externalKeyword;
6710
6711 /**
6712 * The token representing the 'abstract' or 'static' keyword, or `null` if
6713 * neither modifier was specified.
6714 */
6715 Token modifierKeyword;
6716
6717 /**
6718 * The return type of the method, or `null` if no return type was declared.
6719 */
6720 TypeName _returnType;
6721
6722 /**
6723 * The token representing the 'get' or 'set' keyword, or `null` if this is a
6724 * method declaration rather than a property declaration.
6725 */
6726 Token propertyKeyword;
6727
6728 /**
6729 * The token representing the 'operator' keyword, or `null` if this method
6730 * does not declare an operator.
6731 */
6732 Token operatorKeyword;
6733
6734 /**
6735 * The name of the method.
6736 */
6737 SimpleIdentifier _name;
6738
6739 /**
6740 * The type parameters associated with the method, or `null` if the method is
6741 * not a generic method.
6742 */
6743 TypeParameterList _typeParameters;
6744
6745 /**
6746 * The parameters associated with the method, or `null` if this method
6747 * declares a getter.
6748 */
6749 FormalParameterList _parameters;
6750
6751 /**
6752 * The body of the method.
6753 */
6754 FunctionBody _body;
6755
6756 /**
6757 * Initialize a newly created method declaration. Either or both of the
6758 * [comment] and [metadata] can be `null` if the declaration does not have the
6759 * corresponding attribute. The [externalKeyword] can be `null` if the method
6760 * is not external. The [modifierKeyword] can be `null` if the method is
6761 * neither abstract nor static. The [returnType] can be `null` if no return
6762 * type was specified. The [propertyKeyword] can be `null` if the method is
6763 * neither a getter or a setter. The [operatorKeyword] can be `null` if the
6764 * method does not implement an operator. The [parameters] must be `null` if
6765 * this method declares a getter.
6766 */
6767 MethodDeclarationImpl(
6768 Comment comment,
6769 List<Annotation> metadata,
6770 this.externalKeyword,
6771 this.modifierKeyword,
6772 TypeName returnType,
6773 this.propertyKeyword,
6774 this.operatorKeyword,
6775 SimpleIdentifier name,
6776 TypeParameterList typeParameters,
6777 FormalParameterList parameters,
6778 FunctionBody body)
6779 : super(comment, metadata) {
6780 _returnType = _becomeParentOf(returnType);
6781 _name = _becomeParentOf(name);
6782 _typeParameters = _becomeParentOf(typeParameters);
6783 _parameters = _becomeParentOf(parameters);
6784 _body = _becomeParentOf(body);
6785 }
6786
6787 @override
6788 FunctionBody get body => _body;
6789
6790 @override
6791 void set body(FunctionBody functionBody) {
6792 _body = _becomeParentOf(functionBody);
6793 }
6794
6795 @override
6796 Iterable get childEntities => super._childEntities
6797 ..add(externalKeyword)
6798 ..add(modifierKeyword)
6799 ..add(_returnType)
6800 ..add(propertyKeyword)
6801 ..add(operatorKeyword)
6802 ..add(_name)
6803 ..add(_parameters)
6804 ..add(_body);
6805
6806 /**
6807 * Return the element associated with this method, or `null` if the AST
6808 * structure has not been resolved. The element can either be a
6809 * [MethodElement], if this represents the declaration of a normal method, or
6810 * a [PropertyAccessorElement] if this represents the declaration of either a
6811 * getter or a setter.
6812 */
6813 @override
6814 ExecutableElement get element =>
6815 _name != null ? (_name.staticElement as ExecutableElement) : null;
6816
6817 @override
6818 Token get endToken => _body.endToken;
6819
6820 @override
6821 Token get firstTokenAfterCommentAndMetadata {
6822 if (modifierKeyword != null) {
6823 return modifierKeyword;
6824 } else if (_returnType != null) {
6825 return _returnType.beginToken;
6826 } else if (propertyKeyword != null) {
6827 return propertyKeyword;
6828 } else if (operatorKeyword != null) {
6829 return operatorKeyword;
6830 }
6831 return _name.beginToken;
6832 }
6833
6834 @override
6835 bool get isAbstract {
6836 FunctionBody body = _body;
6837 return externalKeyword == null &&
6838 (body is EmptyFunctionBody && !body.semicolon.isSynthetic);
6839 }
6840
6841 @override
6842 bool get isGetter =>
6843 propertyKeyword != null &&
6844 (propertyKeyword as KeywordToken).keyword == Keyword.GET;
6845
6846 @override
6847 bool get isOperator => operatorKeyword != null;
6848
6849 @override
6850 bool get isSetter =>
6851 propertyKeyword != null &&
6852 (propertyKeyword as KeywordToken).keyword == Keyword.SET;
6853
6854 @override
6855 bool get isStatic =>
6856 modifierKeyword != null &&
6857 (modifierKeyword as KeywordToken).keyword == Keyword.STATIC;
6858
6859 @override
6860 SimpleIdentifier get name => _name;
6861
6862 @override
6863 void set name(SimpleIdentifier identifier) {
6864 _name = _becomeParentOf(identifier);
6865 }
6866
6867 @override
6868 FormalParameterList get parameters => _parameters;
6869
6870 @override
6871 void set parameters(FormalParameterList parameters) {
6872 _parameters = _becomeParentOf(parameters);
6873 }
6874
6875 @override
6876 TypeName get returnType => _returnType;
6877
6878 @override
6879 void set returnType(TypeName typeName) {
6880 _returnType = _becomeParentOf(typeName);
6881 }
6882
6883 @override
6884 TypeParameterList get typeParameters => _typeParameters;
6885
6886 @override
6887 void set typeParameters(TypeParameterList typeParameters) {
6888 _typeParameters = _becomeParentOf(typeParameters);
6889 }
6890
6891 @override
6892 accept(AstVisitor visitor) => visitor.visitMethodDeclaration(this);
6893
6894 @override
6895 void visitChildren(AstVisitor visitor) {
6896 super.visitChildren(visitor);
6897 _safelyVisitChild(_returnType, visitor);
6898 _safelyVisitChild(_name, visitor);
6899 _safelyVisitChild(_typeParameters, visitor);
6900 _safelyVisitChild(_parameters, visitor);
6901 _safelyVisitChild(_body, visitor);
6902 }
6903 }
6904
6905 /**
6906 * The invocation of either a function or a method. Invocations of functions
6907 * resulting from evaluating an expression are represented by
6908 * [FunctionExpressionInvocation] nodes. Invocations of getters and setters are
6909 * represented by either [PrefixedIdentifier] or [PropertyAccess] nodes.
6910 *
6911 * > methodInvocation ::=
6912 * > ([Expression] '.')? [SimpleIdentifier] [TypeArgumentList]? [ArgumentLis t]
6913 */
6914 class MethodInvocationImpl extends ExpressionImpl implements MethodInvocation {
6915 /**
6916 * The expression producing the object on which the method is defined, or
6917 * `null` if there is no target (that is, the target is implicitly `this`).
6918 */
6919 Expression _target;
6920
6921 /**
6922 * The operator that separates the target from the method name, or `null`
6923 * if there is no target. In an ordinary method invocation this will be a
6924 * period ('.'). In a cascade section this will be the cascade operator
6925 * ('..').
6926 */
6927 Token operator;
6928
6929 /**
6930 * The name of the method being invoked.
6931 */
6932 SimpleIdentifier _methodName;
6933
6934 /**
6935 * The type arguments to be applied to the method being invoked, or `null` if
6936 * no type arguments were provided.
6937 */
6938 TypeArgumentList _typeArguments;
6939
6940 /**
6941 * The list of arguments to the method.
6942 */
6943 ArgumentList _argumentList;
6944
6945 /**
6946 * The function type of the method invocation, or `null` if the AST
6947 * structure has not been resolved, or if the invoke could not be resolved.
6948 *
6949 * This will usually be a [FunctionType], but it can also be an
6950 * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
6951 * interface type that implements `Function`.
6952 */
6953 DartType staticInvokeType;
6954
6955 /**
6956 * Like [staticInvokeType], but reflects propagated type information.
6957 */
6958 DartType propagatedInvokeType;
6959
6960 /**
6961 * Initialize a newly created method invocation. The [target] and [operator]
6962 * can be `null` if there is no target.
6963 */
6964 MethodInvocationImpl(
6965 Expression target,
6966 this.operator,
6967 SimpleIdentifier methodName,
6968 TypeArgumentList typeArguments,
6969 ArgumentList argumentList) {
6970 _target = _becomeParentOf(target);
6971 _methodName = _becomeParentOf(methodName);
6972 _typeArguments = _becomeParentOf(typeArguments);
6973 _argumentList = _becomeParentOf(argumentList);
6974 }
6975
6976 @override
6977 ArgumentList get argumentList => _argumentList;
6978
6979 @override
6980 void set argumentList(ArgumentList argumentList) {
6981 _argumentList = _becomeParentOf(argumentList);
6982 }
6983
6984 @override
6985 Token get beginToken {
6986 if (_target != null) {
6987 return _target.beginToken;
6988 } else if (operator != null) {
6989 return operator;
6990 }
6991 return _methodName.beginToken;
6992 }
6993
6994 @override
6995 Iterable get childEntities => new ChildEntities()
6996 ..add(_target)
6997 ..add(operator)
6998 ..add(_methodName)
6999 ..add(_argumentList);
7000
7001 @override
7002 Token get endToken => _argumentList.endToken;
7003
7004 @override
7005 bool get isCascaded =>
7006 operator != null && operator.type == TokenType.PERIOD_PERIOD;
7007
7008 @override
7009 SimpleIdentifier get methodName => _methodName;
7010
7011 @override
7012 void set methodName(SimpleIdentifier identifier) {
7013 _methodName = _becomeParentOf(identifier);
7014 }
7015
7016 @override
7017 int get precedence => 15;
7018
7019 @override
7020 Expression get realTarget {
7021 if (isCascaded) {
7022 AstNode ancestor = parent;
7023 while (ancestor is! CascadeExpression) {
7024 if (ancestor == null) {
7025 return _target;
7026 }
7027 ancestor = ancestor.parent;
7028 }
7029 return (ancestor as CascadeExpression).target;
7030 }
7031 return _target;
7032 }
7033
7034 @override
7035 Expression get target => _target;
7036
7037 @override
7038 void set target(Expression expression) {
7039 _target = _becomeParentOf(expression);
7040 }
7041
7042 @override
7043 TypeArgumentList get typeArguments => _typeArguments;
7044
7045 @override
7046 void set typeArguments(TypeArgumentList typeArguments) {
7047 _typeArguments = _becomeParentOf(typeArguments);
7048 }
7049
7050 @override
7051 accept(AstVisitor visitor) => visitor.visitMethodInvocation(this);
7052
7053 @override
7054 void visitChildren(AstVisitor visitor) {
7055 _safelyVisitChild(_target, visitor);
7056 _safelyVisitChild(_methodName, visitor);
7057 _safelyVisitChild(_typeArguments, visitor);
7058 _safelyVisitChild(_argumentList, visitor);
7059 }
7060 }
7061
7062 /**
7063 * A node that declares a single name within the scope of a compilation unit.
7064 */
7065 abstract class NamedCompilationUnitMemberImpl extends CompilationUnitMemberImpl
7066 implements NamedCompilationUnitMember {
7067 /**
7068 * The name of the member being declared.
7069 */
7070 SimpleIdentifier _name;
7071
7072 /**
7073 * Initialize a newly created compilation unit member with the given [name].
7074 * Either or both of the [comment] and [metadata] can be `null` if the member
7075 * does not have the corresponding attribute.
7076 */
7077 NamedCompilationUnitMemberImpl(
7078 Comment comment, List<Annotation> metadata, SimpleIdentifier name)
7079 : super(comment, metadata) {
7080 _name = _becomeParentOf(name);
7081 }
7082
7083 @override
7084 SimpleIdentifier get name => _name;
7085
7086 @override
7087 void set name(SimpleIdentifier identifier) {
7088 _name = _becomeParentOf(identifier);
7089 }
7090 }
7091
7092 /**
7093 * An expression that has a name associated with it. They are used in method
7094 * invocations when there are named parameters.
7095 *
7096 * > namedExpression ::=
7097 * > [Label] [Expression]
7098 */
7099 class NamedExpressionImpl extends ExpressionImpl implements NamedExpression {
7100 /**
7101 * The name associated with the expression.
7102 */
7103 Label _name;
7104
7105 /**
7106 * The expression with which the name is associated.
7107 */
7108 Expression _expression;
7109
7110 /**
7111 * Initialize a newly created named expression..
7112 */
7113 NamedExpressionImpl(Label name, Expression expression) {
7114 _name = _becomeParentOf(name);
7115 _expression = _becomeParentOf(expression);
7116 }
7117
7118 @override
7119 Token get beginToken => _name.beginToken;
7120
7121 @override
7122 Iterable get childEntities =>
7123 new ChildEntities()..add(_name)..add(_expression);
7124
7125 @override
7126 ParameterElement get element {
7127 Element element = _name.label.staticElement;
7128 if (element is ParameterElement) {
7129 return element;
7130 }
7131 return null;
7132 }
7133
7134 @override
7135 Token get endToken => _expression.endToken;
7136
7137 @override
7138 Expression get expression => _expression;
7139
7140 @override
7141 void set expression(Expression expression) {
7142 _expression = _becomeParentOf(expression);
7143 }
7144
7145 @override
7146 Label get name => _name;
7147
7148 @override
7149 void set name(Label identifier) {
7150 _name = _becomeParentOf(identifier);
7151 }
7152
7153 @override
7154 int get precedence => 0;
7155
7156 @override
7157 accept(AstVisitor visitor) => visitor.visitNamedExpression(this);
7158
7159 @override
7160 void visitChildren(AstVisitor visitor) {
7161 _safelyVisitChild(_name, visitor);
7162 _safelyVisitChild(_expression, visitor);
7163 }
7164 }
7165
7166 /**
7167 * A node that represents a directive that impacts the namespace of a library.
7168 *
7169 * > directive ::=
7170 * > [ExportDirective]
7171 * > | [ImportDirective]
7172 */
7173 abstract class NamespaceDirectiveImpl extends UriBasedDirectiveImpl
7174 implements NamespaceDirective {
7175 /**
7176 * The token representing the 'import' or 'export' keyword.
7177 */
7178 Token keyword;
7179
7180 /**
7181 * The configurations used to control which library will actually be loaded at
7182 * run-time.
7183 */
7184 NodeList<Configuration> _configurations;
7185
7186 /**
7187 * The combinators used to control which names are imported or exported.
7188 */
7189 NodeList<Combinator> _combinators;
7190
7191 /**
7192 * The semicolon terminating the directive.
7193 */
7194 Token semicolon;
7195
7196 /**
7197 * Initialize a newly created namespace directive. Either or both of the
7198 * [comment] and [metadata] can be `null` if the directive does not have the
7199 * corresponding attribute. The list of [combinators] can be `null` if there
7200 * are no combinators.
7201 */
7202 NamespaceDirectiveImpl(
7203 Comment comment,
7204 List<Annotation> metadata,
7205 this.keyword,
7206 StringLiteral libraryUri,
7207 List<Configuration> configurations,
7208 List<Combinator> combinators,
7209 this.semicolon)
7210 : super(comment, metadata, libraryUri) {
7211 _configurations = new NodeList<Configuration>(this, configurations);
7212 _combinators = new NodeList<Combinator>(this, combinators);
7213 }
7214
7215 @override
7216 NodeList<Combinator> get combinators => _combinators;
7217
7218 @override
7219 NodeList<Configuration> get configurations => _configurations;
7220
7221 @override
7222 Token get endToken => semicolon;
7223
7224 @override
7225 Token get firstTokenAfterCommentAndMetadata => keyword;
7226
7227 @override
7228 LibraryElement get uriElement;
7229 }
7230
7231 /**
7232 * The "native" clause in an class declaration.
7233 *
7234 * > nativeClause ::=
7235 * > 'native' [StringLiteral]
7236 */
7237 class NativeClauseImpl extends AstNodeImpl implements NativeClause {
7238 /**
7239 * The token representing the 'native' keyword.
7240 */
7241 Token nativeKeyword;
7242
7243 /**
7244 * The name of the native object that implements the class.
7245 */
7246 StringLiteral _name;
7247
7248 /**
7249 * Initialize a newly created native clause.
7250 */
7251 NativeClauseImpl(this.nativeKeyword, StringLiteral name) {
7252 _name = _becomeParentOf(name);
7253 }
7254
7255 @override
7256 Token get beginToken => nativeKeyword;
7257
7258 @override
7259 Iterable get childEntities =>
7260 new ChildEntities()..add(nativeKeyword)..add(_name);
7261
7262 @override
7263 Token get endToken => _name.endToken;
7264
7265 @override
7266 StringLiteral get name => _name;
7267
7268 @override
7269 void set name(StringLiteral name) {
7270 _name = _becomeParentOf(name);
7271 }
7272
7273 @override
7274 accept(AstVisitor visitor) => visitor.visitNativeClause(this);
7275
7276 @override
7277 void visitChildren(AstVisitor visitor) {
7278 _safelyVisitChild(_name, visitor);
7279 }
7280 }
7281
7282 /**
7283 * A function body that consists of a native keyword followed by a string
7284 * literal.
7285 *
7286 * > nativeFunctionBody ::=
7287 * > 'native' [SimpleStringLiteral] ';'
7288 */
7289 class NativeFunctionBodyImpl extends FunctionBodyImpl
7290 implements NativeFunctionBody {
7291 /**
7292 * The token representing 'native' that marks the start of the function body.
7293 */
7294 Token nativeKeyword;
7295
7296 /**
7297 * The string literal, after the 'native' token.
7298 */
7299 StringLiteral _stringLiteral;
7300
7301 /**
7302 * The token representing the semicolon that marks the end of the function
7303 * body.
7304 */
7305 Token semicolon;
7306
7307 /**
7308 * Initialize a newly created function body consisting of the 'native' token,
7309 * a string literal, and a semicolon.
7310 */
7311 NativeFunctionBodyImpl(
7312 this.nativeKeyword, StringLiteral stringLiteral, this.semicolon) {
7313 _stringLiteral = _becomeParentOf(stringLiteral);
7314 }
7315
7316 @override
7317 Token get beginToken => nativeKeyword;
7318
7319 @override
7320 Iterable get childEntities => new ChildEntities()
7321 ..add(nativeKeyword)
7322 ..add(_stringLiteral)
7323 ..add(semicolon);
7324
7325 @override
7326 Token get endToken => semicolon;
7327
7328 @override
7329 StringLiteral get stringLiteral => _stringLiteral;
7330
7331 @override
7332 void set stringLiteral(StringLiteral stringLiteral) {
7333 _stringLiteral = _becomeParentOf(stringLiteral);
7334 }
7335
7336 @override
7337 accept(AstVisitor visitor) => visitor.visitNativeFunctionBody(this);
7338
7339 @override
7340 void visitChildren(AstVisitor visitor) {
7341 _safelyVisitChild(_stringLiteral, visitor);
7342 }
7343 }
7344
7345 /**
7346 * A list of AST nodes that have a common parent.
7347 */
7348 class NodeListImpl<E extends AstNode> extends Object
7349 with ListMixin<E>
7350 implements NodeList<E> {
7351 /**
7352 * The node that is the parent of each of the elements in the list.
7353 */
7354 AstNodeImpl owner;
7355
7356 /**
7357 * The elements contained in the list.
7358 */
7359 List<E> _elements = <E>[];
7360
7361 /**
7362 * Initialize a newly created list of nodes such that all of the nodes that
7363 * are added to the list will have their parent set to the given [owner]. The
7364 * list will initially be populated with the given [elements].
7365 */
7366 NodeListImpl(this.owner, [List<E> elements]) {
7367 addAll(elements);
7368 }
7369
7370 @override
7371 Token get beginToken {
7372 if (_elements.length == 0) {
7373 return null;
7374 }
7375 return _elements[0].beginToken;
7376 }
7377
7378 @override
7379 Token get endToken {
7380 int length = _elements.length;
7381 if (length == 0) {
7382 return null;
7383 }
7384 return _elements[length - 1].endToken;
7385 }
7386
7387 int get length => _elements.length;
7388
7389 @deprecated // Never intended for public use.
7390 @override
7391 void set length(int newLength) {
7392 throw new UnsupportedError("Cannot resize NodeList.");
7393 }
7394
7395 E operator [](int index) {
7396 if (index < 0 || index >= _elements.length) {
7397 throw new RangeError("Index: $index, Size: ${_elements.length}");
7398 }
7399 return _elements[index];
7400 }
7401
7402 void operator []=(int index, E node) {
7403 if (index < 0 || index >= _elements.length) {
7404 throw new RangeError("Index: $index, Size: ${_elements.length}");
7405 }
7406 owner._becomeParentOf(node);
7407 _elements[index] = node;
7408 }
7409
7410 @override
7411 accept(AstVisitor visitor) {
7412 int length = _elements.length;
7413 for (var i = 0; i < length; i++) {
7414 _elements[i].accept(visitor);
7415 }
7416 }
7417
7418 @override
7419 void add(E node) {
7420 insert(length, node);
7421 }
7422
7423 @override
7424 bool addAll(Iterable<E> nodes) {
7425 if (nodes != null && !nodes.isEmpty) {
7426 _elements.addAll(nodes);
7427 for (E node in nodes) {
7428 owner._becomeParentOf(node);
7429 }
7430 return true;
7431 }
7432 return false;
7433 }
7434
7435 @override
7436 void clear() {
7437 _elements = <E>[];
7438 }
7439
7440 @override
7441 void insert(int index, E node) {
7442 int length = _elements.length;
7443 if (index < 0 || index > length) {
7444 throw new RangeError("Index: $index, Size: ${_elements.length}");
7445 }
7446 owner._becomeParentOf(node);
7447 if (length == 0) {
7448 _elements.add(node);
7449 } else {
7450 _elements.insert(index, node);
7451 }
7452 }
7453
7454 @override
7455 E removeAt(int index) {
7456 if (index < 0 || index >= _elements.length) {
7457 throw new RangeError("Index: $index, Size: ${_elements.length}");
7458 }
7459 E removedNode = _elements[index];
7460 _elements.removeAt(index);
7461 return removedNode;
7462 }
7463 }
7464
7465 /**
7466 * A formal parameter that is required (is not optional).
7467 *
7468 * > normalFormalParameter ::=
7469 * > [FunctionTypedFormalParameter]
7470 * > | [FieldFormalParameter]
7471 * > | [SimpleFormalParameter]
7472 */
7473 abstract class NormalFormalParameterImpl extends FormalParameterImpl
7474 implements NormalFormalParameter {
7475 /**
7476 * The documentation comment associated with this parameter, or `null` if this
7477 * parameter does not have a documentation comment associated with it.
7478 */
7479 Comment _comment;
7480
7481 /**
7482 * The annotations associated with this parameter.
7483 */
7484 NodeList<Annotation> _metadata;
7485
7486 /**
7487 * The name of the parameter being declared.
7488 */
7489 SimpleIdentifier _identifier;
7490
7491 /**
7492 * Initialize a newly created formal parameter. Either or both of the
7493 * [comment] and [metadata] can be `null` if the parameter does not have the
7494 * corresponding attribute.
7495 */
7496 NormalFormalParameterImpl(
7497 Comment comment, List<Annotation> metadata, SimpleIdentifier identifier) {
7498 _comment = _becomeParentOf(comment);
7499 _metadata = new NodeList<Annotation>(this, metadata);
7500 _identifier = _becomeParentOf(identifier);
7501 }
7502
7503 @override
7504 Comment get documentationComment => _comment;
7505
7506 @override
7507 void set documentationComment(Comment comment) {
7508 _comment = _becomeParentOf(comment);
7509 }
7510
7511 @override
7512 SimpleIdentifier get identifier => _identifier;
7513
7514 @override
7515 void set identifier(SimpleIdentifier identifier) {
7516 _identifier = _becomeParentOf(identifier);
7517 }
7518
7519 @override
7520 ParameterKind get kind {
7521 AstNode parent = this.parent;
7522 if (parent is DefaultFormalParameter) {
7523 return parent.kind;
7524 }
7525 return ParameterKind.REQUIRED;
7526 }
7527
7528 @override
7529 NodeList<Annotation> get metadata => _metadata;
7530
7531 @override
7532 void set metadata(List<Annotation> metadata) {
7533 _metadata.clear();
7534 _metadata.addAll(metadata);
7535 }
7536
7537 @override
7538 List<AstNode> get sortedCommentAndAnnotations {
7539 return <AstNode>[]
7540 ..add(_comment)
7541 ..addAll(_metadata)
7542 ..sort(AstNode.LEXICAL_ORDER);
7543 }
7544
7545 ChildEntities get _childEntities {
7546 ChildEntities result = new ChildEntities();
7547 if (_commentIsBeforeAnnotations()) {
7548 result
7549 ..add(_comment)
7550 ..addAll(_metadata);
7551 } else {
7552 result.addAll(sortedCommentAndAnnotations);
7553 }
7554 return result;
7555 }
7556
7557 @override
7558 void visitChildren(AstVisitor visitor) {
7559 //
7560 // Note that subclasses are responsible for visiting the identifier because
7561 // they often need to visit other nodes before visiting the identifier.
7562 //
7563 if (_commentIsBeforeAnnotations()) {
7564 _safelyVisitChild(_comment, visitor);
7565 _metadata.accept(visitor);
7566 } else {
7567 for (AstNode child in sortedCommentAndAnnotations) {
7568 child.accept(visitor);
7569 }
7570 }
7571 }
7572
7573 /**
7574 * Return `true` if the comment is lexically before any annotations.
7575 */
7576 bool _commentIsBeforeAnnotations() {
7577 if (_comment == null || _metadata.isEmpty) {
7578 return true;
7579 }
7580 Annotation firstAnnotation = _metadata[0];
7581 return _comment.offset < firstAnnotation.offset;
7582 }
7583 }
7584
7585 /**
7586 * A null literal expression.
7587 *
7588 * > nullLiteral ::=
7589 * > 'null'
7590 */
7591 class NullLiteralImpl extends LiteralImpl implements NullLiteral {
7592 /**
7593 * The token representing the literal.
7594 */
7595 Token literal;
7596
7597 /**
7598 * Initialize a newly created null literal.
7599 */
7600 NullLiteralImpl(this.literal);
7601
7602 @override
7603 Token get beginToken => literal;
7604
7605 @override
7606 Iterable get childEntities => new ChildEntities()..add(literal);
7607
7608 @override
7609 Token get endToken => literal;
7610
7611 @override
7612 accept(AstVisitor visitor) => visitor.visitNullLiteral(this);
7613
7614 @override
7615 void visitChildren(AstVisitor visitor) {
7616 // There are no children to visit.
7617 }
7618 }
7619
7620 /**
7621 * A parenthesized expression.
7622 *
7623 * > parenthesizedExpression ::=
7624 * > '(' [Expression] ')'
7625 */
7626 class ParenthesizedExpressionImpl extends ExpressionImpl
7627 implements ParenthesizedExpression {
7628 /**
7629 * The left parenthesis.
7630 */
7631 Token leftParenthesis;
7632
7633 /**
7634 * The expression within the parentheses.
7635 */
7636 Expression _expression;
7637
7638 /**
7639 * The right parenthesis.
7640 */
7641 Token rightParenthesis;
7642
7643 /**
7644 * Initialize a newly created parenthesized expression.
7645 */
7646 ParenthesizedExpressionImpl(
7647 this.leftParenthesis, Expression expression, this.rightParenthesis) {
7648 _expression = _becomeParentOf(expression);
7649 }
7650
7651 @override
7652 Token get beginToken => leftParenthesis;
7653
7654 @override
7655 Iterable get childEntities => new ChildEntities()
7656 ..add(leftParenthesis)
7657 ..add(_expression)
7658 ..add(rightParenthesis);
7659
7660 @override
7661 Token get endToken => rightParenthesis;
7662
7663 @override
7664 Expression get expression => _expression;
7665
7666 @override
7667 void set expression(Expression expression) {
7668 _expression = _becomeParentOf(expression);
7669 }
7670
7671 @override
7672 int get precedence => 15;
7673
7674 @override
7675 accept(AstVisitor visitor) => visitor.visitParenthesizedExpression(this);
7676
7677 @override
7678 void visitChildren(AstVisitor visitor) {
7679 _safelyVisitChild(_expression, visitor);
7680 }
7681 }
7682
7683 /**
7684 * A part directive.
7685 *
7686 * > partDirective ::=
7687 * > [Annotation] 'part' [StringLiteral] ';'
7688 */
7689 class PartDirectiveImpl extends UriBasedDirectiveImpl implements PartDirective {
7690 /**
7691 * The token representing the 'part' keyword.
7692 */
7693 Token partKeyword;
7694
7695 /**
7696 * The semicolon terminating the directive.
7697 */
7698 Token semicolon;
7699
7700 /**
7701 * Initialize a newly created part directive. Either or both of the [comment]
7702 * and [metadata] can be `null` if the directive does not have the
7703 * corresponding attribute.
7704 */
7705 PartDirectiveImpl(Comment comment, List<Annotation> metadata,
7706 this.partKeyword, StringLiteral partUri, this.semicolon)
7707 : super(comment, metadata, partUri);
7708
7709 @override
7710 Iterable get childEntities =>
7711 super._childEntities..add(partKeyword)..add(_uri)..add(semicolon);
7712
7713 @override
7714 Token get endToken => semicolon;
7715
7716 @override
7717 Token get firstTokenAfterCommentAndMetadata => partKeyword;
7718
7719 @override
7720 Token get keyword => partKeyword;
7721
7722 @override
7723 CompilationUnitElement get uriElement => element as CompilationUnitElement;
7724
7725 @override
7726 accept(AstVisitor visitor) => visitor.visitPartDirective(this);
7727 }
7728
7729 /**
7730 * A part-of directive.
7731 *
7732 * > partOfDirective ::=
7733 * > [Annotation] 'part' 'of' [Identifier] ';'
7734 */
7735 class PartOfDirectiveImpl extends DirectiveImpl implements PartOfDirective {
7736 /**
7737 * The token representing the 'part' keyword.
7738 */
7739 Token partKeyword;
7740
7741 /**
7742 * The token representing the 'of' keyword.
7743 */
7744 Token ofKeyword;
7745
7746 /**
7747 * The name of the library that the containing compilation unit is part of.
7748 */
7749 LibraryIdentifier _libraryName;
7750
7751 /**
7752 * The semicolon terminating the directive.
7753 */
7754 Token semicolon;
7755
7756 /**
7757 * Initialize a newly created part-of directive. Either or both of the
7758 * [comment] and [metadata] can be `null` if the directive does not have the
7759 * corresponding attribute.
7760 */
7761 PartOfDirectiveImpl(
7762 Comment comment,
7763 List<Annotation> metadata,
7764 this.partKeyword,
7765 this.ofKeyword,
7766 LibraryIdentifier libraryName,
7767 this.semicolon)
7768 : super(comment, metadata) {
7769 _libraryName = _becomeParentOf(libraryName);
7770 }
7771
7772 @override
7773 Iterable get childEntities => super._childEntities
7774 ..add(partKeyword)
7775 ..add(ofKeyword)
7776 ..add(_libraryName)
7777 ..add(semicolon);
7778
7779 @override
7780 Token get endToken => semicolon;
7781
7782 @override
7783 Token get firstTokenAfterCommentAndMetadata => partKeyword;
7784
7785 @override
7786 Token get keyword => partKeyword;
7787
7788 @override
7789 LibraryIdentifier get libraryName => _libraryName;
7790
7791 @override
7792 void set libraryName(LibraryIdentifier libraryName) {
7793 _libraryName = _becomeParentOf(libraryName);
7794 }
7795
7796 @override
7797 accept(AstVisitor visitor) => visitor.visitPartOfDirective(this);
7798
7799 @override
7800 void visitChildren(AstVisitor visitor) {
7801 super.visitChildren(visitor);
7802 _safelyVisitChild(_libraryName, visitor);
7803 }
7804 }
7805
7806 /**
7807 * A postfix unary expression.
7808 *
7809 * > postfixExpression ::=
7810 * > [Expression] [Token]
7811 */
7812 class PostfixExpressionImpl extends ExpressionImpl
7813 implements PostfixExpression {
7814 /**
7815 * The expression computing the operand for the operator.
7816 */
7817 Expression _operand;
7818
7819 /**
7820 * The postfix operator being applied to the operand.
7821 */
7822 Token operator;
7823
7824 /**
7825 * The element associated with this the operator based on the propagated type
7826 * of the operand, or `null` if the AST structure has not been resolved, if
7827 * the operator is not user definable, or if the operator could not be
7828 * resolved.
7829 */
7830 MethodElement propagatedElement;
7831
7832 /**
7833 * The element associated with the operator based on the static type of the
7834 * operand, or `null` if the AST structure has not been resolved, if the
7835 * operator is not user definable, or if the operator could not be resolved.
7836 */
7837 MethodElement staticElement;
7838
7839 /**
7840 * Initialize a newly created postfix expression.
7841 */
7842 PostfixExpressionImpl(Expression operand, this.operator) {
7843 _operand = _becomeParentOf(operand);
7844 }
7845
7846 @override
7847 Token get beginToken => _operand.beginToken;
7848
7849 @override
7850 MethodElement get bestElement {
7851 MethodElement element = propagatedElement;
7852 if (element == null) {
7853 element = staticElement;
7854 }
7855 return element;
7856 }
7857
7858 @override
7859 Iterable get childEntities =>
7860 new ChildEntities()..add(_operand)..add(operator);
7861
7862 @override
7863 Token get endToken => operator;
7864
7865 @override
7866 Expression get operand => _operand;
7867
7868 @override
7869 void set operand(Expression expression) {
7870 _operand = _becomeParentOf(expression);
7871 }
7872
7873 @override
7874 int get precedence => 15;
7875
7876 /**
7877 * If the AST structure has been resolved, and the function being invoked is
7878 * known based on propagated type information, then return the parameter
7879 * element representing the parameter to which the value of the operand will
7880 * be bound. Otherwise, return `null`.
7881 */
7882 ParameterElement get _propagatedParameterElementForOperand {
7883 if (propagatedElement == null) {
7884 return null;
7885 }
7886 List<ParameterElement> parameters = propagatedElement.parameters;
7887 if (parameters.length < 1) {
7888 return null;
7889 }
7890 return parameters[0];
7891 }
7892
7893 /**
7894 * If the AST structure has been resolved, and the function being invoked is
7895 * known based on static type information, then return the parameter element
7896 * representing the parameter to which the value of the operand will be bound.
7897 * Otherwise, return `null`.
7898 */
7899 ParameterElement get _staticParameterElementForOperand {
7900 if (staticElement == null) {
7901 return null;
7902 }
7903 List<ParameterElement> parameters = staticElement.parameters;
7904 if (parameters.length < 1) {
7905 return null;
7906 }
7907 return parameters[0];
7908 }
7909
7910 @override
7911 accept(AstVisitor visitor) => visitor.visitPostfixExpression(this);
7912
7913 @override
7914 void visitChildren(AstVisitor visitor) {
7915 _safelyVisitChild(_operand, visitor);
7916 }
7917 }
7918
7919 /**
7920 * An identifier that is prefixed or an access to an object property where the
7921 * target of the property access is a simple identifier.
7922 *
7923 * > prefixedIdentifier ::=
7924 * > [SimpleIdentifier] '.' [SimpleIdentifier]
7925 */
7926 class PrefixedIdentifierImpl extends IdentifierImpl
7927 implements PrefixedIdentifier {
7928 /**
7929 * The prefix associated with the library in which the identifier is defined.
7930 */
7931 SimpleIdentifier _prefix;
7932
7933 /**
7934 * The period used to separate the prefix from the identifier.
7935 */
7936 Token period;
7937
7938 /**
7939 * The identifier being prefixed.
7940 */
7941 SimpleIdentifier _identifier;
7942
7943 /**
7944 * Initialize a newly created prefixed identifier.
7945 */
7946 PrefixedIdentifierImpl(
7947 SimpleIdentifier prefix, this.period, SimpleIdentifier identifier) {
7948 _prefix = _becomeParentOf(prefix);
7949 _identifier = _becomeParentOf(identifier);
7950 }
7951
7952 @override
7953 Token get beginToken => _prefix.beginToken;
7954
7955 @override
7956 Element get bestElement {
7957 if (_identifier == null) {
7958 return null;
7959 }
7960 return _identifier.bestElement;
7961 }
7962
7963 @override
7964 Iterable get childEntities =>
7965 new ChildEntities()..add(_prefix)..add(period)..add(_identifier);
7966
7967 @override
7968 Token get endToken => _identifier.endToken;
7969
7970 @override
7971 SimpleIdentifier get identifier => _identifier;
7972
7973 @override
7974 void set identifier(SimpleIdentifier identifier) {
7975 _identifier = _becomeParentOf(identifier);
7976 }
7977
7978 @override
7979 bool get isDeferred {
7980 Element element = _prefix.staticElement;
7981 if (element is! PrefixElement) {
7982 return false;
7983 }
7984 PrefixElement prefixElement = element as PrefixElement;
7985 List<ImportElement> imports =
7986 prefixElement.enclosingElement.getImportsWithPrefix(prefixElement);
7987 if (imports.length != 1) {
7988 return false;
7989 }
7990 return imports[0].isDeferred;
7991 }
7992
7993 @override
7994 String get name => "${_prefix.name}.${_identifier.name}";
7995
7996 @override
7997 int get precedence => 15;
7998
7999 @override
8000 SimpleIdentifier get prefix => _prefix;
8001
8002 @override
8003 void set prefix(SimpleIdentifier identifier) {
8004 _prefix = _becomeParentOf(identifier);
8005 }
8006
8007 @override
8008 Element get propagatedElement {
8009 if (_identifier == null) {
8010 return null;
8011 }
8012 return _identifier.propagatedElement;
8013 }
8014
8015 @override
8016 Element get staticElement {
8017 if (_identifier == null) {
8018 return null;
8019 }
8020 return _identifier.staticElement;
8021 }
8022
8023 @override
8024 accept(AstVisitor visitor) => visitor.visitPrefixedIdentifier(this);
8025
8026 @override
8027 void visitChildren(AstVisitor visitor) {
8028 _safelyVisitChild(_prefix, visitor);
8029 _safelyVisitChild(_identifier, visitor);
8030 }
8031 }
8032
8033 /**
8034 * A prefix unary expression.
8035 *
8036 * > prefixExpression ::=
8037 * > [Token] [Expression]
8038 */
8039 class PrefixExpressionImpl extends ExpressionImpl implements PrefixExpression {
8040 /**
8041 * The prefix operator being applied to the operand.
8042 */
8043 Token operator;
8044
8045 /**
8046 * The expression computing the operand for the operator.
8047 */
8048 Expression _operand;
8049
8050 /**
8051 * The element associated with the operator based on the static type of the
8052 * operand, or `null` if the AST structure has not been resolved, if the
8053 * operator is not user definable, or if the operator could not be resolved.
8054 */
8055 MethodElement staticElement;
8056
8057 /**
8058 * The element associated with the operator based on the propagated type of
8059 * the operand, or `null` if the AST structure has not been resolved, if the
8060 * operator is not user definable, or if the operator could not be resolved.
8061 */
8062 MethodElement propagatedElement;
8063
8064 /**
8065 * Initialize a newly created prefix expression.
8066 */
8067 PrefixExpressionImpl(this.operator, Expression operand) {
8068 _operand = _becomeParentOf(operand);
8069 }
8070
8071 @override
8072 Token get beginToken => operator;
8073
8074 @override
8075 MethodElement get bestElement {
8076 MethodElement element = propagatedElement;
8077 if (element == null) {
8078 element = staticElement;
8079 }
8080 return element;
8081 }
8082
8083 @override
8084 Iterable get childEntities =>
8085 new ChildEntities()..add(operator)..add(_operand);
8086
8087 @override
8088 Token get endToken => _operand.endToken;
8089
8090 @override
8091 Expression get operand => _operand;
8092
8093 @override
8094 void set operand(Expression expression) {
8095 _operand = _becomeParentOf(expression);
8096 }
8097
8098 @override
8099 int get precedence => 14;
8100
8101 /**
8102 * If the AST structure has been resolved, and the function being invoked is
8103 * known based on propagated type information, then return the parameter
8104 * element representing the parameter to which the value of the operand will
8105 * be bound. Otherwise, return `null`.
8106 */
8107 ParameterElement get _propagatedParameterElementForOperand {
8108 if (propagatedElement == null) {
8109 return null;
8110 }
8111 List<ParameterElement> parameters = propagatedElement.parameters;
8112 if (parameters.length < 1) {
8113 return null;
8114 }
8115 return parameters[0];
8116 }
8117
8118 /**
8119 * If the AST structure has been resolved, and the function being invoked is
8120 * known based on static type information, then return the parameter element
8121 * representing the parameter to which the value of the operand will be bound.
8122 * Otherwise, return `null`.
8123 */
8124 ParameterElement get _staticParameterElementForOperand {
8125 if (staticElement == null) {
8126 return null;
8127 }
8128 List<ParameterElement> parameters = staticElement.parameters;
8129 if (parameters.length < 1) {
8130 return null;
8131 }
8132 return parameters[0];
8133 }
8134
8135 @override
8136 accept(AstVisitor visitor) => visitor.visitPrefixExpression(this);
8137
8138 @override
8139 void visitChildren(AstVisitor visitor) {
8140 _safelyVisitChild(_operand, visitor);
8141 }
8142 }
8143
8144 /**
8145 * The access of a property of an object.
8146 *
8147 * Note, however, that accesses to properties of objects can also be represented
8148 * as [PrefixedIdentifier] nodes in cases where the target is also a simple
8149 * identifier.
8150 *
8151 * > propertyAccess ::=
8152 * > [Expression] '.' [SimpleIdentifier]
8153 */
8154 class PropertyAccessImpl extends ExpressionImpl implements PropertyAccess {
8155 /**
8156 * The expression computing the object defining the property being accessed.
8157 */
8158 Expression _target;
8159
8160 /**
8161 * The property access operator.
8162 */
8163 Token operator;
8164
8165 /**
8166 * The name of the property being accessed.
8167 */
8168 SimpleIdentifier _propertyName;
8169
8170 /**
8171 * Initialize a newly created property access expression.
8172 */
8173 PropertyAccessImpl(
8174 Expression target, this.operator, SimpleIdentifier propertyName) {
8175 _target = _becomeParentOf(target);
8176 _propertyName = _becomeParentOf(propertyName);
8177 }
8178
8179 @override
8180 Token get beginToken {
8181 if (_target != null) {
8182 return _target.beginToken;
8183 }
8184 return operator;
8185 }
8186
8187 @override
8188 Iterable get childEntities =>
8189 new ChildEntities()..add(_target)..add(operator)..add(_propertyName);
8190
8191 @override
8192 Token get endToken => _propertyName.endToken;
8193
8194 @override
8195 bool get isAssignable => true;
8196
8197 @override
8198 bool get isCascaded =>
8199 operator != null && operator.type == TokenType.PERIOD_PERIOD;
8200
8201 @override
8202 int get precedence => 15;
8203
8204 @override
8205 SimpleIdentifier get propertyName => _propertyName;
8206
8207 @override
8208 void set propertyName(SimpleIdentifier identifier) {
8209 _propertyName = _becomeParentOf(identifier);
8210 }
8211
8212 @override
8213 Expression get realTarget {
8214 if (isCascaded) {
8215 AstNode ancestor = parent;
8216 while (ancestor is! CascadeExpression) {
8217 if (ancestor == null) {
8218 return _target;
8219 }
8220 ancestor = ancestor.parent;
8221 }
8222 return (ancestor as CascadeExpression).target;
8223 }
8224 return _target;
8225 }
8226
8227 @override
8228 Expression get target => _target;
8229
8230 @override
8231 void set target(Expression expression) {
8232 _target = _becomeParentOf(expression);
8233 }
8234
8235 @override
8236 accept(AstVisitor visitor) => visitor.visitPropertyAccess(this);
8237
8238 @override
8239 void visitChildren(AstVisitor visitor) {
8240 _safelyVisitChild(_target, visitor);
8241 _safelyVisitChild(_propertyName, visitor);
8242 }
8243 }
8244
8245 /**
8246 * The invocation of a constructor in the same class from within a constructor's
8247 * initialization list.
8248 *
8249 * > redirectingConstructorInvocation ::=
8250 * > 'this' ('.' identifier)? arguments
8251 */
8252 class RedirectingConstructorInvocationImpl extends ConstructorInitializerImpl
8253 implements RedirectingConstructorInvocation {
8254 /**
8255 * The token for the 'this' keyword.
8256 */
8257 Token thisKeyword;
8258
8259 /**
8260 * The token for the period before the name of the constructor that is being
8261 * invoked, or `null` if the unnamed constructor is being invoked.
8262 */
8263 Token period;
8264
8265 /**
8266 * The name of the constructor that is being invoked, or `null` if the unnamed
8267 * constructor is being invoked.
8268 */
8269 SimpleIdentifier _constructorName;
8270
8271 /**
8272 * The list of arguments to the constructor.
8273 */
8274 ArgumentList _argumentList;
8275
8276 /**
8277 * The element associated with the constructor based on static type
8278 * information, or `null` if the AST structure has not been resolved or if the
8279 * constructor could not be resolved.
8280 */
8281 ConstructorElement staticElement;
8282
8283 /**
8284 * Initialize a newly created redirecting invocation to invoke the constructor
8285 * with the given name with the given arguments. The [constructorName] can be
8286 * `null` if the constructor being invoked is the unnamed constructor.
8287 */
8288 RedirectingConstructorInvocationImpl(this.thisKeyword, this.period,
8289 SimpleIdentifier constructorName, ArgumentList argumentList) {
8290 _constructorName = _becomeParentOf(constructorName);
8291 _argumentList = _becomeParentOf(argumentList);
8292 }
8293
8294 @override
8295 ArgumentList get argumentList => _argumentList;
8296
8297 @override
8298 void set argumentList(ArgumentList argumentList) {
8299 _argumentList = _becomeParentOf(argumentList);
8300 }
8301
8302 @override
8303 Token get beginToken => thisKeyword;
8304
8305 @override
8306 Iterable get childEntities => new ChildEntities()
8307 ..add(thisKeyword)
8308 ..add(period)
8309 ..add(_constructorName)
8310 ..add(_argumentList);
8311
8312 @override
8313 SimpleIdentifier get constructorName => _constructorName;
8314
8315 @override
8316 void set constructorName(SimpleIdentifier identifier) {
8317 _constructorName = _becomeParentOf(identifier);
8318 }
8319
8320 @override
8321 Token get endToken => _argumentList.endToken;
8322
8323 @override
8324 accept(AstVisitor visitor) =>
8325 visitor.visitRedirectingConstructorInvocation(this);
8326
8327 @override
8328 void visitChildren(AstVisitor visitor) {
8329 _safelyVisitChild(_constructorName, visitor);
8330 _safelyVisitChild(_argumentList, visitor);
8331 }
8332 }
8333
8334 /**
8335 * A rethrow expression.
8336 *
8337 * > rethrowExpression ::=
8338 * > 'rethrow'
8339 */
8340 class RethrowExpressionImpl extends ExpressionImpl
8341 implements RethrowExpression {
8342 /**
8343 * The token representing the 'rethrow' keyword.
8344 */
8345 Token rethrowKeyword;
8346
8347 /**
8348 * Initialize a newly created rethrow expression.
8349 */
8350 RethrowExpressionImpl(this.rethrowKeyword);
8351
8352 @override
8353 Token get beginToken => rethrowKeyword;
8354
8355 @override
8356 Iterable get childEntities => new ChildEntities()..add(rethrowKeyword);
8357
8358 @override
8359 Token get endToken => rethrowKeyword;
8360
8361 @override
8362 int get precedence => 0;
8363
8364 @override
8365 accept(AstVisitor visitor) => visitor.visitRethrowExpression(this);
8366
8367 @override
8368 void visitChildren(AstVisitor visitor) {
8369 // There are no children to visit.
8370 }
8371 }
8372
8373 /**
8374 * A return statement.
8375 *
8376 * > returnStatement ::=
8377 * > 'return' [Expression]? ';'
8378 */
8379 class ReturnStatementImpl extends StatementImpl implements ReturnStatement {
8380 /**
8381 * The token representing the 'return' keyword.
8382 */
8383 Token returnKeyword;
8384
8385 /**
8386 * The expression computing the value to be returned, or `null` if no explicit
8387 * value was provided.
8388 */
8389 Expression _expression;
8390
8391 /**
8392 * The semicolon terminating the statement.
8393 */
8394 Token semicolon;
8395
8396 /**
8397 * Initialize a newly created return statement. The [expression] can be `null`
8398 * if no explicit value was provided.
8399 */
8400 ReturnStatementImpl(
8401 this.returnKeyword, Expression expression, this.semicolon) {
8402 _expression = _becomeParentOf(expression);
8403 }
8404
8405 @override
8406 Token get beginToken => returnKeyword;
8407
8408 @override
8409 Iterable get childEntities =>
8410 new ChildEntities()..add(returnKeyword)..add(_expression)..add(semicolon);
8411
8412 @override
8413 Token get endToken => semicolon;
8414
8415 @override
8416 Expression get expression => _expression;
8417
8418 @override
8419 void set expression(Expression expression) {
8420 _expression = _becomeParentOf(expression);
8421 }
8422
8423 @override
8424 accept(AstVisitor visitor) => visitor.visitReturnStatement(this);
8425
8426 @override
8427 void visitChildren(AstVisitor visitor) {
8428 _safelyVisitChild(_expression, visitor);
8429 }
8430 }
8431
8432 /**
8433 * A script tag that can optionally occur at the beginning of a compilation unit .
8434 *
8435 * > scriptTag ::=
8436 * > '#!' (~NEWLINE)* NEWLINE
8437 */
8438 class ScriptTagImpl extends AstNodeImpl implements ScriptTag {
8439 /**
8440 * The token representing this script tag.
8441 */
8442 Token scriptTag;
8443
8444 /**
8445 * Initialize a newly created script tag.
8446 */
8447 ScriptTagImpl(this.scriptTag);
8448
8449 @override
8450 Token get beginToken => scriptTag;
8451
8452 @override
8453 Iterable get childEntities => new ChildEntities()..add(scriptTag);
8454
8455 @override
8456 Token get endToken => scriptTag;
8457
8458 @override
8459 accept(AstVisitor visitor) => visitor.visitScriptTag(this);
8460
8461 @override
8462 void visitChildren(AstVisitor visitor) {
8463 // There are no children to visit.
8464 }
8465 }
8466
8467 /**
8468 * A combinator that restricts the names being imported to those in a given list .
8469 *
8470 * > showCombinator ::=
8471 * > 'show' [SimpleIdentifier] (',' [SimpleIdentifier])*
8472 */
8473 class ShowCombinatorImpl extends CombinatorImpl implements ShowCombinator {
8474 /**
8475 * The list of names from the library that are made visible by this combinator .
8476 */
8477 NodeList<SimpleIdentifier> _shownNames;
8478
8479 /**
8480 * Initialize a newly created import show combinator.
8481 */
8482 ShowCombinatorImpl(Token keyword, List<SimpleIdentifier> shownNames)
8483 : super(keyword) {
8484 _shownNames = new NodeList<SimpleIdentifier>(this, shownNames);
8485 }
8486
8487 @override
8488 // TODO(paulberry): add commas.
8489 Iterable get childEntities => new ChildEntities()
8490 ..add(keyword)
8491 ..addAll(_shownNames);
8492
8493 @override
8494 Token get endToken => _shownNames.endToken;
8495
8496 @override
8497 NodeList<SimpleIdentifier> get shownNames => _shownNames;
8498
8499 @override
8500 accept(AstVisitor visitor) => visitor.visitShowCombinator(this);
8501
8502 @override
8503 void visitChildren(AstVisitor visitor) {
8504 _shownNames.accept(visitor);
8505 }
8506 }
8507
8508 /**
8509 * A simple formal parameter.
8510 *
8511 * > simpleFormalParameter ::=
8512 * > ('final' [TypeName] | 'var' | [TypeName])? [SimpleIdentifier]
8513 */
8514 class SimpleFormalParameterImpl extends NormalFormalParameterImpl
8515 implements SimpleFormalParameter {
8516 /**
8517 * The token representing either the 'final', 'const' or 'var' keyword, or
8518 * `null` if no keyword was used.
8519 */
8520 Token keyword;
8521
8522 /**
8523 * The name of the declared type of the parameter, or `null` if the parameter
8524 * does not have a declared type.
8525 */
8526 TypeName _type;
8527
8528 /**
8529 * Initialize a newly created formal parameter. Either or both of the
8530 * [comment] and [metadata] can be `null` if the parameter does not have the
8531 * corresponding attribute. The [keyword] can be `null` if a type was
8532 * specified. The [type] must be `null` if the keyword is 'var'.
8533 */
8534 SimpleFormalParameterImpl(Comment comment, List<Annotation> metadata,
8535 this.keyword, TypeName type, SimpleIdentifier identifier)
8536 : super(comment, metadata, identifier) {
8537 _type = _becomeParentOf(type);
8538 }
8539
8540 @override
8541 Token get beginToken {
8542 NodeList<Annotation> metadata = this.metadata;
8543 if (!metadata.isEmpty) {
8544 return metadata.beginToken;
8545 } else if (keyword != null) {
8546 return keyword;
8547 } else if (_type != null) {
8548 return _type.beginToken;
8549 }
8550 return identifier.beginToken;
8551 }
8552
8553 @override
8554 Iterable get childEntities =>
8555 super._childEntities..add(keyword)..add(_type)..add(identifier);
8556
8557 @override
8558 Token get endToken => identifier.endToken;
8559
8560 @override
8561 bool get isConst =>
8562 (keyword is KeywordToken) &&
8563 (keyword as KeywordToken).keyword == Keyword.CONST;
8564
8565 @override
8566 bool get isFinal =>
8567 (keyword is KeywordToken) &&
8568 (keyword as KeywordToken).keyword == Keyword.FINAL;
8569
8570 @override
8571 TypeName get type => _type;
8572
8573 @override
8574 void set type(TypeName typeName) {
8575 _type = _becomeParentOf(typeName);
8576 }
8577
8578 @override
8579 accept(AstVisitor visitor) => visitor.visitSimpleFormalParameter(this);
8580
8581 @override
8582 void visitChildren(AstVisitor visitor) {
8583 super.visitChildren(visitor);
8584 _safelyVisitChild(_type, visitor);
8585 _safelyVisitChild(identifier, visitor);
8586 }
8587 }
8588
8589 /**
8590 * A simple identifier.
8591 *
8592 * > simpleIdentifier ::=
8593 * > initialCharacter internalCharacter*
8594 * >
8595 * > initialCharacter ::= '_' | '$' | letter
8596 * >
8597 * > internalCharacter ::= '_' | '$' | letter | digit
8598 */
8599 class SimpleIdentifierImpl extends IdentifierImpl implements SimpleIdentifier {
8600 /**
8601 * The token representing the identifier.
8602 */
8603 Token token;
8604
8605 /**
8606 * The element associated with this identifier based on static type
8607 * information, or `null` if the AST structure has not been resolved or if
8608 * this identifier could not be resolved.
8609 */
8610 Element _staticElement;
8611
8612 /**
8613 * The element associated with this identifier based on propagated type
8614 * information, or `null` if the AST structure has not been resolved or if
8615 * this identifier could not be resolved.
8616 */
8617 Element _propagatedElement;
8618
8619 /**
8620 * If this expression is both in a getter and setter context, the
8621 * [AuxiliaryElements] will be set to hold onto the static and propagated
8622 * information. The auxiliary element will hold onto the elements from the
8623 * getter context.
8624 */
8625 AuxiliaryElements auxiliaryElements = null;
8626
8627 /**
8628 * Initialize a newly created identifier.
8629 */
8630 SimpleIdentifierImpl(this.token);
8631
8632 @override
8633 Token get beginToken => token;
8634
8635 @override
8636 Element get bestElement {
8637 if (_propagatedElement == null) {
8638 return _staticElement;
8639 }
8640 return _propagatedElement;
8641 }
8642
8643 @override
8644 Iterable get childEntities => new ChildEntities()..add(token);
8645
8646 @override
8647 Token get endToken => token;
8648
8649 @override
8650 bool get isQualified {
8651 AstNode parent = this.parent;
8652 if (parent is PrefixedIdentifier) {
8653 return identical(parent.identifier, this);
8654 }
8655 if (parent is PropertyAccess) {
8656 return identical(parent.propertyName, this);
8657 }
8658 if (parent is MethodInvocation) {
8659 MethodInvocation invocation = parent;
8660 return identical(invocation.methodName, this) &&
8661 invocation.realTarget != null;
8662 }
8663 return false;
8664 }
8665
8666 @override
8667 bool get isSynthetic => token.isSynthetic;
8668
8669 @override
8670 String get name => token.lexeme;
8671
8672 @override
8673 int get precedence => 16;
8674
8675 @override
8676 Element get propagatedElement => _propagatedElement;
8677
8678 @override
8679 void set propagatedElement(Element element) {
8680 _propagatedElement = _validateElement(element);
8681 }
8682
8683 @override
8684 Element get staticElement => _staticElement;
8685
8686 @override
8687 void set staticElement(Element element) {
8688 _staticElement = _validateElement(element);
8689 }
8690
8691 @override
8692 accept(AstVisitor visitor) => visitor.visitSimpleIdentifier(this);
8693
8694 @override
8695 bool inDeclarationContext() {
8696 // TODO(brianwilkerson) Convert this to a getter.
8697 AstNode parent = this.parent;
8698 if (parent is CatchClause) {
8699 CatchClause clause = parent;
8700 return identical(this, clause.exceptionParameter) ||
8701 identical(this, clause.stackTraceParameter);
8702 } else if (parent is ClassDeclaration) {
8703 return identical(this, parent.name);
8704 } else if (parent is ClassTypeAlias) {
8705 return identical(this, parent.name);
8706 } else if (parent is ConstructorDeclaration) {
8707 return identical(this, parent.name);
8708 } else if (parent is DeclaredIdentifier) {
8709 return identical(this, parent.identifier);
8710 } else if (parent is EnumDeclaration) {
8711 return identical(this, parent.name);
8712 } else if (parent is EnumConstantDeclaration) {
8713 return identical(this, parent.name);
8714 } else if (parent is FunctionDeclaration) {
8715 return identical(this, parent.name);
8716 } else if (parent is FunctionTypeAlias) {
8717 return identical(this, parent.name);
8718 } else if (parent is ImportDirective) {
8719 return identical(this, parent.prefix);
8720 } else if (parent is Label) {
8721 return identical(this, parent.label) &&
8722 (parent.parent is LabeledStatement);
8723 } else if (parent is MethodDeclaration) {
8724 return identical(this, parent.name);
8725 } else if (parent is FunctionTypedFormalParameter ||
8726 parent is SimpleFormalParameter) {
8727 return identical(this, (parent as NormalFormalParameter).identifier);
8728 } else if (parent is TypeParameter) {
8729 return identical(this, parent.name);
8730 } else if (parent is VariableDeclaration) {
8731 return identical(this, parent.name);
8732 }
8733 return false;
8734 }
8735
8736 @override
8737 bool inGetterContext() {
8738 // TODO(brianwilkerson) Convert this to a getter.
8739 AstNode parent = this.parent;
8740 AstNode target = this;
8741 // skip prefix
8742 if (parent is PrefixedIdentifier) {
8743 PrefixedIdentifier prefixed = parent as PrefixedIdentifier;
8744 if (identical(prefixed.prefix, this)) {
8745 return true;
8746 }
8747 parent = prefixed.parent;
8748 target = prefixed;
8749 } else if (parent is PropertyAccess) {
8750 PropertyAccess access = parent as PropertyAccess;
8751 if (identical(access.target, this)) {
8752 return true;
8753 }
8754 parent = access.parent;
8755 target = access;
8756 }
8757 // skip label
8758 if (parent is Label) {
8759 return false;
8760 }
8761 // analyze usage
8762 if (parent is AssignmentExpression) {
8763 if (identical(parent.leftHandSide, target) &&
8764 parent.operator.type == TokenType.EQ) {
8765 return false;
8766 }
8767 }
8768 if (parent is ForEachStatement) {
8769 if (identical(parent.identifier, target)) {
8770 return false;
8771 }
8772 }
8773 return true;
8774 }
8775
8776 @override
8777 bool inSetterContext() {
8778 // TODO(brianwilkerson) Convert this to a getter.
8779 AstNode parent = this.parent;
8780 AstNode target = this;
8781 // skip prefix
8782 if (parent is PrefixedIdentifier) {
8783 PrefixedIdentifier prefixed = parent as PrefixedIdentifier;
8784 // if this is the prefix, then return false
8785 if (identical(prefixed.prefix, this)) {
8786 return false;
8787 }
8788 parent = prefixed.parent;
8789 target = prefixed;
8790 } else if (parent is PropertyAccess) {
8791 PropertyAccess access = parent as PropertyAccess;
8792 if (identical(access.target, this)) {
8793 return false;
8794 }
8795 parent = access.parent;
8796 target = access;
8797 }
8798 // analyze usage
8799 if (parent is PrefixExpression) {
8800 return parent.operator.type.isIncrementOperator;
8801 } else if (parent is PostfixExpression) {
8802 return true;
8803 } else if (parent is AssignmentExpression) {
8804 return identical(parent.leftHandSide, target);
8805 } else if (parent is ForEachStatement) {
8806 return identical(parent.identifier, target);
8807 }
8808 return false;
8809 }
8810
8811 @override
8812 void visitChildren(AstVisitor visitor) {
8813 // There are no children to visit.
8814 }
8815
8816 /**
8817 * Return the given element if it is valid, or report the problem and return
8818 * `null` if it is not appropriate.
8819 *
8820 * The [parent] is the parent of the element, used for reporting when there is
8821 * a problem.
8822 * The [isValid] is `true` if the element is appropriate.
8823 * The [element] is the element to be associated with this identifier.
8824 */
8825 Element _returnOrReportElement(
8826 AstNode parent, bool isValid, Element element) {
8827 if (!isValid) {
8828 AnalysisEngine.instance.logger.logInformation(
8829 "Internal error: attempting to set the name of a ${parent.runtimeType} to a ${element.runtimeType}",
8830 new CaughtException(new AnalysisException(), null));
8831 return null;
8832 }
8833 return element;
8834 }
8835
8836 /**
8837 * Return the given [element] if it is an appropriate element based on the
8838 * parent of this identifier, or `null` if it is not appropriate.
8839 */
8840 Element _validateElement(Element element) {
8841 if (element == null) {
8842 return null;
8843 }
8844 AstNode parent = this.parent;
8845 if (parent is ClassDeclaration && identical(parent.name, this)) {
8846 return _returnOrReportElement(parent, element is ClassElement, element);
8847 } else if (parent is ClassTypeAlias && identical(parent.name, this)) {
8848 return _returnOrReportElement(parent, element is ClassElement, element);
8849 } else if (parent is DeclaredIdentifier &&
8850 identical(parent.identifier, this)) {
8851 return _returnOrReportElement(
8852 parent, element is LocalVariableElement, element);
8853 } else if (parent is FormalParameter &&
8854 identical(parent.identifier, this)) {
8855 return _returnOrReportElement(
8856 parent, element is ParameterElement, element);
8857 } else if (parent is FunctionDeclaration && identical(parent.name, this)) {
8858 return _returnOrReportElement(
8859 parent, element is ExecutableElement, element);
8860 } else if (parent is FunctionTypeAlias && identical(parent.name, this)) {
8861 return _returnOrReportElement(
8862 parent, element is FunctionTypeAliasElement, element);
8863 } else if (parent is MethodDeclaration && identical(parent.name, this)) {
8864 return _returnOrReportElement(
8865 parent, element is ExecutableElement, element);
8866 } else if (parent is TypeParameter && identical(parent.name, this)) {
8867 return _returnOrReportElement(
8868 parent, element is TypeParameterElement, element);
8869 } else if (parent is VariableDeclaration && identical(parent.name, this)) {
8870 return _returnOrReportElement(
8871 parent, element is VariableElement, element);
8872 }
8873 return element;
8874 }
8875 }
8876
8877 /**
8878 * A string literal expression that does not contain any interpolations.
8879 *
8880 * > simpleStringLiteral ::=
8881 * > rawStringLiteral
8882 * > | basicStringLiteral
8883 * >
8884 * > rawStringLiteral ::=
8885 * > 'r' basicStringLiteral
8886 * >
8887 * > simpleStringLiteral ::=
8888 * > multiLineStringLiteral
8889 * > | singleLineStringLiteral
8890 * >
8891 * > multiLineStringLiteral ::=
8892 * > "'''" characters "'''"
8893 * > | '"""' characters '"""'
8894 * >
8895 * > singleLineStringLiteral ::=
8896 * > "'" characters "'"
8897 * > | '"' characters '"'
8898 */
8899 class SimpleStringLiteralImpl extends SingleStringLiteralImpl
8900 implements SimpleStringLiteral {
8901 /**
8902 * The token representing the literal.
8903 */
8904 Token literal;
8905
8906 /**
8907 * The value of the literal.
8908 */
8909 String _value;
8910
8911 /**
8912 * Initialize a newly created simple string literal.
8913 */
8914 SimpleStringLiteralImpl(this.literal, String value) {
8915 _value = StringUtilities.intern(value);
8916 }
8917
8918 @override
8919 Token get beginToken => literal;
8920
8921 @override
8922 Iterable get childEntities => new ChildEntities()..add(literal);
8923
8924 @override
8925 int get contentsEnd => offset + _helper.end;
8926
8927 @override
8928 int get contentsOffset => offset + _helper.start;
8929
8930 @override
8931 Token get endToken => literal;
8932
8933 @override
8934 bool get isMultiline => _helper.isMultiline;
8935
8936 @override
8937 bool get isRaw => _helper.isRaw;
8938
8939 @override
8940 bool get isSingleQuoted => _helper.isSingleQuoted;
8941
8942 @override
8943 bool get isSynthetic => literal.isSynthetic;
8944
8945 @override
8946 String get value => _value;
8947
8948 @override
8949 void set value(String string) {
8950 _value = StringUtilities.intern(_value);
8951 }
8952
8953 StringLexemeHelper get _helper {
8954 return new StringLexemeHelper(literal.lexeme, true, true);
8955 }
8956
8957 @override
8958 accept(AstVisitor visitor) => visitor.visitSimpleStringLiteral(this);
8959
8960 @override
8961 void visitChildren(AstVisitor visitor) {
8962 // There are no children to visit.
8963 }
8964
8965 @override
8966 void _appendStringValue(StringBuffer buffer) {
8967 buffer.write(value);
8968 }
8969 }
8970
8971 /**
8972 * A single string literal expression.
8973 *
8974 * > singleStringLiteral ::=
8975 * > [SimpleStringLiteral]
8976 * > | [StringInterpolation]
8977 */
8978 abstract class SingleStringLiteralImpl extends StringLiteralImpl
8979 implements SingleStringLiteral {}
8980
8981 /**
8982 * A node that represents a statement.
8983 *
8984 * > statement ::=
8985 * > [Block]
8986 * > | [VariableDeclarationStatement]
8987 * > | [ForStatement]
8988 * > | [ForEachStatement]
8989 * > | [WhileStatement]
8990 * > | [DoStatement]
8991 * > | [SwitchStatement]
8992 * > | [IfStatement]
8993 * > | [TryStatement]
8994 * > | [BreakStatement]
8995 * > | [ContinueStatement]
8996 * > | [ReturnStatement]
8997 * > | [ExpressionStatement]
8998 * > | [FunctionDeclarationStatement]
8999 */
9000 abstract class StatementImpl extends AstNodeImpl implements Statement {
9001 @override
9002 Statement get unlabeled => this;
9003 }
9004
9005 /**
9006 * A string interpolation literal.
9007 *
9008 * > stringInterpolation ::=
9009 * > ''' [InterpolationElement]* '''
9010 * > | '"' [InterpolationElement]* '"'
9011 */
9012 class StringInterpolationImpl extends SingleStringLiteralImpl
9013 implements StringInterpolation {
9014 /**
9015 * The elements that will be composed to produce the resulting string.
9016 */
9017 NodeList<InterpolationElement> _elements;
9018
9019 /**
9020 * Initialize a newly created string interpolation expression.
9021 */
9022 StringInterpolationImpl(List<InterpolationElement> elements) {
9023 _elements = new NodeList<InterpolationElement>(this, elements);
9024 }
9025
9026 @override
9027 Token get beginToken => _elements.beginToken;
9028
9029 @override
9030 Iterable get childEntities => new ChildEntities()..addAll(_elements);
9031
9032 @override
9033 int get contentsEnd {
9034 InterpolationString element = _elements.last;
9035 return element.contentsEnd;
9036 }
9037
9038 @override
9039 int get contentsOffset {
9040 InterpolationString element = _elements.first;
9041 return element.contentsOffset;
9042 }
9043
9044 /**
9045 * Return the elements that will be composed to produce the resulting string.
9046 */
9047 NodeList<InterpolationElement> get elements => _elements;
9048
9049 @override
9050 Token get endToken => _elements.endToken;
9051
9052 @override
9053 bool get isMultiline => _firstHelper.isMultiline;
9054
9055 @override
9056 bool get isRaw => false;
9057
9058 @override
9059 bool get isSingleQuoted => _firstHelper.isSingleQuoted;
9060
9061 StringLexemeHelper get _firstHelper {
9062 InterpolationString lastString = _elements.first;
9063 String lexeme = lastString.contents.lexeme;
9064 return new StringLexemeHelper(lexeme, true, false);
9065 }
9066
9067 @override
9068 accept(AstVisitor visitor) => visitor.visitStringInterpolation(this);
9069
9070 @override
9071 void visitChildren(AstVisitor visitor) {
9072 _elements.accept(visitor);
9073 }
9074
9075 @override
9076 void _appendStringValue(StringBuffer buffer) {
9077 throw new IllegalArgumentException();
9078 }
9079 }
9080
9081 /**
9082 * A helper for analyzing string lexemes.
9083 */
9084 class StringLexemeHelper {
9085 final String lexeme;
9086 final bool isFirst;
9087 final bool isLast;
9088
9089 bool isRaw = false;
9090 bool isSingleQuoted = false;
9091 bool isMultiline = false;
9092 int start = 0;
9093 int end;
9094
9095 StringLexemeHelper(this.lexeme, this.isFirst, this.isLast) {
9096 if (isFirst) {
9097 isRaw = StringUtilities.startsWithChar(lexeme, 0x72);
9098 if (isRaw) {
9099 start++;
9100 }
9101 if (StringUtilities.startsWith3(lexeme, start, 0x27, 0x27, 0x27)) {
9102 isSingleQuoted = true;
9103 isMultiline = true;
9104 start += 3;
9105 start = _trimInitialWhitespace(start);
9106 } else if (StringUtilities.startsWith3(lexeme, start, 0x22, 0x22, 0x22)) {
9107 isSingleQuoted = false;
9108 isMultiline = true;
9109 start += 3;
9110 start = _trimInitialWhitespace(start);
9111 } else if (start < lexeme.length && lexeme.codeUnitAt(start) == 0x27) {
9112 isSingleQuoted = true;
9113 isMultiline = false;
9114 start++;
9115 } else if (start < lexeme.length && lexeme.codeUnitAt(start) == 0x22) {
9116 isSingleQuoted = false;
9117 isMultiline = false;
9118 start++;
9119 }
9120 }
9121 end = lexeme.length;
9122 if (isLast) {
9123 if (start + 3 <= end &&
9124 (StringUtilities.endsWith3(lexeme, 0x22, 0x22, 0x22) ||
9125 StringUtilities.endsWith3(lexeme, 0x27, 0x27, 0x27))) {
9126 end -= 3;
9127 } else if (start + 1 <= end &&
9128 (StringUtilities.endsWithChar(lexeme, 0x22) ||
9129 StringUtilities.endsWithChar(lexeme, 0x27))) {
9130 end -= 1;
9131 }
9132 }
9133 }
9134
9135 /**
9136 * Given the [lexeme] for a multi-line string whose content begins at the
9137 * given [start] index, return the index of the first character that is
9138 * included in the value of the string. According to the specification:
9139 *
9140 * If the first line of a multiline string consists solely of the whitespace
9141 * characters defined by the production WHITESPACE 20.1), possibly prefixed
9142 * by \, then that line is ignored, including the new line at its end.
9143 */
9144 int _trimInitialWhitespace(int start) {
9145 int length = lexeme.length;
9146 int index = start;
9147 while (index < length) {
9148 int currentChar = lexeme.codeUnitAt(index);
9149 if (currentChar == 0x0D) {
9150 if (index + 1 < length && lexeme.codeUnitAt(index + 1) == 0x0A) {
9151 return index + 2;
9152 }
9153 return index + 1;
9154 } else if (currentChar == 0x0A) {
9155 return index + 1;
9156 } else if (currentChar == 0x5C) {
9157 if (index + 1 >= length) {
9158 return start;
9159 }
9160 currentChar = lexeme.codeUnitAt(index + 1);
9161 if (currentChar != 0x0D &&
9162 currentChar != 0x0A &&
9163 currentChar != 0x09 &&
9164 currentChar != 0x20) {
9165 return start;
9166 }
9167 } else if (currentChar != 0x09 && currentChar != 0x20) {
9168 return start;
9169 }
9170 index++;
9171 }
9172 return start;
9173 }
9174 }
9175
9176 /**
9177 * A string literal expression.
9178 *
9179 * > stringLiteral ::=
9180 * > [SimpleStringLiteral]
9181 * > | [AdjacentStrings]
9182 * > | [StringInterpolation]
9183 */
9184 abstract class StringLiteralImpl extends LiteralImpl implements StringLiteral {
9185 @override
9186 String get stringValue {
9187 StringBuffer buffer = new StringBuffer();
9188 try {
9189 _appendStringValue(buffer);
9190 } on IllegalArgumentException {
9191 return null;
9192 }
9193 return buffer.toString();
9194 }
9195
9196 /**
9197 * Append the value of this string literal to the given [buffer]. Throw an
9198 * [IllegalArgumentException] if the string is not a constant string without
9199 * any string interpolation.
9200 */
9201 void _appendStringValue(StringBuffer buffer);
9202 }
9203
9204 /**
9205 * The invocation of a superclass' constructor from within a constructor's
9206 * initialization list.
9207 *
9208 * > superInvocation ::=
9209 * > 'super' ('.' [SimpleIdentifier])? [ArgumentList]
9210 */
9211 class SuperConstructorInvocationImpl extends ConstructorInitializerImpl
9212 implements SuperConstructorInvocation {
9213 /**
9214 * The token for the 'super' keyword.
9215 */
9216 Token superKeyword;
9217
9218 /**
9219 * The token for the period before the name of the constructor that is being
9220 * invoked, or `null` if the unnamed constructor is being invoked.
9221 */
9222 Token period;
9223
9224 /**
9225 * The name of the constructor that is being invoked, or `null` if the unnamed
9226 * constructor is being invoked.
9227 */
9228 SimpleIdentifier _constructorName;
9229
9230 /**
9231 * The list of arguments to the constructor.
9232 */
9233 ArgumentList _argumentList;
9234
9235 /**
9236 * The element associated with the constructor based on static type
9237 * information, or `null` if the AST structure has not been resolved or if the
9238 * constructor could not be resolved.
9239 */
9240 ConstructorElement staticElement;
9241
9242 /**
9243 * Initialize a newly created super invocation to invoke the inherited
9244 * constructor with the given name with the given arguments. The [period] and
9245 * [constructorName] can be `null` if the constructor being invoked is the
9246 * unnamed constructor.
9247 */
9248 SuperConstructorInvocationImpl(this.superKeyword, this.period,
9249 SimpleIdentifier constructorName, ArgumentList argumentList) {
9250 _constructorName = _becomeParentOf(constructorName);
9251 _argumentList = _becomeParentOf(argumentList);
9252 }
9253
9254 @override
9255 ArgumentList get argumentList => _argumentList;
9256
9257 @override
9258 void set argumentList(ArgumentList argumentList) {
9259 _argumentList = _becomeParentOf(argumentList);
9260 }
9261
9262 @override
9263 Token get beginToken => superKeyword;
9264
9265 @override
9266 Iterable get childEntities => new ChildEntities()
9267 ..add(superKeyword)
9268 ..add(period)
9269 ..add(_constructorName)
9270 ..add(_argumentList);
9271
9272 @override
9273 SimpleIdentifier get constructorName => _constructorName;
9274
9275 @override
9276 void set constructorName(SimpleIdentifier identifier) {
9277 _constructorName = _becomeParentOf(identifier);
9278 }
9279
9280 @override
9281 Token get endToken => _argumentList.endToken;
9282
9283 @override
9284 accept(AstVisitor visitor) => visitor.visitSuperConstructorInvocation(this);
9285
9286 @override
9287 void visitChildren(AstVisitor visitor) {
9288 _safelyVisitChild(_constructorName, visitor);
9289 _safelyVisitChild(_argumentList, visitor);
9290 }
9291 }
9292
9293 /**
9294 * A super expression.
9295 *
9296 * > superExpression ::=
9297 * > 'super'
9298 */
9299 class SuperExpressionImpl extends ExpressionImpl implements SuperExpression {
9300 /**
9301 * The token representing the 'super' keyword.
9302 */
9303 Token superKeyword;
9304
9305 /**
9306 * Initialize a newly created super expression.
9307 */
9308 SuperExpressionImpl(this.superKeyword);
9309
9310 @override
9311 Token get beginToken => superKeyword;
9312
9313 @override
9314 Iterable get childEntities => new ChildEntities()..add(superKeyword);
9315
9316 @override
9317 Token get endToken => superKeyword;
9318
9319 @override
9320 int get precedence => 16;
9321
9322 @override
9323 accept(AstVisitor visitor) => visitor.visitSuperExpression(this);
9324
9325 @override
9326 void visitChildren(AstVisitor visitor) {
9327 // There are no children to visit.
9328 }
9329 }
9330
9331 /**
9332 * A case in a switch statement.
9333 *
9334 * > switchCase ::=
9335 * > [SimpleIdentifier]* 'case' [Expression] ':' [Statement]*
9336 */
9337 class SwitchCaseImpl extends SwitchMemberImpl implements SwitchCase {
9338 /**
9339 * The expression controlling whether the statements will be executed.
9340 */
9341 Expression _expression;
9342
9343 /**
9344 * Initialize a newly created switch case. The list of [labels] can be `null`
9345 * if there are no labels.
9346 */
9347 SwitchCaseImpl(List<Label> labels, Token keyword, Expression expression,
9348 Token colon, List<Statement> statements)
9349 : super(labels, keyword, colon, statements) {
9350 _expression = _becomeParentOf(expression);
9351 }
9352
9353 @override
9354 Iterable get childEntities => new ChildEntities()
9355 ..addAll(labels)
9356 ..add(keyword)
9357 ..add(_expression)
9358 ..add(colon)
9359 ..addAll(statements);
9360
9361 @override
9362 Expression get expression => _expression;
9363
9364 @override
9365 void set expression(Expression expression) {
9366 _expression = _becomeParentOf(expression);
9367 }
9368
9369 @override
9370 accept(AstVisitor visitor) => visitor.visitSwitchCase(this);
9371
9372 @override
9373 void visitChildren(AstVisitor visitor) {
9374 labels.accept(visitor);
9375 _safelyVisitChild(_expression, visitor);
9376 statements.accept(visitor);
9377 }
9378 }
9379
9380 /**
9381 * The default case in a switch statement.
9382 *
9383 * > switchDefault ::=
9384 * > [SimpleIdentifier]* 'default' ':' [Statement]*
9385 */
9386 class SwitchDefaultImpl extends SwitchMemberImpl implements SwitchDefault {
9387 /**
9388 * Initialize a newly created switch default. The list of [labels] can be
9389 * `null` if there are no labels.
9390 */
9391 SwitchDefaultImpl(List<Label> labels, Token keyword, Token colon,
9392 List<Statement> statements)
9393 : super(labels, keyword, colon, statements);
9394
9395 @override
9396 Iterable get childEntities => new ChildEntities()
9397 ..addAll(labels)
9398 ..add(keyword)
9399 ..add(colon)
9400 ..addAll(statements);
9401
9402 @override
9403 accept(AstVisitor visitor) => visitor.visitSwitchDefault(this);
9404
9405 @override
9406 void visitChildren(AstVisitor visitor) {
9407 labels.accept(visitor);
9408 statements.accept(visitor);
9409 }
9410 }
9411
9412 /**
9413 * An element within a switch statement.
9414 *
9415 * > switchMember ::=
9416 * > switchCase
9417 * > | switchDefault
9418 */
9419 abstract class SwitchMemberImpl extends AstNodeImpl implements SwitchMember {
9420 /**
9421 * The labels associated with the switch member.
9422 */
9423 NodeList<Label> _labels;
9424
9425 /**
9426 * The token representing the 'case' or 'default' keyword.
9427 */
9428 Token keyword;
9429
9430 /**
9431 * The colon separating the keyword or the expression from the statements.
9432 */
9433 Token colon;
9434
9435 /**
9436 * The statements that will be executed if this switch member is selected.
9437 */
9438 NodeList<Statement> _statements;
9439
9440 /**
9441 * Initialize a newly created switch member. The list of [labels] can be
9442 * `null` if there are no labels.
9443 */
9444 SwitchMemberImpl(List<Label> labels, this.keyword, this.colon,
9445 List<Statement> statements) {
9446 _labels = new NodeList<Label>(this, labels);
9447 _statements = new NodeList<Statement>(this, statements);
9448 }
9449
9450 @override
9451 Token get beginToken {
9452 if (!_labels.isEmpty) {
9453 return _labels.beginToken;
9454 }
9455 return keyword;
9456 }
9457
9458 @override
9459 Token get endToken {
9460 if (!_statements.isEmpty) {
9461 return _statements.endToken;
9462 }
9463 return colon;
9464 }
9465
9466 @override
9467 NodeList<Label> get labels => _labels;
9468
9469 @override
9470 NodeList<Statement> get statements => _statements;
9471 }
9472
9473 /**
9474 * A switch statement.
9475 *
9476 * > switchStatement ::=
9477 * > 'switch' '(' [Expression] ')' '{' [SwitchCase]* [SwitchDefault]? '}'
9478 */
9479 class SwitchStatementImpl extends StatementImpl implements SwitchStatement {
9480 /**
9481 * The token representing the 'switch' keyword.
9482 */
9483 Token switchKeyword;
9484
9485 /**
9486 * The left parenthesis.
9487 */
9488 Token leftParenthesis;
9489
9490 /**
9491 * The expression used to determine which of the switch members will be
9492 * selected.
9493 */
9494 Expression _expression;
9495
9496 /**
9497 * The right parenthesis.
9498 */
9499 Token rightParenthesis;
9500
9501 /**
9502 * The left curly bracket.
9503 */
9504 Token leftBracket;
9505
9506 /**
9507 * The switch members that can be selected by the expression.
9508 */
9509 NodeList<SwitchMember> _members;
9510
9511 /**
9512 * The right curly bracket.
9513 */
9514 Token rightBracket;
9515
9516 /**
9517 * Initialize a newly created switch statement. The list of [members] can be
9518 * `null` if there are no switch members.
9519 */
9520 SwitchStatementImpl(
9521 this.switchKeyword,
9522 this.leftParenthesis,
9523 Expression expression,
9524 this.rightParenthesis,
9525 this.leftBracket,
9526 List<SwitchMember> members,
9527 this.rightBracket) {
9528 _expression = _becomeParentOf(expression);
9529 _members = new NodeList<SwitchMember>(this, members);
9530 }
9531
9532 @override
9533 Token get beginToken => switchKeyword;
9534
9535 @override
9536 Iterable get childEntities => new ChildEntities()
9537 ..add(switchKeyword)
9538 ..add(leftParenthesis)
9539 ..add(_expression)
9540 ..add(rightParenthesis)
9541 ..add(leftBracket)
9542 ..addAll(_members)
9543 ..add(rightBracket);
9544
9545 @override
9546 Token get endToken => rightBracket;
9547
9548 @override
9549 Expression get expression => _expression;
9550
9551 @override
9552 void set expression(Expression expression) {
9553 _expression = _becomeParentOf(expression);
9554 }
9555
9556 @override
9557 NodeList<SwitchMember> get members => _members;
9558
9559 @override
9560 accept(AstVisitor visitor) => visitor.visitSwitchStatement(this);
9561
9562 @override
9563 void visitChildren(AstVisitor visitor) {
9564 _safelyVisitChild(_expression, visitor);
9565 _members.accept(visitor);
9566 }
9567 }
9568
9569 /**
9570 * A symbol literal expression.
9571 *
9572 * > symbolLiteral ::=
9573 * > '#' (operator | (identifier ('.' identifier)*))
9574 */
9575 class SymbolLiteralImpl extends LiteralImpl implements SymbolLiteral {
9576 /**
9577 * The token introducing the literal.
9578 */
9579 Token poundSign;
9580
9581 /**
9582 * The components of the literal.
9583 */
9584 final List<Token> components;
9585
9586 /**
9587 * Initialize a newly created symbol literal.
9588 */
9589 SymbolLiteralImpl(this.poundSign, this.components);
9590
9591 @override
9592 Token get beginToken => poundSign;
9593
9594 @override
9595 // TODO(paulberry): add "." tokens.
9596 Iterable get childEntities => new ChildEntities()
9597 ..add(poundSign)
9598 ..addAll(components);
9599
9600 @override
9601 Token get endToken => components[components.length - 1];
9602
9603 @override
9604 accept(AstVisitor visitor) => visitor.visitSymbolLiteral(this);
9605
9606 @override
9607 void visitChildren(AstVisitor visitor) {
9608 // There are no children to visit.
9609 }
9610 }
9611
9612 /**
9613 * A this expression.
9614 *
9615 * > thisExpression ::=
9616 * > 'this'
9617 */
9618 class ThisExpressionImpl extends ExpressionImpl implements ThisExpression {
9619 /**
9620 * The token representing the 'this' keyword.
9621 */
9622 Token thisKeyword;
9623
9624 /**
9625 * Initialize a newly created this expression.
9626 */
9627 ThisExpressionImpl(this.thisKeyword);
9628
9629 @override
9630 Token get beginToken => thisKeyword;
9631
9632 @override
9633 Iterable get childEntities => new ChildEntities()..add(thisKeyword);
9634
9635 @override
9636 Token get endToken => thisKeyword;
9637
9638 @override
9639 int get precedence => 16;
9640
9641 @override
9642 accept(AstVisitor visitor) => visitor.visitThisExpression(this);
9643
9644 @override
9645 void visitChildren(AstVisitor visitor) {
9646 // There are no children to visit.
9647 }
9648 }
9649
9650 /**
9651 * A throw expression.
9652 *
9653 * > throwExpression ::=
9654 * > 'throw' [Expression]
9655 */
9656 class ThrowExpressionImpl extends ExpressionImpl implements ThrowExpression {
9657 /**
9658 * The token representing the 'throw' keyword.
9659 */
9660 Token throwKeyword;
9661
9662 /**
9663 * The expression computing the exception to be thrown.
9664 */
9665 Expression _expression;
9666
9667 /**
9668 * Initialize a newly created throw expression.
9669 */
9670 ThrowExpressionImpl(this.throwKeyword, Expression expression) {
9671 _expression = _becomeParentOf(expression);
9672 }
9673
9674 @override
9675 Token get beginToken => throwKeyword;
9676
9677 @override
9678 Iterable get childEntities =>
9679 new ChildEntities()..add(throwKeyword)..add(_expression);
9680
9681 @override
9682 Token get endToken {
9683 if (_expression != null) {
9684 return _expression.endToken;
9685 }
9686 return throwKeyword;
9687 }
9688
9689 @override
9690 Expression get expression => _expression;
9691
9692 @override
9693 void set expression(Expression expression) {
9694 _expression = _becomeParentOf(expression);
9695 }
9696
9697 @override
9698 int get precedence => 0;
9699
9700 @override
9701 accept(AstVisitor visitor) => visitor.visitThrowExpression(this);
9702
9703 @override
9704 void visitChildren(AstVisitor visitor) {
9705 _safelyVisitChild(_expression, visitor);
9706 }
9707 }
9708
9709 /**
9710 * The declaration of one or more top-level variables of the same type.
9711 *
9712 * > topLevelVariableDeclaration ::=
9713 * > ('final' | 'const') type? staticFinalDeclarationList ';'
9714 * > | variableDeclaration ';'
9715 */
9716 class TopLevelVariableDeclarationImpl extends CompilationUnitMemberImpl
9717 implements TopLevelVariableDeclaration {
9718 /**
9719 * The top-level variables being declared.
9720 */
9721 VariableDeclarationList _variableList;
9722
9723 /**
9724 * The semicolon terminating the declaration.
9725 */
9726 Token semicolon;
9727
9728 /**
9729 * Initialize a newly created top-level variable declaration. Either or both
9730 * of the [comment] and [metadata] can be `null` if the variable does not have
9731 * the corresponding attribute.
9732 */
9733 TopLevelVariableDeclarationImpl(Comment comment, List<Annotation> metadata,
9734 VariableDeclarationList variableList, this.semicolon)
9735 : super(comment, metadata) {
9736 _variableList = _becomeParentOf(variableList);
9737 }
9738
9739 @override
9740 Iterable get childEntities =>
9741 super._childEntities..add(_variableList)..add(semicolon);
9742
9743 @override
9744 Element get element => null;
9745
9746 @override
9747 Token get endToken => semicolon;
9748
9749 @override
9750 Token get firstTokenAfterCommentAndMetadata => _variableList.beginToken;
9751
9752 @override
9753 VariableDeclarationList get variables => _variableList;
9754
9755 @override
9756 void set variables(VariableDeclarationList variables) {
9757 _variableList = _becomeParentOf(variables);
9758 }
9759
9760 @override
9761 accept(AstVisitor visitor) => visitor.visitTopLevelVariableDeclaration(this);
9762
9763 @override
9764 void visitChildren(AstVisitor visitor) {
9765 super.visitChildren(visitor);
9766 _safelyVisitChild(_variableList, visitor);
9767 }
9768 }
9769
9770 /**
9771 * A try statement.
9772 *
9773 * > tryStatement ::=
9774 * > 'try' [Block] ([CatchClause]+ finallyClause? | finallyClause)
9775 * >
9776 * > finallyClause ::=
9777 * > 'finally' [Block]
9778 */
9779 class TryStatementImpl extends StatementImpl implements TryStatement {
9780 /**
9781 * The token representing the 'try' keyword.
9782 */
9783 Token tryKeyword;
9784
9785 /**
9786 * The body of the statement.
9787 */
9788 Block _body;
9789
9790 /**
9791 * The catch clauses contained in the try statement.
9792 */
9793 NodeList<CatchClause> _catchClauses;
9794
9795 /**
9796 * The token representing the 'finally' keyword, or `null` if the statement
9797 * does not contain a finally clause.
9798 */
9799 Token finallyKeyword;
9800
9801 /**
9802 * The finally block contained in the try statement, or `null` if the
9803 * statement does not contain a finally clause.
9804 */
9805 Block _finallyBlock;
9806
9807 /**
9808 * Initialize a newly created try statement. The list of [catchClauses] can be
9809 * `null` if there are no catch clauses. The [finallyKeyword] and
9810 * [finallyBlock] can be `null` if there is no finally clause.
9811 */
9812 TryStatementImpl(this.tryKeyword, Block body, List<CatchClause> catchClauses,
9813 this.finallyKeyword, Block finallyBlock) {
9814 _body = _becomeParentOf(body);
9815 _catchClauses = new NodeList<CatchClause>(this, catchClauses);
9816 _finallyBlock = _becomeParentOf(finallyBlock);
9817 }
9818
9819 @override
9820 Token get beginToken => tryKeyword;
9821
9822 @override
9823 Block get body => _body;
9824
9825 @override
9826 void set body(Block block) {
9827 _body = _becomeParentOf(block);
9828 }
9829
9830 @override
9831 NodeList<CatchClause> get catchClauses => _catchClauses;
9832
9833 @override
9834 Iterable get childEntities => new ChildEntities()
9835 ..add(tryKeyword)
9836 ..add(_body)
9837 ..addAll(_catchClauses)
9838 ..add(finallyKeyword)
9839 ..add(_finallyBlock);
9840
9841 @override
9842 Token get endToken {
9843 if (_finallyBlock != null) {
9844 return _finallyBlock.endToken;
9845 } else if (finallyKeyword != null) {
9846 return finallyKeyword;
9847 } else if (!_catchClauses.isEmpty) {
9848 return _catchClauses.endToken;
9849 }
9850 return _body.endToken;
9851 }
9852
9853 @override
9854 Block get finallyBlock => _finallyBlock;
9855
9856 @override
9857 void set finallyBlock(Block block) {
9858 _finallyBlock = _becomeParentOf(block);
9859 }
9860
9861 @override
9862 accept(AstVisitor visitor) => visitor.visitTryStatement(this);
9863
9864 @override
9865 void visitChildren(AstVisitor visitor) {
9866 _safelyVisitChild(_body, visitor);
9867 _catchClauses.accept(visitor);
9868 _safelyVisitChild(_finallyBlock, visitor);
9869 }
9870 }
9871
9872 /**
9873 * The declaration of a type alias.
9874 *
9875 * > typeAlias ::=
9876 * > 'typedef' typeAliasBody
9877 * >
9878 * > typeAliasBody ::=
9879 * > classTypeAlias
9880 * > | functionTypeAlias
9881 */
9882 abstract class TypeAliasImpl extends NamedCompilationUnitMemberImpl
9883 implements TypeAlias {
9884 /**
9885 * The token representing the 'typedef' keyword.
9886 */
9887 Token typedefKeyword;
9888
9889 /**
9890 * The semicolon terminating the declaration.
9891 */
9892 Token semicolon;
9893
9894 /**
9895 * Initialize a newly created type alias. Either or both of the [comment] and
9896 * [metadata] can be `null` if the declaration does not have the corresponding
9897 * attribute.
9898 */
9899 TypeAliasImpl(Comment comment, List<Annotation> metadata, this.typedefKeyword,
9900 SimpleIdentifier name, this.semicolon)
9901 : super(comment, metadata, name);
9902
9903 @override
9904 Token get endToken => semicolon;
9905
9906 @override
9907 Token get firstTokenAfterCommentAndMetadata => typedefKeyword;
9908 }
9909
9910 /**
9911 * A list of type arguments.
9912 *
9913 * > typeArguments ::=
9914 * > '<' typeName (',' typeName)* '>'
9915 */
9916 class TypeArgumentListImpl extends AstNodeImpl implements TypeArgumentList {
9917 /**
9918 * The left bracket.
9919 */
9920 Token leftBracket;
9921
9922 /**
9923 * The type arguments associated with the type.
9924 */
9925 NodeList<TypeName> _arguments;
9926
9927 /**
9928 * The right bracket.
9929 */
9930 Token rightBracket;
9931
9932 /**
9933 * Initialize a newly created list of type arguments.
9934 */
9935 TypeArgumentListImpl(
9936 this.leftBracket, List<TypeName> arguments, this.rightBracket) {
9937 _arguments = new NodeList<TypeName>(this, arguments);
9938 }
9939
9940 @override
9941 NodeList<TypeName> get arguments => _arguments;
9942
9943 @override
9944 Token get beginToken => leftBracket;
9945
9946 @override
9947 // TODO(paulberry): Add commas.
9948 Iterable get childEntities => new ChildEntities()
9949 ..add(leftBracket)
9950 ..addAll(_arguments)
9951 ..add(rightBracket);
9952
9953 @override
9954 Token get endToken => rightBracket;
9955
9956 @override
9957 accept(AstVisitor visitor) => visitor.visitTypeArgumentList(this);
9958
9959 @override
9960 void visitChildren(AstVisitor visitor) {
9961 _arguments.accept(visitor);
9962 }
9963 }
9964
9965 /**
9966 * A literal that has a type associated with it.
9967 *
9968 * > typedLiteral ::=
9969 * > [ListLiteral]
9970 * > | [MapLiteral]
9971 */
9972 abstract class TypedLiteralImpl extends LiteralImpl implements TypedLiteral {
9973 /**
9974 * The token representing the 'const' keyword, or `null` if the literal is not
9975 * a constant.
9976 */
9977 Token constKeyword;
9978
9979 /**
9980 * The type argument associated with this literal, or `null` if no type
9981 * arguments were declared.
9982 */
9983 TypeArgumentList _typeArguments;
9984
9985 /**
9986 * Initialize a newly created typed literal. The [constKeyword] can be `null`\
9987 * if the literal is not a constant. The [typeArguments] can be `null` if no
9988 * type arguments were declared.
9989 */
9990 TypedLiteralImpl(this.constKeyword, TypeArgumentList typeArguments) {
9991 _typeArguments = _becomeParentOf(typeArguments);
9992 }
9993
9994 @override
9995 TypeArgumentList get typeArguments => _typeArguments;
9996
9997 @override
9998 void set typeArguments(TypeArgumentList typeArguments) {
9999 _typeArguments = _becomeParentOf(typeArguments);
10000 }
10001
10002 ChildEntities get _childEntities =>
10003 new ChildEntities()..add(constKeyword)..add(_typeArguments);
10004
10005 @override
10006 void visitChildren(AstVisitor visitor) {
10007 _safelyVisitChild(_typeArguments, visitor);
10008 }
10009 }
10010
10011 /**
10012 * The name of a type, which can optionally include type arguments.
10013 *
10014 * > typeName ::=
10015 * > [Identifier] typeArguments?
10016 */
10017 class TypeNameImpl extends AstNodeImpl implements TypeName {
10018 /**
10019 * The name of the type.
10020 */
10021 Identifier _name;
10022
10023 /**
10024 * The type arguments associated with the type, or `null` if there are no type
10025 * arguments.
10026 */
10027 TypeArgumentList _typeArguments;
10028
10029 /**
10030 * The type being named, or `null` if the AST structure has not been resolved.
10031 */
10032 DartType type;
10033
10034 /**
10035 * Initialize a newly created type name. The [typeArguments] can be `null` if
10036 * there are no type arguments.
10037 */
10038 TypeNameImpl(Identifier name, TypeArgumentList typeArguments) {
10039 _name = _becomeParentOf(name);
10040 _typeArguments = _becomeParentOf(typeArguments);
10041 }
10042
10043 @override
10044 Token get beginToken => _name.beginToken;
10045
10046 @override
10047 Iterable get childEntities =>
10048 new ChildEntities()..add(_name)..add(_typeArguments);
10049
10050 @override
10051 Token get endToken {
10052 if (_typeArguments != null) {
10053 return _typeArguments.endToken;
10054 }
10055 return _name.endToken;
10056 }
10057
10058 @override
10059 bool get isDeferred {
10060 Identifier identifier = name;
10061 if (identifier is! PrefixedIdentifier) {
10062 return false;
10063 }
10064 return (identifier as PrefixedIdentifier).isDeferred;
10065 }
10066
10067 @override
10068 bool get isSynthetic => _name.isSynthetic && _typeArguments == null;
10069
10070 @override
10071 Identifier get name => _name;
10072
10073 @override
10074 void set name(Identifier identifier) {
10075 _name = _becomeParentOf(identifier);
10076 }
10077
10078 @override
10079 TypeArgumentList get typeArguments => _typeArguments;
10080
10081 @override
10082 void set typeArguments(TypeArgumentList typeArguments) {
10083 _typeArguments = _becomeParentOf(typeArguments);
10084 }
10085
10086 @override
10087 accept(AstVisitor visitor) => visitor.visitTypeName(this);
10088
10089 @override
10090 void visitChildren(AstVisitor visitor) {
10091 _safelyVisitChild(_name, visitor);
10092 _safelyVisitChild(_typeArguments, visitor);
10093 }
10094 }
10095
10096 /**
10097 * A type parameter.
10098 *
10099 * > typeParameter ::=
10100 * > [SimpleIdentifier] ('extends' [TypeName])?
10101 */
10102 class TypeParameterImpl extends DeclarationImpl implements TypeParameter {
10103 /**
10104 * The name of the type parameter.
10105 */
10106 SimpleIdentifier _name;
10107
10108 /**
10109 * The token representing the 'extends' keyword, or `null` if there is no
10110 * explicit upper bound.
10111 */
10112 Token extendsKeyword;
10113
10114 /**
10115 * The name of the upper bound for legal arguments, or `null` if there is no
10116 * explicit upper bound.
10117 */
10118 TypeName _bound;
10119
10120 /**
10121 * Initialize a newly created type parameter. Either or both of the [comment]
10122 * and [metadata] can be `null` if the parameter does not have the
10123 * corresponding attribute. The [extendsKeyword] and [bound] can be `null` if
10124 * the parameter does not have an upper bound.
10125 */
10126 TypeParameterImpl(Comment comment, List<Annotation> metadata,
10127 SimpleIdentifier name, this.extendsKeyword, TypeName bound)
10128 : super(comment, metadata) {
10129 _name = _becomeParentOf(name);
10130 _bound = _becomeParentOf(bound);
10131 }
10132
10133 @override
10134 TypeName get bound => _bound;
10135
10136 @override
10137 void set bound(TypeName typeName) {
10138 _bound = _becomeParentOf(typeName);
10139 }
10140
10141 @override
10142 Iterable get childEntities =>
10143 super._childEntities..add(_name)..add(extendsKeyword)..add(_bound);
10144
10145 @override
10146 TypeParameterElement get element =>
10147 _name != null ? (_name.staticElement as TypeParameterElement) : null;
10148
10149 @override
10150 Token get endToken {
10151 if (_bound == null) {
10152 return _name.endToken;
10153 }
10154 return _bound.endToken;
10155 }
10156
10157 @override
10158 Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
10159
10160 @override
10161 SimpleIdentifier get name => _name;
10162
10163 @override
10164 void set name(SimpleIdentifier identifier) {
10165 _name = _becomeParentOf(identifier);
10166 }
10167
10168 @override
10169 accept(AstVisitor visitor) => visitor.visitTypeParameter(this);
10170
10171 @override
10172 void visitChildren(AstVisitor visitor) {
10173 super.visitChildren(visitor);
10174 _safelyVisitChild(_name, visitor);
10175 _safelyVisitChild(_bound, visitor);
10176 }
10177 }
10178
10179 /**
10180 * Type parameters within a declaration.
10181 *
10182 * > typeParameterList ::=
10183 * > '<' [TypeParameter] (',' [TypeParameter])* '>'
10184 */
10185 class TypeParameterListImpl extends AstNodeImpl implements TypeParameterList {
10186 /**
10187 * The left angle bracket.
10188 */
10189 final Token leftBracket;
10190
10191 /**
10192 * The type parameters in the list.
10193 */
10194 NodeList<TypeParameter> _typeParameters;
10195
10196 /**
10197 * The right angle bracket.
10198 */
10199 final Token rightBracket;
10200
10201 /**
10202 * Initialize a newly created list of type parameters.
10203 */
10204 TypeParameterListImpl(
10205 this.leftBracket, List<TypeParameter> typeParameters, this.rightBracket) {
10206 _typeParameters = new NodeList<TypeParameter>(this, typeParameters);
10207 }
10208
10209 @override
10210 Token get beginToken => leftBracket;
10211
10212 @override
10213 Iterable get childEntities => new ChildEntities()
10214 ..add(leftBracket)
10215 ..addAll(_typeParameters)
10216 ..add(rightBracket);
10217
10218 @override
10219 Token get endToken => rightBracket;
10220
10221 @override
10222 NodeList<TypeParameter> get typeParameters => _typeParameters;
10223
10224 @override
10225 accept(AstVisitor visitor) => visitor.visitTypeParameterList(this);
10226
10227 @override
10228 void visitChildren(AstVisitor visitor) {
10229 _typeParameters.accept(visitor);
10230 }
10231 }
10232
10233 /**
10234 * A directive that references a URI.
10235 *
10236 * > uriBasedDirective ::=
10237 * > [ExportDirective]
10238 * > | [ImportDirective]
10239 * > | [PartDirective]
10240 */
10241 abstract class UriBasedDirectiveImpl extends DirectiveImpl
10242 implements UriBasedDirective {
10243 /**
10244 * The prefix of a URI using the `dart-ext` scheme to reference a native code
10245 * library.
10246 */
10247 static String _DART_EXT_SCHEME = "dart-ext:";
10248
10249 /**
10250 * The URI referenced by this directive.
10251 */
10252 StringLiteral _uri;
10253
10254 /**
10255 * The content of the URI.
10256 */
10257 String uriContent;
10258
10259 /**
10260 * The source to which the URI was resolved.
10261 */
10262 Source source;
10263
10264 /**
10265 * Initialize a newly create URI-based directive. Either or both of the
10266 * [comment] and [metadata] can be `null` if the directive does not have the
10267 * corresponding attribute.
10268 */
10269 UriBasedDirectiveImpl(
10270 Comment comment, List<Annotation> metadata, StringLiteral uri)
10271 : super(comment, metadata) {
10272 _uri = _becomeParentOf(uri);
10273 }
10274
10275 @override
10276 StringLiteral get uri => _uri;
10277
10278 @override
10279 void set uri(StringLiteral uri) {
10280 _uri = _becomeParentOf(uri);
10281 }
10282
10283 @override
10284 UriValidationCode validate() {
10285 StringLiteral uriLiteral = uri;
10286 if (uriLiteral is StringInterpolation) {
10287 return UriValidationCode.URI_WITH_INTERPOLATION;
10288 }
10289 String uriContent = this.uriContent;
10290 if (uriContent == null) {
10291 return UriValidationCode.INVALID_URI;
10292 }
10293 if (this is ImportDirective && uriContent.startsWith(_DART_EXT_SCHEME)) {
10294 return UriValidationCode.URI_WITH_DART_EXT_SCHEME;
10295 }
10296 try {
10297 parseUriWithException(Uri.encodeFull(uriContent));
10298 } on URISyntaxException {
10299 return UriValidationCode.INVALID_URI;
10300 }
10301 return null;
10302 }
10303
10304 @override
10305 void visitChildren(AstVisitor visitor) {
10306 super.visitChildren(visitor);
10307 _safelyVisitChild(_uri, visitor);
10308 }
10309 }
10310
10311 /**
10312 * Validation codes returned by [UriBasedDirective.validate].
10313 */
10314 class UriValidationCodeImpl implements UriValidationCode {
10315 static const UriValidationCode INVALID_URI =
10316 const UriValidationCodeImpl('INVALID_URI');
10317
10318 static const UriValidationCode URI_WITH_INTERPOLATION =
10319 const UriValidationCodeImpl('URI_WITH_INTERPOLATION');
10320
10321 static const UriValidationCode URI_WITH_DART_EXT_SCHEME =
10322 const UriValidationCodeImpl('URI_WITH_DART_EXT_SCHEME');
10323
10324 /**
10325 * The name of the validation code.
10326 */
10327 final String name;
10328
10329 /**
10330 * Initialize a newly created validation code to have the given [name].
10331 */
10332 const UriValidationCodeImpl(this.name);
10333
10334 @override
10335 String toString() => name;
10336 }
10337
10338 /**
10339 * An identifier that has an initial value associated with it. Instances of this
10340 * class are always children of the class [VariableDeclarationList].
10341 *
10342 * > variableDeclaration ::=
10343 * > [SimpleIdentifier] ('=' [Expression])?
10344 *
10345 * TODO(paulberry): the grammar does not allow metadata to be associated with
10346 * a VariableDeclaration, and currently we don't record comments for it either.
10347 * Consider changing the class hierarchy so that [VariableDeclaration] does not
10348 * extend [Declaration].
10349 */
10350 class VariableDeclarationImpl extends DeclarationImpl
10351 implements VariableDeclaration {
10352 /**
10353 * The name of the variable being declared.
10354 */
10355 SimpleIdentifier _name;
10356
10357 /**
10358 * The equal sign separating the variable name from the initial value, or
10359 * `null` if the initial value was not specified.
10360 */
10361 Token equals;
10362
10363 /**
10364 * The expression used to compute the initial value for the variable, or
10365 * `null` if the initial value was not specified.
10366 */
10367 Expression _initializer;
10368
10369 /**
10370 * Initialize a newly created variable declaration. The [equals] and
10371 * [initializer] can be `null` if there is no initializer.
10372 */
10373 VariableDeclarationImpl(
10374 SimpleIdentifier name, this.equals, Expression initializer)
10375 : super(null, null) {
10376 _name = _becomeParentOf(name);
10377 _initializer = _becomeParentOf(initializer);
10378 }
10379
10380 @override
10381 Iterable get childEntities =>
10382 super._childEntities..add(_name)..add(equals)..add(_initializer);
10383
10384 /**
10385 * This overridden implementation of getDocumentationComment() looks in the
10386 * grandparent node for Dartdoc comments if no documentation is specifically
10387 * available on the node.
10388 */
10389 @override
10390 Comment get documentationComment {
10391 Comment comment = super.documentationComment;
10392 if (comment == null) {
10393 if (parent != null && parent.parent != null) {
10394 AstNode node = parent.parent;
10395 if (node is AnnotatedNode) {
10396 return node.documentationComment;
10397 }
10398 }
10399 }
10400 return comment;
10401 }
10402
10403 @override
10404 VariableElement get element =>
10405 _name != null ? (_name.staticElement as VariableElement) : null;
10406
10407 @override
10408 Token get endToken {
10409 if (_initializer != null) {
10410 return _initializer.endToken;
10411 }
10412 return _name.endToken;
10413 }
10414
10415 @override
10416 Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
10417
10418 @override
10419 Expression get initializer => _initializer;
10420
10421 @override
10422 void set initializer(Expression expression) {
10423 _initializer = _becomeParentOf(expression);
10424 }
10425
10426 @override
10427 bool get isConst {
10428 AstNode parent = this.parent;
10429 return parent is VariableDeclarationList && parent.isConst;
10430 }
10431
10432 @override
10433 bool get isFinal {
10434 AstNode parent = this.parent;
10435 return parent is VariableDeclarationList && parent.isFinal;
10436 }
10437
10438 @override
10439 SimpleIdentifier get name => _name;
10440
10441 @override
10442 void set name(SimpleIdentifier identifier) {
10443 _name = _becomeParentOf(identifier);
10444 }
10445
10446 @override
10447 accept(AstVisitor visitor) => visitor.visitVariableDeclaration(this);
10448
10449 @override
10450 void visitChildren(AstVisitor visitor) {
10451 super.visitChildren(visitor);
10452 _safelyVisitChild(_name, visitor);
10453 _safelyVisitChild(_initializer, visitor);
10454 }
10455 }
10456
10457 /**
10458 * The declaration of one or more variables of the same type.
10459 *
10460 * > variableDeclarationList ::=
10461 * > finalConstVarOrType [VariableDeclaration] (',' [VariableDeclaration])*
10462 * >
10463 * > finalConstVarOrType ::=
10464 * > | 'final' [TypeName]?
10465 * > | 'const' [TypeName]?
10466 * > | 'var'
10467 * > | [TypeName]
10468 */
10469 class VariableDeclarationListImpl extends AnnotatedNodeImpl
10470 implements VariableDeclarationList {
10471 /**
10472 * The token representing the 'final', 'const' or 'var' keyword, or `null` if
10473 * no keyword was included.
10474 */
10475 Token keyword;
10476
10477 /**
10478 * The type of the variables being declared, or `null` if no type was provided .
10479 */
10480 TypeName _type;
10481
10482 /**
10483 * A list containing the individual variables being declared.
10484 */
10485 NodeList<VariableDeclaration> _variables;
10486
10487 /**
10488 * Initialize a newly created variable declaration list. Either or both of the
10489 * [comment] and [metadata] can be `null` if the variable list does not have
10490 * the corresponding attribute. The [keyword] can be `null` if a type was
10491 * specified. The [type] must be `null` if the keyword is 'var'.
10492 */
10493 VariableDeclarationListImpl(Comment comment, List<Annotation> metadata,
10494 this.keyword, TypeName type, List<VariableDeclaration> variables)
10495 : super(comment, metadata) {
10496 _type = _becomeParentOf(type);
10497 _variables = new NodeList<VariableDeclaration>(this, variables);
10498 }
10499
10500 @override
10501 // TODO(paulberry): include commas.
10502 Iterable get childEntities => super._childEntities
10503 ..add(keyword)
10504 ..add(_type)
10505 ..addAll(_variables);
10506
10507 @override
10508 Token get endToken => _variables.endToken;
10509
10510 @override
10511 Token get firstTokenAfterCommentAndMetadata {
10512 if (keyword != null) {
10513 return keyword;
10514 } else if (_type != null) {
10515 return _type.beginToken;
10516 }
10517 return _variables.beginToken;
10518 }
10519
10520 @override
10521 bool get isConst =>
10522 keyword is KeywordToken &&
10523 (keyword as KeywordToken).keyword == Keyword.CONST;
10524
10525 @override
10526 bool get isFinal =>
10527 keyword is KeywordToken &&
10528 (keyword as KeywordToken).keyword == Keyword.FINAL;
10529
10530 @override
10531 TypeName get type => _type;
10532
10533 @override
10534 void set type(TypeName typeName) {
10535 _type = _becomeParentOf(typeName);
10536 }
10537
10538 @override
10539 NodeList<VariableDeclaration> get variables => _variables;
10540
10541 @override
10542 accept(AstVisitor visitor) => visitor.visitVariableDeclarationList(this);
10543
10544 @override
10545 void visitChildren(AstVisitor visitor) {
10546 super.visitChildren(visitor);
10547 _safelyVisitChild(_type, visitor);
10548 _variables.accept(visitor);
10549 }
10550 }
10551
10552 /**
10553 * A list of variables that are being declared in a context where a statement is
10554 * required.
10555 *
10556 * > variableDeclarationStatement ::=
10557 * > [VariableDeclarationList] ';'
10558 */
10559 class VariableDeclarationStatementImpl extends StatementImpl
10560 implements VariableDeclarationStatement {
10561 /**
10562 * The variables being declared.
10563 */
10564 VariableDeclarationList _variableList;
10565
10566 /**
10567 * The semicolon terminating the statement.
10568 */
10569 Token semicolon;
10570
10571 /**
10572 * Initialize a newly created variable declaration statement.
10573 */
10574 VariableDeclarationStatementImpl(
10575 VariableDeclarationList variableList, this.semicolon) {
10576 _variableList = _becomeParentOf(variableList);
10577 }
10578
10579 @override
10580 Token get beginToken => _variableList.beginToken;
10581
10582 @override
10583 Iterable get childEntities =>
10584 new ChildEntities()..add(_variableList)..add(semicolon);
10585
10586 @override
10587 Token get endToken => semicolon;
10588
10589 @override
10590 VariableDeclarationList get variables => _variableList;
10591
10592 @override
10593 void set variables(VariableDeclarationList variables) {
10594 _variableList = _becomeParentOf(variables);
10595 }
10596
10597 @override
10598 accept(AstVisitor visitor) => visitor.visitVariableDeclarationStatement(this);
10599
10600 @override
10601 void visitChildren(AstVisitor visitor) {
10602 _safelyVisitChild(_variableList, visitor);
10603 }
10604 }
10605
10606 /**
10607 * A while statement.
10608 *
10609 * > whileStatement ::=
10610 * > 'while' '(' [Expression] ')' [Statement]
10611 */
10612 class WhileStatementImpl extends StatementImpl implements WhileStatement {
10613 /**
10614 * The token representing the 'while' keyword.
10615 */
10616 Token whileKeyword;
10617
10618 /**
10619 * The left parenthesis.
10620 */
10621 Token leftParenthesis;
10622
10623 /**
10624 * The expression used to determine whether to execute the body of the loop.
10625 */
10626 Expression _condition;
10627
10628 /**
10629 * The right parenthesis.
10630 */
10631 Token rightParenthesis;
10632
10633 /**
10634 * The body of the loop.
10635 */
10636 Statement _body;
10637
10638 /**
10639 * Initialize a newly created while statement.
10640 */
10641 WhileStatementImpl(this.whileKeyword, this.leftParenthesis,
10642 Expression condition, this.rightParenthesis, Statement body) {
10643 _condition = _becomeParentOf(condition);
10644 _body = _becomeParentOf(body);
10645 }
10646
10647 @override
10648 Token get beginToken => whileKeyword;
10649
10650 @override
10651 Statement get body => _body;
10652
10653 @override
10654 void set body(Statement statement) {
10655 _body = _becomeParentOf(statement);
10656 }
10657
10658 @override
10659 Iterable get childEntities => new ChildEntities()
10660 ..add(whileKeyword)
10661 ..add(leftParenthesis)
10662 ..add(_condition)
10663 ..add(rightParenthesis)
10664 ..add(_body);
10665
10666 @override
10667 Expression get condition => _condition;
10668
10669 @override
10670 void set condition(Expression expression) {
10671 _condition = _becomeParentOf(expression);
10672 }
10673
10674 @override
10675 Token get endToken => _body.endToken;
10676
10677 @override
10678 accept(AstVisitor visitor) => visitor.visitWhileStatement(this);
10679
10680 @override
10681 void visitChildren(AstVisitor visitor) {
10682 _safelyVisitChild(_condition, visitor);
10683 _safelyVisitChild(_body, visitor);
10684 }
10685 }
10686
10687 /**
10688 * The with clause in a class declaration.
10689 *
10690 * > withClause ::=
10691 * > 'with' [TypeName] (',' [TypeName])*
10692 */
10693 class WithClauseImpl extends AstNodeImpl implements WithClause {
10694 /**
10695 * The token representing the 'with' keyword.
10696 */
10697 Token withKeyword;
10698
10699 /**
10700 * The names of the mixins that were specified.
10701 */
10702 NodeList<TypeName> _mixinTypes;
10703
10704 /**
10705 * Initialize a newly created with clause.
10706 */
10707 WithClauseImpl(this.withKeyword, List<TypeName> mixinTypes) {
10708 _mixinTypes = new NodeList<TypeName>(this, mixinTypes);
10709 }
10710
10711 @override
10712 Token get beginToken => withKeyword;
10713
10714 @override
10715 // TODO(paulberry): add commas.
10716 Iterable get childEntities => new ChildEntities()
10717 ..add(withKeyword)
10718 ..addAll(_mixinTypes);
10719
10720 @override
10721 Token get endToken => _mixinTypes.endToken;
10722
10723 @override
10724 NodeList<TypeName> get mixinTypes => _mixinTypes;
10725
10726 @override
10727 accept(AstVisitor visitor) => visitor.visitWithClause(this);
10728
10729 @override
10730 void visitChildren(AstVisitor visitor) {
10731 _mixinTypes.accept(visitor);
10732 }
10733 }
10734
10735 /**
10736 * A yield statement.
10737 *
10738 * > yieldStatement ::=
10739 * > 'yield' '*'? [Expression] ‘;’
10740 */
10741 class YieldStatementImpl extends StatementImpl implements YieldStatement {
10742 /**
10743 * The 'yield' keyword.
10744 */
10745 Token yieldKeyword;
10746
10747 /**
10748 * The star optionally following the 'yield' keyword.
10749 */
10750 Token star;
10751
10752 /**
10753 * The expression whose value will be yielded.
10754 */
10755 Expression _expression;
10756
10757 /**
10758 * The semicolon following the expression.
10759 */
10760 Token semicolon;
10761
10762 /**
10763 * Initialize a newly created yield expression. The [star] can be `null` if no
10764 * star was provided.
10765 */
10766 YieldStatementImpl(
10767 this.yieldKeyword, this.star, Expression expression, this.semicolon) {
10768 _expression = _becomeParentOf(expression);
10769 }
10770
10771 @override
10772 Token get beginToken {
10773 if (yieldKeyword != null) {
10774 return yieldKeyword;
10775 }
10776 return _expression.beginToken;
10777 }
10778
10779 @override
10780 Iterable get childEntities => new ChildEntities()
10781 ..add(yieldKeyword)
10782 ..add(star)
10783 ..add(_expression)
10784 ..add(semicolon);
10785
10786 @override
10787 Token get endToken {
10788 if (semicolon != null) {
10789 return semicolon;
10790 }
10791 return _expression.endToken;
10792 }
10793
10794 @override
10795 Expression get expression => _expression;
10796
10797 @override
10798 void set expression(Expression expression) {
10799 _expression = _becomeParentOf(expression);
10800 }
10801
10802 @override
10803 accept(AstVisitor visitor) => visitor.visitYieldStatement(this);
10804
10805 @override
10806 void visitChildren(AstVisitor visitor) {
10807 _safelyVisitChild(_expression, visitor);
10808 }
10809 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/dart/ast/utilities.dart ('k') | pkg/analyzer/lib/src/generated/element.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698