| // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'dart:collection'; |
| |
| import 'package:analyzer/dart/ast/ast.dart'; |
| import 'package:analyzer/dart/ast/syntactic_entity.dart'; |
| import 'package:analyzer/dart/ast/token.dart'; |
| import 'package:analyzer/dart/element/element.dart'; |
| import 'package:analyzer/dart/element/type.dart'; |
| import 'package:analyzer/error/error.dart'; |
| import 'package:analyzer/error/listener.dart'; |
| import 'package:analyzer/exception/exception.dart'; |
| import 'package:analyzer/src/dart/ast/token.dart'; |
| import 'package:analyzer/src/dart/ast/utilities.dart'; |
| import 'package:analyzer/src/dart/element/element.dart'; |
| import 'package:analyzer/src/dart/element/type.dart'; |
| import 'package:analyzer/src/error/codes.dart'; |
| import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine; |
| import 'package:analyzer/src/generated/engine.dart'; |
| import 'package:analyzer/src/generated/java_engine.dart'; |
| import 'package:analyzer/src/generated/parser.dart'; |
| import 'package:analyzer/src/generated/resolver.dart'; |
| import 'package:analyzer/src/generated/source.dart' show LineInfo, Source; |
| import 'package:analyzer/src/generated/utilities_dart.dart'; |
| import 'package:analyzer/src/fasta/token_utils.dart' as util show findPrevious; |
| |
| /** |
| * Two or more string literals that are implicitly concatenated because of being |
| * adjacent (separated only by whitespace). |
| * |
| * While the grammar only allows adjacent strings when all of the strings are of |
| * the same kind (single line or multi-line), this class doesn't enforce that |
| * restriction. |
| * |
| * adjacentStrings ::= |
| * [StringLiteral] [StringLiteral]+ |
| */ |
| class AdjacentStringsImpl extends StringLiteralImpl implements AdjacentStrings { |
| /** |
| * The strings that are implicitly concatenated. |
| */ |
| NodeList<StringLiteral> _strings; |
| |
| /** |
| * Initialize a newly created list of adjacent strings. To be syntactically |
| * valid, the list of [strings] must contain at least two elements. |
| */ |
| AdjacentStringsImpl(List<StringLiteral> strings) { |
| _strings = new NodeListImpl<StringLiteral>(this, strings); |
| } |
| |
| @override |
| Token get beginToken => _strings.beginToken; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| new ChildEntities()..addAll(_strings); |
| |
| @override |
| Token get endToken => _strings.endToken; |
| |
| @override |
| NodeList<StringLiteral> get strings => _strings; |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitAdjacentStrings(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _strings.accept(visitor); |
| } |
| |
| @override |
| void _appendStringValue(StringBuffer buffer) { |
| int length = strings.length; |
| for (int i = 0; i < length; i++) { |
| StringLiteralImpl stringLiteral = strings[i]; |
| stringLiteral._appendStringValue(buffer); |
| } |
| } |
| } |
| |
| /** |
| * An AST node that can be annotated with both a documentation comment and a |
| * list of annotations. |
| */ |
| abstract class AnnotatedNodeImpl extends AstNodeImpl implements AnnotatedNode { |
| /** |
| * The documentation comment associated with this node, or `null` if this node |
| * does not have a documentation comment associated with it. |
| */ |
| CommentImpl _comment; |
| |
| /** |
| * The annotations associated with this node. |
| */ |
| NodeList<Annotation> _metadata; |
| |
| /** |
| * Initialize a newly created annotated node. Either or both of the [comment] |
| * and [metadata] can be `null` if the node does not have the corresponding |
| * attribute. |
| */ |
| AnnotatedNodeImpl(CommentImpl comment, List<Annotation> metadata) { |
| _comment = _becomeParentOf(comment); |
| _metadata = new NodeListImpl<Annotation>(this, metadata); |
| } |
| |
| @override |
| Token get beginToken { |
| if (_comment == null) { |
| if (_metadata.isEmpty) { |
| return firstTokenAfterCommentAndMetadata; |
| } |
| return _metadata.beginToken; |
| } else if (_metadata.isEmpty) { |
| return _comment.beginToken; |
| } |
| Token commentToken = _comment.beginToken; |
| Token metadataToken = _metadata.beginToken; |
| if (commentToken.offset < metadataToken.offset) { |
| return commentToken; |
| } |
| return metadataToken; |
| } |
| |
| @override |
| Comment get documentationComment => _comment; |
| |
| @override |
| void set documentationComment(Comment comment) { |
| _comment = _becomeParentOf(comment as CommentImpl); |
| } |
| |
| @override |
| NodeList<Annotation> get metadata => _metadata; |
| |
| @override |
| List<AstNode> get sortedCommentAndAnnotations { |
| return <AstNode>[] |
| ..add(_comment) |
| ..addAll(_metadata) |
| ..sort(AstNode.LEXICAL_ORDER); |
| } |
| |
| /** |
| * Return a holder of child entities that subclasses can add to. |
| */ |
| ChildEntities get _childEntities { |
| ChildEntities result = new ChildEntities(); |
| if (_commentIsBeforeAnnotations()) { |
| result |
| ..add(_comment) |
| ..addAll(_metadata); |
| } else { |
| result.addAll(sortedCommentAndAnnotations); |
| } |
| return result; |
| } |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| if (_commentIsBeforeAnnotations()) { |
| _comment?.accept(visitor); |
| _metadata.accept(visitor); |
| } else { |
| List<AstNode> children = sortedCommentAndAnnotations; |
| int length = children.length; |
| for (int i = 0; i < length; i++) { |
| children[i].accept(visitor); |
| } |
| } |
| } |
| |
| /** |
| * Return `true` if there are no annotations before the comment. Note that a |
| * result of `true` does not imply that there is a comment, nor that there are |
| * annotations associated with this node. |
| */ |
| bool _commentIsBeforeAnnotations() { |
| if (_comment == null || _metadata.isEmpty) { |
| return true; |
| } |
| Annotation firstAnnotation = _metadata[0]; |
| return _comment.offset < firstAnnotation.offset; |
| } |
| } |
| |
| /** |
| * An annotation that can be associated with an AST node. |
| * |
| * metadata ::= |
| * annotation* |
| * |
| * annotation ::= |
| * '@' [Identifier] ('.' [SimpleIdentifier])? [ArgumentList]? |
| */ |
| class AnnotationImpl extends AstNodeImpl implements Annotation { |
| /** |
| * The at sign that introduced the annotation. |
| */ |
| @override |
| Token atSign; |
| |
| /** |
| * The name of the class defining the constructor that is being invoked or the |
| * name of the field that is being referenced. |
| */ |
| IdentifierImpl _name; |
| |
| /** |
| * The period before the constructor name, or `null` if this annotation is not |
| * the invocation of a named constructor. |
| */ |
| @override |
| Token period; |
| |
| /** |
| * The name of the constructor being invoked, or `null` if this annotation is |
| * not the invocation of a named constructor. |
| */ |
| SimpleIdentifierImpl _constructorName; |
| |
| /** |
| * The arguments to the constructor being invoked, or `null` if this |
| * annotation is not the invocation of a constructor. |
| */ |
| ArgumentListImpl _arguments; |
| |
| /** |
| * The element associated with this annotation, or `null` if the AST structure |
| * has not been resolved or if this annotation could not be resolved. |
| */ |
| Element _element; |
| |
| /** |
| * The element annotation representing this annotation in the element model. |
| */ |
| @override |
| ElementAnnotation elementAnnotation; |
| |
| /** |
| * Initialize a newly created annotation. Both the [period] and the |
| * [constructorName] can be `null` if the annotation is not referencing a |
| * named constructor. The [arguments] can be `null` if the annotation is not |
| * referencing a constructor. |
| */ |
| AnnotationImpl(this.atSign, IdentifierImpl name, this.period, |
| SimpleIdentifierImpl constructorName, ArgumentListImpl arguments) { |
| _name = _becomeParentOf(name); |
| _constructorName = _becomeParentOf(constructorName); |
| _arguments = _becomeParentOf(arguments); |
| } |
| |
| @override |
| ArgumentList get arguments => _arguments; |
| |
| @override |
| void set arguments(ArgumentList arguments) { |
| _arguments = _becomeParentOf(arguments as ArgumentListImpl); |
| } |
| |
| @override |
| Token get beginToken => atSign; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => new ChildEntities() |
| ..add(atSign) |
| ..add(_name) |
| ..add(period) |
| ..add(_constructorName) |
| ..add(_arguments); |
| |
| @override |
| SimpleIdentifier get constructorName => _constructorName; |
| |
| @override |
| void set constructorName(SimpleIdentifier name) { |
| _constructorName = _becomeParentOf(name as SimpleIdentifierImpl); |
| } |
| |
| @override |
| Element get element { |
| if (_element != null) { |
| return _element; |
| } else if (_constructorName == null && _name != null) { |
| return _name.staticElement; |
| } |
| return null; |
| } |
| |
| @override |
| void set element(Element element) { |
| _element = element; |
| } |
| |
| @override |
| Token get endToken { |
| if (_arguments != null) { |
| return _arguments.endToken; |
| } else if (_constructorName != null) { |
| return _constructorName.endToken; |
| } |
| return _name.endToken; |
| } |
| |
| @override |
| Identifier get name => _name; |
| |
| @override |
| void set name(Identifier name) { |
| _name = _becomeParentOf(name as IdentifierImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitAnnotation(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _name?.accept(visitor); |
| _constructorName?.accept(visitor); |
| _arguments?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A list of arguments in the invocation of an executable element (that is, a |
| * function, method, or constructor). |
| * |
| * argumentList ::= |
| * '(' arguments? ')' |
| * |
| * arguments ::= |
| * [NamedExpression] (',' [NamedExpression])* |
| * | [Expression] (',' [Expression])* (',' [NamedExpression])* |
| */ |
| class ArgumentListImpl extends AstNodeImpl implements ArgumentList { |
| /** |
| * The left parenthesis. |
| */ |
| @override |
| Token leftParenthesis; |
| |
| /** |
| * The expressions producing the values of the arguments. |
| */ |
| NodeList<Expression> _arguments; |
| |
| /** |
| * The right parenthesis. |
| */ |
| @override |
| Token rightParenthesis; |
| |
| /** |
| * A list containing the elements representing the parameters corresponding to |
| * each of the arguments in this list, or `null` if the AST has not been |
| * resolved or if the function or method being invoked could not be determined |
| * based on static type information. The list must be the same length as the |
| * number of arguments, but can contain `null` entries if a given argument |
| * does not correspond to a formal parameter. |
| */ |
| List<ParameterElement> _correspondingStaticParameters; |
| |
| /** |
| * A list containing the elements representing the parameters corresponding to |
| * each of the arguments in this list, or `null` if the AST has not been |
| * resolved or if the function or method being invoked could not be determined |
| * based on propagated type information. The list must be the same length as |
| * the number of arguments, but can contain `null` entries if a given argument |
| * does not correspond to a formal parameter. |
| */ |
| List<ParameterElement> _correspondingPropagatedParameters; |
| |
| /** |
| * Initialize a newly created list of arguments. The list of [arguments] can |
| * be `null` if there are no arguments. |
| */ |
| ArgumentListImpl( |
| this.leftParenthesis, List<Expression> arguments, this.rightParenthesis) { |
| _arguments = new NodeListImpl<Expression>(this, arguments); |
| } |
| |
| @override |
| NodeList<Expression> get arguments => _arguments; |
| |
| @override |
| Token get beginToken => leftParenthesis; |
| |
| @override |
| // TODO(paulberry): Add commas. |
| Iterable<SyntacticEntity> get childEntities => new ChildEntities() |
| ..add(leftParenthesis) |
| ..addAll(_arguments) |
| ..add(rightParenthesis); |
| |
| List<ParameterElement> get correspondingPropagatedParameters => |
| _correspondingPropagatedParameters; |
| |
| @override |
| void set correspondingPropagatedParameters( |
| List<ParameterElement> parameters) { |
| if (parameters != null && parameters.length != _arguments.length) { |
| throw new ArgumentError( |
| "Expected ${_arguments.length} parameters, not ${parameters.length}"); |
| } |
| _correspondingPropagatedParameters = parameters; |
| } |
| |
| List<ParameterElement> get correspondingStaticParameters => |
| _correspondingStaticParameters; |
| |
| @override |
| void set correspondingStaticParameters(List<ParameterElement> parameters) { |
| if (parameters != null && parameters.length != _arguments.length) { |
| throw new ArgumentError( |
| "Expected ${_arguments.length} parameters, not ${parameters.length}"); |
| } |
| _correspondingStaticParameters = parameters; |
| } |
| |
| @override |
| Token get endToken => rightParenthesis; |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitArgumentList(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _arguments.accept(visitor); |
| } |
| |
| /** |
| * If |
| * * the given [expression] is a child of this list, |
| * * the AST structure has been resolved, |
| * * the function being invoked is known based on propagated type information, |
| * and |
| * * the expression corresponds to one of the parameters of the function being |
| * invoked, |
| * then return the parameter element representing the parameter to which the |
| * value of the given expression will be bound. Otherwise, return `null`. |
| */ |
| ParameterElement _getPropagatedParameterElementFor(Expression expression) { |
| if (_correspondingPropagatedParameters == null || |
| _correspondingPropagatedParameters.length != _arguments.length) { |
| // Either the AST structure has not been resolved, the invocation of which |
| // this list is a part could not be resolved, or the argument list was |
| // modified after the parameters were set. |
| return null; |
| } |
| int index = _arguments.indexOf(expression); |
| if (index < 0) { |
| // The expression isn't a child of this node. |
| return null; |
| } |
| return _correspondingPropagatedParameters[index]; |
| } |
| |
| /** |
| * If |
| * * the given [expression] is a child of this list, |
| * * the AST structure has been resolved, |
| * * the function being invoked is known based on static type information, and |
| * * the expression corresponds to one of the parameters of the function being |
| * invoked, |
| * then return the parameter element representing the parameter to which the |
| * value of the given expression will be bound. Otherwise, return `null`. |
| */ |
| ParameterElement _getStaticParameterElementFor(Expression expression) { |
| if (_correspondingStaticParameters == null || |
| _correspondingStaticParameters.length != _arguments.length) { |
| // Either the AST structure has not been resolved, the invocation of which |
| // this list is a part could not be resolved, or the argument list was |
| // modified after the parameters were set. |
| return null; |
| } |
| int index = _arguments.indexOf(expression); |
| if (index < 0) { |
| // The expression isn't a child of this node. |
| return null; |
| } |
| return _correspondingStaticParameters[index]; |
| } |
| } |
| |
| /** |
| * An as expression. |
| * |
| * asExpression ::= |
| * [Expression] 'as' [TypeName] |
| */ |
| class AsExpressionImpl extends ExpressionImpl implements AsExpression { |
| /** |
| * The expression used to compute the value being cast. |
| */ |
| ExpressionImpl _expression; |
| |
| /** |
| * The 'as' operator. |
| */ |
| @override |
| Token asOperator; |
| |
| /** |
| * The type being cast to. |
| */ |
| TypeAnnotationImpl _type; |
| |
| /** |
| * Initialize a newly created as expression. |
| */ |
| AsExpressionImpl( |
| ExpressionImpl expression, this.asOperator, TypeAnnotationImpl type) { |
| _expression = _becomeParentOf(expression); |
| _type = _becomeParentOf(type); |
| } |
| |
| @override |
| Token get beginToken => _expression.beginToken; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| new ChildEntities()..add(_expression)..add(asOperator)..add(_type); |
| |
| @override |
| Token get endToken => _type.endToken; |
| |
| @override |
| Expression get expression => _expression; |
| |
| @override |
| void set expression(Expression expression) { |
| _expression = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| @override |
| int get precedence => 7; |
| |
| @override |
| TypeAnnotation get type => _type; |
| |
| @override |
| void set type(TypeAnnotation type) { |
| _type = _becomeParentOf(type as TypeAnnotationImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitAsExpression(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _expression?.accept(visitor); |
| _type?.accept(visitor); |
| } |
| } |
| |
| /** |
| * An assert in the initializer list of a constructor. |
| * |
| * assertInitializer ::= |
| * 'assert' '(' [Expression] (',' [Expression])? ')' |
| */ |
| class AssertInitializerImpl extends ConstructorInitializerImpl |
| implements AssertInitializer { |
| @override |
| Token assertKeyword; |
| |
| @override |
| Token leftParenthesis; |
| |
| /** |
| * The condition that is being asserted to be `true`. |
| */ |
| ExpressionImpl _condition; |
| |
| @override |
| Token comma; |
| |
| /** |
| * The message to report if the assertion fails, or `null` if no message was |
| * supplied. |
| */ |
| ExpressionImpl _message; |
| |
| @override |
| Token rightParenthesis; |
| |
| /** |
| * Initialize a newly created assert initializer. |
| */ |
| AssertInitializerImpl( |
| this.assertKeyword, |
| this.leftParenthesis, |
| ExpressionImpl condition, |
| this.comma, |
| ExpressionImpl message, |
| this.rightParenthesis) { |
| _condition = _becomeParentOf(condition); |
| _message = _becomeParentOf(message); |
| } |
| |
| @override |
| Token get beginToken => assertKeyword; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => new ChildEntities() |
| ..add(assertKeyword) |
| ..add(leftParenthesis) |
| ..add(_condition) |
| ..add(comma) |
| ..add(_message) |
| ..add(rightParenthesis); |
| |
| @override |
| Expression get condition => _condition; |
| |
| @override |
| void set condition(Expression condition) { |
| _condition = _becomeParentOf(condition as ExpressionImpl); |
| } |
| |
| @override |
| Token get endToken => rightParenthesis; |
| |
| @override |
| Expression get message => _message; |
| |
| @override |
| void set message(Expression expression) { |
| _message = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitAssertInitializer(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _condition?.accept(visitor); |
| message?.accept(visitor); |
| } |
| } |
| |
| /** |
| * An assert statement. |
| * |
| * assertStatement ::= |
| * 'assert' '(' [Expression] ')' ';' |
| */ |
| class AssertStatementImpl extends StatementImpl implements AssertStatement { |
| @override |
| Token assertKeyword; |
| |
| @override |
| Token leftParenthesis; |
| |
| /** |
| * The condition that is being asserted to be `true`. |
| */ |
| ExpressionImpl _condition; |
| |
| @override |
| Token comma; |
| |
| /** |
| * The message to report if the assertion fails, or `null` if no message was |
| * supplied. |
| */ |
| ExpressionImpl _message; |
| |
| @override |
| Token rightParenthesis; |
| |
| @override |
| Token semicolon; |
| |
| /** |
| * Initialize a newly created assert statement. |
| */ |
| AssertStatementImpl( |
| this.assertKeyword, |
| this.leftParenthesis, |
| ExpressionImpl condition, |
| this.comma, |
| ExpressionImpl message, |
| this.rightParenthesis, |
| this.semicolon) { |
| _condition = _becomeParentOf(condition); |
| _message = _becomeParentOf(message); |
| } |
| |
| @override |
| Token get beginToken => assertKeyword; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => new ChildEntities() |
| ..add(assertKeyword) |
| ..add(leftParenthesis) |
| ..add(_condition) |
| ..add(comma) |
| ..add(_message) |
| ..add(rightParenthesis) |
| ..add(semicolon); |
| |
| @override |
| Expression get condition => _condition; |
| |
| @override |
| void set condition(Expression condition) { |
| _condition = _becomeParentOf(condition as ExpressionImpl); |
| } |
| |
| @override |
| Token get endToken => semicolon; |
| |
| @override |
| Expression get message => _message; |
| |
| @override |
| void set message(Expression expression) { |
| _message = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitAssertStatement(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _condition?.accept(visitor); |
| message?.accept(visitor); |
| } |
| } |
| |
| /** |
| * An assignment expression. |
| * |
| * assignmentExpression ::= |
| * [Expression] operator [Expression] |
| */ |
| class AssignmentExpressionImpl extends ExpressionImpl |
| implements AssignmentExpression { |
| /** |
| * The expression used to compute the left hand side. |
| */ |
| ExpressionImpl _leftHandSide; |
| |
| /** |
| * The assignment operator being applied. |
| */ |
| @override |
| Token operator; |
| |
| /** |
| * The expression used to compute the right hand side. |
| */ |
| ExpressionImpl _rightHandSide; |
| |
| /** |
| * The element associated with the operator based on the static type of the |
| * left-hand-side, or `null` if the AST structure has not been resolved, if |
| * the operator is not a compound operator, or if the operator could not be |
| * resolved. |
| */ |
| @override |
| MethodElement staticElement; |
| |
| /** |
| * The element associated with the operator based on the propagated type of |
| * the left-hand-side, or `null` if the AST structure has not been resolved, |
| * if the operator is not a compound operator, or if the operator could not be |
| * resolved. |
| */ |
| @override |
| MethodElement propagatedElement; |
| |
| /** |
| * Initialize a newly created assignment expression. |
| */ |
| AssignmentExpressionImpl(ExpressionImpl leftHandSide, this.operator, |
| ExpressionImpl rightHandSide) { |
| if (leftHandSide == null || rightHandSide == null) { |
| String message; |
| if (leftHandSide == null) { |
| if (rightHandSide == null) { |
| message = "Both the left-hand and right-hand sides are null"; |
| } else { |
| message = "The left-hand size is null"; |
| } |
| } else { |
| message = "The right-hand size is null"; |
| } |
| AnalysisEngine.instance.logger.logError( |
| message, new CaughtException(new AnalysisException(message), null)); |
| } |
| _leftHandSide = _becomeParentOf(leftHandSide); |
| _rightHandSide = _becomeParentOf(rightHandSide); |
| } |
| |
| @override |
| Token get beginToken => _leftHandSide.beginToken; |
| |
| @override |
| MethodElement get bestElement { |
| MethodElement element = propagatedElement; |
| if (element == null) { |
| element = staticElement; |
| } |
| return element; |
| } |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => new ChildEntities() |
| ..add(_leftHandSide) |
| ..add(operator) |
| ..add(_rightHandSide); |
| |
| @override |
| Token get endToken => _rightHandSide.endToken; |
| |
| @override |
| Expression get leftHandSide => _leftHandSide; |
| |
| @override |
| void set leftHandSide(Expression expression) { |
| _leftHandSide = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| @override |
| int get precedence => 1; |
| |
| @override |
| Expression get rightHandSide => _rightHandSide; |
| |
| @override |
| void set rightHandSide(Expression expression) { |
| _rightHandSide = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| /** |
| * If the AST structure has been resolved, and the function being invoked is |
| * known based on propagated type information, then return the parameter |
| * element representing the parameter to which the value of the right operand |
| * will be bound. Otherwise, return `null`. |
| */ |
| ParameterElement get _propagatedParameterElementForRightHandSide { |
| ExecutableElement executableElement = null; |
| if (propagatedElement != null) { |
| executableElement = propagatedElement; |
| } else { |
| Expression left = _leftHandSide; |
| if (left is Identifier) { |
| Element leftElement = left.propagatedElement; |
| if (leftElement is ExecutableElement) { |
| executableElement = leftElement; |
| } |
| } else if (left is PropertyAccess) { |
| Element leftElement = left.propertyName.propagatedElement; |
| if (leftElement is ExecutableElement) { |
| executableElement = leftElement; |
| } |
| } |
| } |
| if (executableElement == null) { |
| return null; |
| } |
| List<ParameterElement> parameters = executableElement.parameters; |
| if (parameters.length < 1) { |
| return null; |
| } |
| return parameters[0]; |
| } |
| |
| /** |
| * If the AST structure has been resolved, and the function being invoked is |
| * known based on static type information, then return the parameter element |
| * representing the parameter to which the value of the right operand will be |
| * bound. Otherwise, return `null`. |
| */ |
| ParameterElement get _staticParameterElementForRightHandSide { |
| ExecutableElement executableElement = null; |
| if (staticElement != null) { |
| executableElement = staticElement; |
| } else { |
| Expression left = _leftHandSide; |
| if (left is Identifier) { |
| Element leftElement = left.staticElement; |
| if (leftElement is ExecutableElement) { |
| executableElement = leftElement; |
| } |
| } else if (left is PropertyAccess) { |
| Element leftElement = left.propertyName.staticElement; |
| if (leftElement is ExecutableElement) { |
| executableElement = leftElement; |
| } |
| } |
| } |
| if (executableElement == null) { |
| return null; |
| } |
| List<ParameterElement> parameters = executableElement.parameters; |
| if (parameters.length < 1) { |
| return null; |
| } |
| return parameters[0]; |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitAssignmentExpression(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _leftHandSide?.accept(visitor); |
| _rightHandSide?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A node in the AST structure for a Dart program. |
| */ |
| abstract class AstNodeImpl implements AstNode { |
| /** |
| * The parent of the node, or `null` if the node is the root of an AST |
| * structure. |
| */ |
| AstNode _parent; |
| |
| /** |
| * A table mapping the names of properties to their values, or `null` if this |
| * node does not have any properties associated with it. |
| */ |
| Map<String, Object> _propertyMap; |
| |
| @override |
| int get end => offset + length; |
| |
| @override |
| bool get isSynthetic => false; |
| |
| @override |
| int get length { |
| Token beginToken = this.beginToken; |
| Token endToken = this.endToken; |
| if (beginToken == null || endToken == null) { |
| return -1; |
| } |
| return endToken.offset + endToken.length - beginToken.offset; |
| } |
| |
| @override |
| int get offset { |
| Token beginToken = this.beginToken; |
| if (beginToken == null) { |
| return -1; |
| } |
| return beginToken.offset; |
| } |
| |
| @override |
| AstNode get parent => _parent; |
| |
| @override |
| AstNode get root { |
| AstNode root = this; |
| AstNode parent = this.parent; |
| while (parent != null) { |
| root = parent; |
| parent = root.parent; |
| } |
| return root; |
| } |
| |
| @override |
| E getAncestor<E extends AstNode>(Predicate<AstNode> predicate) { |
| // TODO(brianwilkerson) It is a bug that this method can return `this`. |
| AstNode node = this; |
| while (node != null && !predicate(node)) { |
| node = node.parent; |
| } |
| return node as E; |
| } |
| |
| @override |
| E getProperty<E>(String name) { |
| if (_propertyMap == null) { |
| return null; |
| } |
| return _propertyMap[name] as E; |
| } |
| |
| Token findPrevious(Token target) => |
| util.findPrevious(beginToken, target) ?? parent?.findPrevious(target); |
| |
| @override |
| void setProperty(String name, Object value) { |
| if (value == null) { |
| if (_propertyMap != null) { |
| _propertyMap.remove(name); |
| if (_propertyMap.isEmpty) { |
| _propertyMap = null; |
| } |
| } |
| } else { |
| if (_propertyMap == null) { |
| _propertyMap = new HashMap<String, Object>(); |
| } |
| _propertyMap[name] = value; |
| } |
| } |
| |
| @override |
| String toSource() { |
| StringBuffer buffer = new StringBuffer(); |
| accept(new ToSourceVisitor2(buffer)); |
| return buffer.toString(); |
| } |
| |
| @override |
| String toString() => toSource(); |
| |
| /** |
| * Make this node the parent of the given [child] node. Return the child node. |
| */ |
| T _becomeParentOf<T extends AstNodeImpl>(T child) { |
| if (child != null) { |
| child._parent = this; |
| } |
| return child; |
| } |
| } |
| |
| /** |
| * An await expression. |
| * |
| * awaitExpression ::= |
| * 'await' [Expression] |
| */ |
| class AwaitExpressionImpl extends ExpressionImpl implements AwaitExpression { |
| /** |
| * The 'await' keyword. |
| */ |
| @override |
| Token awaitKeyword; |
| |
| /** |
| * The expression whose value is being waited on. |
| */ |
| ExpressionImpl _expression; |
| |
| /** |
| * Initialize a newly created await expression. |
| */ |
| AwaitExpressionImpl(this.awaitKeyword, ExpressionImpl expression) { |
| _expression = _becomeParentOf(expression); |
| } |
| |
| @override |
| Token get beginToken { |
| if (awaitKeyword != null) { |
| return awaitKeyword; |
| } |
| return _expression.beginToken; |
| } |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| new ChildEntities()..add(awaitKeyword)..add(_expression); |
| |
| @override |
| Token get endToken => _expression.endToken; |
| |
| @override |
| Expression get expression => _expression; |
| |
| @override |
| void set expression(Expression expression) { |
| _expression = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| @override |
| int get precedence => 0; |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitAwaitExpression(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _expression?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A binary (infix) expression. |
| * |
| * binaryExpression ::= |
| * [Expression] [Token] [Expression] |
| */ |
| class BinaryExpressionImpl extends ExpressionImpl implements BinaryExpression { |
| /** |
| * The expression used to compute the left operand. |
| */ |
| ExpressionImpl _leftOperand; |
| |
| /** |
| * The binary operator being applied. |
| */ |
| @override |
| Token operator; |
| |
| /** |
| * The expression used to compute the right operand. |
| */ |
| ExpressionImpl _rightOperand; |
| |
| /** |
| * The element associated with the operator based on the static type of the |
| * left operand, or `null` if the AST structure has not been resolved, if the |
| * operator is not user definable, or if the operator could not be resolved. |
| */ |
| @override |
| MethodElement staticElement; |
| |
| /** |
| * The element associated with the operator based on the propagated type of |
| * the left operand, or `null` if the AST structure has not been resolved, if |
| * the operator is not user definable, or if the operator could not be |
| * resolved. |
| */ |
| @override |
| MethodElement propagatedElement; |
| |
| /** |
| * Initialize a newly created binary expression. |
| */ |
| BinaryExpressionImpl( |
| ExpressionImpl leftOperand, this.operator, ExpressionImpl rightOperand) { |
| _leftOperand = _becomeParentOf(leftOperand); |
| _rightOperand = _becomeParentOf(rightOperand); |
| } |
| |
| @override |
| Token get beginToken => _leftOperand.beginToken; |
| |
| @override |
| MethodElement get bestElement { |
| MethodElement element = propagatedElement; |
| if (element == null) { |
| element = staticElement; |
| } |
| return element; |
| } |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| new ChildEntities()..add(_leftOperand)..add(operator)..add(_rightOperand); |
| |
| @override |
| Token get endToken => _rightOperand.endToken; |
| |
| @override |
| Expression get leftOperand => _leftOperand; |
| |
| @override |
| void set leftOperand(Expression expression) { |
| _leftOperand = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| @override |
| int get precedence => operator.type.precedence; |
| |
| @override |
| Expression get rightOperand => _rightOperand; |
| |
| @override |
| void set rightOperand(Expression expression) { |
| _rightOperand = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| /** |
| * If the AST structure has been resolved, and the function being invoked is |
| * known based on propagated type information, then return the parameter |
| * element representing the parameter to which the value of the right operand |
| * will be bound. Otherwise, return `null`. |
| */ |
| ParameterElement get _propagatedParameterElementForRightOperand { |
| if (propagatedElement == null) { |
| return null; |
| } |
| List<ParameterElement> parameters = propagatedElement.parameters; |
| if (parameters.length < 1) { |
| return null; |
| } |
| return parameters[0]; |
| } |
| |
| /** |
| * If the AST structure has been resolved, and the function being invoked is |
| * known based on static type information, then return the parameter element |
| * representing the parameter to which the value of the right operand will be |
| * bound. Otherwise, return `null`. |
| */ |
| ParameterElement get _staticParameterElementForRightOperand { |
| if (staticElement == null) { |
| return null; |
| } |
| List<ParameterElement> parameters = staticElement.parameters; |
| if (parameters.length < 1) { |
| return null; |
| } |
| return parameters[0]; |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitBinaryExpression(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _leftOperand?.accept(visitor); |
| _rightOperand?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A function body that consists of a block of statements. |
| * |
| * blockFunctionBody ::= |
| * ('async' | 'async' '*' | 'sync' '*')? [Block] |
| */ |
| class BlockFunctionBodyImpl extends FunctionBodyImpl |
| implements BlockFunctionBody { |
| /** |
| * The token representing the 'async' or 'sync' keyword, or `null` if there is |
| * no such keyword. |
| */ |
| @override |
| Token keyword; |
| |
| /** |
| * The star optionally following the 'async' or 'sync' keyword, or `null` if |
| * there is wither no such keyword or no star. |
| */ |
| @override |
| Token star; |
| |
| /** |
| * The block representing the body of the function. |
| */ |
| BlockImpl _block; |
| |
| /** |
| * Initialize a newly created function body consisting of a block of |
| * statements. The [keyword] can be `null` if there is no keyword specified |
| * for the block. The [star] can be `null` if there is no star following the |
| * keyword (and must be `null` if there is no keyword). |
| */ |
| BlockFunctionBodyImpl(this.keyword, this.star, BlockImpl block) { |
| _block = _becomeParentOf(block); |
| } |
| |
| @override |
| Token get beginToken { |
| if (keyword != null) { |
| return keyword; |
| } |
| return _block.beginToken; |
| } |
| |
| @override |
| Block get block => _block; |
| |
| @override |
| void set block(Block block) { |
| _block = _becomeParentOf(block as BlockImpl); |
| } |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| new ChildEntities()..add(keyword)..add(star)..add(_block); |
| |
| @override |
| Token get endToken => _block.endToken; |
| |
| @override |
| bool get isAsynchronous => keyword != null && keyword.lexeme == Parser.ASYNC; |
| |
| @override |
| bool get isGenerator => star != null; |
| |
| @override |
| bool get isSynchronous => keyword == null || keyword.lexeme != Parser.ASYNC; |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitBlockFunctionBody(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _block?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A sequence of statements. |
| * |
| * block ::= |
| * '{' statement* '}' |
| */ |
| class BlockImpl extends StatementImpl implements Block { |
| /** |
| * The left curly bracket. |
| */ |
| @override |
| Token leftBracket; |
| |
| /** |
| * The statements contained in the block. |
| */ |
| NodeList<Statement> _statements; |
| |
| /** |
| * The right curly bracket. |
| */ |
| @override |
| Token rightBracket; |
| |
| /** |
| * Initialize a newly created block of code. |
| */ |
| BlockImpl(this.leftBracket, List<Statement> statements, this.rightBracket) { |
| _statements = new NodeListImpl<Statement>(this, statements); |
| } |
| |
| @override |
| Token get beginToken => leftBracket; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => new ChildEntities() |
| ..add(leftBracket) |
| ..addAll(_statements) |
| ..add(rightBracket); |
| |
| @override |
| Token get endToken => rightBracket; |
| |
| @override |
| NodeList<Statement> get statements => _statements; |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitBlock(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _statements.accept(visitor); |
| } |
| } |
| |
| /** |
| * A boolean literal expression. |
| * |
| * booleanLiteral ::= |
| * 'false' | 'true' |
| */ |
| class BooleanLiteralImpl extends LiteralImpl implements BooleanLiteral { |
| /** |
| * The token representing the literal. |
| */ |
| @override |
| Token literal; |
| |
| /** |
| * The value of the literal. |
| */ |
| @override |
| bool value = false; |
| |
| /** |
| * Initialize a newly created boolean literal. |
| */ |
| BooleanLiteralImpl(this.literal, this.value); |
| |
| @override |
| Token get beginToken => literal; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| new ChildEntities()..add(literal); |
| |
| @override |
| Token get endToken => literal; |
| |
| @override |
| bool get isSynthetic => literal.isSynthetic; |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitBooleanLiteral(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| // There are no children to visit. |
| } |
| } |
| |
| /** |
| * A break statement. |
| * |
| * breakStatement ::= |
| * 'break' [SimpleIdentifier]? ';' |
| */ |
| class BreakStatementImpl extends StatementImpl implements BreakStatement { |
| /** |
| * The token representing the 'break' keyword. |
| */ |
| @override |
| Token breakKeyword; |
| |
| /** |
| * The label associated with the statement, or `null` if there is no label. |
| */ |
| SimpleIdentifierImpl _label; |
| |
| /** |
| * The semicolon terminating the statement. |
| */ |
| @override |
| Token semicolon; |
| |
| /** |
| * The AstNode which this break statement is breaking from. This will be |
| * either a [Statement] (in the case of breaking out of a loop), a |
| * [SwitchMember] (in the case of a labeled break statement whose label |
| * matches a label on a switch case in an enclosing switch statement), or |
| * `null` if the AST has not yet been resolved or if the target could not be |
| * resolved. Note that if the source code has errors, the target might be |
| * invalid (e.g. trying to break to a switch case). |
| */ |
| @override |
| AstNode target; |
| |
| /** |
| * Initialize a newly created break statement. The [label] can be `null` if |
| * there is no label associated with the statement. |
| */ |
| BreakStatementImpl( |
| this.breakKeyword, SimpleIdentifierImpl label, this.semicolon) { |
| _label = _becomeParentOf(label); |
| } |
| |
| @override |
| Token get beginToken => breakKeyword; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| new ChildEntities()..add(breakKeyword)..add(_label)..add(semicolon); |
| |
| @override |
| Token get endToken => semicolon; |
| |
| @override |
| SimpleIdentifier get label => _label; |
| |
| @override |
| void set label(SimpleIdentifier identifier) { |
| _label = _becomeParentOf(identifier as SimpleIdentifierImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitBreakStatement(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _label?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A sequence of cascaded expressions: expressions that share a common target. |
| * There are three kinds of expressions that can be used in a cascade |
| * expression: [IndexExpression], [MethodInvocation] and [PropertyAccess]. |
| * |
| * cascadeExpression ::= |
| * [Expression] cascadeSection* |
| * |
| * cascadeSection ::= |
| * '..' (cascadeSelector arguments*) (assignableSelector arguments*)* |
| * (assignmentOperator expressionWithoutCascade)? |
| * |
| * cascadeSelector ::= |
| * '[ ' expression '] ' |
| * | identifier |
| */ |
| class CascadeExpressionImpl extends ExpressionImpl |
| implements CascadeExpression { |
| /** |
| * The target of the cascade sections. |
| */ |
| ExpressionImpl _target; |
| |
| /** |
| * The cascade sections sharing the common target. |
| */ |
| NodeList<Expression> _cascadeSections; |
| |
| /** |
| * Initialize a newly created cascade expression. The list of |
| * [cascadeSections] must contain at least one element. |
| */ |
| CascadeExpressionImpl( |
| ExpressionImpl target, List<Expression> cascadeSections) { |
| _target = _becomeParentOf(target); |
| _cascadeSections = new NodeListImpl<Expression>(this, cascadeSections); |
| } |
| |
| @override |
| Token get beginToken => _target.beginToken; |
| |
| @override |
| NodeList<Expression> get cascadeSections => _cascadeSections; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => new ChildEntities() |
| ..add(_target) |
| ..addAll(_cascadeSections); |
| |
| @override |
| Token get endToken => _cascadeSections.endToken; |
| |
| @override |
| int get precedence => 2; |
| |
| @override |
| Expression get target => _target; |
| |
| @override |
| void set target(Expression target) { |
| _target = _becomeParentOf(target as ExpressionImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitCascadeExpression(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _target?.accept(visitor); |
| _cascadeSections.accept(visitor); |
| } |
| } |
| |
| /** |
| * A catch clause within a try statement. |
| * |
| * onPart ::= |
| * catchPart [Block] |
| * | 'on' type catchPart? [Block] |
| * |
| * catchPart ::= |
| * 'catch' '(' [SimpleIdentifier] (',' [SimpleIdentifier])? ')' |
| */ |
| class CatchClauseImpl extends AstNodeImpl implements CatchClause { |
| /** |
| * The token representing the 'on' keyword, or `null` if there is no 'on' |
| * keyword. |
| */ |
| @override |
| Token onKeyword; |
| |
| /** |
| * The type of exceptions caught by this catch clause, or `null` if this catch |
| * clause catches every type of exception. |
| */ |
| TypeAnnotationImpl _exceptionType; |
| |
| /** |
| * The token representing the 'catch' keyword, or `null` if there is no |
| * 'catch' keyword. |
| */ |
| @override |
| Token catchKeyword; |
| |
| /** |
| * The left parenthesis, or `null` if there is no 'catch' keyword. |
| */ |
| @override |
| Token leftParenthesis; |
| |
| /** |
| * The parameter whose value will be the exception that was thrown, or `null` |
| * if there is no 'catch' keyword. |
| */ |
| SimpleIdentifierImpl _exceptionParameter; |
| |
| /** |
| * The comma separating the exception parameter from the stack trace |
| * parameter, or `null` if there is no stack trace parameter. |
| */ |
| @override |
| Token comma; |
| |
| /** |
| * The parameter whose value will be the stack trace associated with the |
| * exception, or `null` if there is no stack trace parameter. |
| */ |
| SimpleIdentifierImpl _stackTraceParameter; |
| |
| /** |
| * The right parenthesis, or `null` if there is no 'catch' keyword. |
| */ |
| @override |
| Token rightParenthesis; |
| |
| /** |
| * The body of the catch block. |
| */ |
| BlockImpl _body; |
| |
| /** |
| * Initialize a newly created catch clause. The [onKeyword] and |
| * [exceptionType] can be `null` if the clause will catch all exceptions. The |
| * [comma] and [stackTraceParameter] can be `null` if the stack trace |
| * parameter is not defined. |
| */ |
| CatchClauseImpl( |
| this.onKeyword, |
| TypeAnnotationImpl exceptionType, |
| this.catchKeyword, |
| this.leftParenthesis, |
| SimpleIdentifierImpl exceptionParameter, |
| this.comma, |
| SimpleIdentifierImpl stackTraceParameter, |
| this.rightParenthesis, |
| BlockImpl body) { |
| _exceptionType = _becomeParentOf(exceptionType); |
| _exceptionParameter = _becomeParentOf(exceptionParameter); |
| _stackTraceParameter = _becomeParentOf(stackTraceParameter); |
| _body = _becomeParentOf(body); |
| } |
| |
| @override |
| Token get beginToken { |
| if (onKeyword != null) { |
| return onKeyword; |
| } |
| return catchKeyword; |
| } |
| |
| @override |
| Block get body => _body; |
| |
| @override |
| void set body(Block block) { |
| _body = _becomeParentOf(block as BlockImpl); |
| } |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => new ChildEntities() |
| ..add(onKeyword) |
| ..add(_exceptionType) |
| ..add(catchKeyword) |
| ..add(leftParenthesis) |
| ..add(_exceptionParameter) |
| ..add(comma) |
| ..add(_stackTraceParameter) |
| ..add(rightParenthesis) |
| ..add(_body); |
| |
| @override |
| Token get endToken => _body.endToken; |
| |
| @override |
| SimpleIdentifier get exceptionParameter => _exceptionParameter; |
| |
| @override |
| void set exceptionParameter(SimpleIdentifier parameter) { |
| _exceptionParameter = _becomeParentOf(parameter as SimpleIdentifierImpl); |
| } |
| |
| @override |
| TypeAnnotation get exceptionType => _exceptionType; |
| |
| @override |
| void set exceptionType(TypeAnnotation exceptionType) { |
| _exceptionType = _becomeParentOf(exceptionType as TypeAnnotationImpl); |
| } |
| |
| @override |
| SimpleIdentifier get stackTraceParameter => _stackTraceParameter; |
| |
| @override |
| void set stackTraceParameter(SimpleIdentifier parameter) { |
| _stackTraceParameter = _becomeParentOf(parameter as SimpleIdentifierImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitCatchClause(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _exceptionType?.accept(visitor); |
| _exceptionParameter?.accept(visitor); |
| _stackTraceParameter?.accept(visitor); |
| _body?.accept(visitor); |
| } |
| } |
| |
| /** |
| * Helper class to allow iteration of child entities of an AST node. |
| */ |
| class ChildEntities extends Object |
| with IterableMixin<SyntacticEntity> |
| implements Iterable<SyntacticEntity> { |
| /** |
| * The list of child entities to be iterated over. |
| */ |
| List<SyntacticEntity> _entities = []; |
| |
| @override |
| Iterator<SyntacticEntity> get iterator => _entities.iterator; |
| |
| /** |
| * Add an AST node or token as the next child entity, if it is not null. |
| */ |
| void add(SyntacticEntity entity) { |
| if (entity != null) { |
| _entities.add(entity); |
| } |
| } |
| |
| /** |
| * Add the given items as the next child entities, if [items] is not null. |
| */ |
| void addAll(Iterable<SyntacticEntity> items) { |
| if (items != null) { |
| _entities.addAll(items); |
| } |
| } |
| } |
| |
| /** |
| * The declaration of a class. |
| * |
| * classDeclaration ::= |
| * 'abstract'? 'class' [SimpleIdentifier] [TypeParameterList]? |
| * ([ExtendsClause] [WithClause]?)? |
| * [ImplementsClause]? |
| * '{' [ClassMember]* '}' |
| */ |
| class ClassDeclarationImpl extends NamedCompilationUnitMemberImpl |
| implements ClassDeclaration { |
| /** |
| * The 'abstract' keyword, or `null` if the keyword was absent. |
| */ |
| @override |
| Token abstractKeyword; |
| |
| /** |
| * The token representing the 'class' keyword. |
| */ |
| @override |
| Token classKeyword; |
| |
| /** |
| * The type parameters for the class, or `null` if the class does not have any |
| * type parameters. |
| */ |
| TypeParameterListImpl _typeParameters; |
| |
| /** |
| * The extends clause for the class, or `null` if the class does not extend |
| * any other class. |
| */ |
| ExtendsClauseImpl _extendsClause; |
| |
| /** |
| * The with clause for the class, or `null` if the class does not have a with |
| * clause. |
| */ |
| WithClauseImpl _withClause; |
| |
| /** |
| * The implements clause for the class, or `null` if the class does not |
| * implement any interfaces. |
| */ |
| ImplementsClauseImpl _implementsClause; |
| |
| /** |
| * The native clause for the class, or `null` if the class does not have a |
| * native clause. |
| */ |
| NativeClauseImpl _nativeClause; |
| |
| /** |
| * The left curly bracket. |
| */ |
| @override |
| Token leftBracket; |
| |
| /** |
| * The members defined by the class. |
| */ |
| NodeList<ClassMember> _members; |
| |
| /** |
| * The right curly bracket. |
| */ |
| @override |
| Token rightBracket; |
| |
| /** |
| * Initialize a newly created class declaration. Either or both of the |
| * [comment] and [metadata] can be `null` if the class does not have the |
| * corresponding attribute. The [abstractKeyword] can be `null` if the class |
| * is not abstract. The [typeParameters] can be `null` if the class does not |
| * have any type parameters. Any or all of the [extendsClause], [withClause], |
| * and [implementsClause] can be `null` if the class does not have the |
| * corresponding clause. The list of [members] can be `null` if the class does |
| * not have any members. |
| */ |
| ClassDeclarationImpl( |
| CommentImpl comment, |
| List<Annotation> metadata, |
| this.abstractKeyword, |
| this.classKeyword, |
| SimpleIdentifierImpl name, |
| TypeParameterListImpl typeParameters, |
| ExtendsClauseImpl extendsClause, |
| WithClauseImpl withClause, |
| ImplementsClauseImpl implementsClause, |
| this.leftBracket, |
| List<ClassMember> members, |
| this.rightBracket) |
| : super(comment, metadata, name) { |
| _typeParameters = _becomeParentOf(typeParameters); |
| _extendsClause = _becomeParentOf(extendsClause); |
| _withClause = _becomeParentOf(withClause); |
| _implementsClause = _becomeParentOf(implementsClause); |
| _members = new NodeListImpl<ClassMember>(this, members); |
| } |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => super._childEntities |
| ..add(abstractKeyword) |
| ..add(classKeyword) |
| ..add(_name) |
| ..add(_typeParameters) |
| ..add(_extendsClause) |
| ..add(_withClause) |
| ..add(_implementsClause) |
| ..add(_nativeClause) |
| ..add(leftBracket) |
| ..addAll(members) |
| ..add(rightBracket); |
| |
| @override |
| ClassElement get element => _name?.staticElement as ClassElement; |
| |
| @override |
| Token get endToken => rightBracket; |
| |
| @override |
| ExtendsClause get extendsClause => _extendsClause; |
| |
| @override |
| void set extendsClause(ExtendsClause extendsClause) { |
| _extendsClause = _becomeParentOf(extendsClause as ExtendsClauseImpl); |
| } |
| |
| @override |
| Token get firstTokenAfterCommentAndMetadata { |
| if (abstractKeyword != null) { |
| return abstractKeyword; |
| } |
| return classKeyword; |
| } |
| |
| @override |
| ImplementsClause get implementsClause => _implementsClause; |
| |
| @override |
| void set implementsClause(ImplementsClause implementsClause) { |
| _implementsClause = |
| _becomeParentOf(implementsClause as ImplementsClauseImpl); |
| } |
| |
| @override |
| bool get isAbstract => abstractKeyword != null; |
| |
| @override |
| NodeList<ClassMember> get members => _members; |
| |
| @override |
| NativeClause get nativeClause => _nativeClause; |
| |
| @override |
| void set nativeClause(NativeClause nativeClause) { |
| _nativeClause = _becomeParentOf(nativeClause as NativeClauseImpl); |
| } |
| |
| @override |
| TypeParameterList get typeParameters => _typeParameters; |
| |
| @override |
| void set typeParameters(TypeParameterList typeParameters) { |
| _typeParameters = _becomeParentOf(typeParameters as TypeParameterListImpl); |
| } |
| |
| @override |
| WithClause get withClause => _withClause; |
| |
| @override |
| void set withClause(WithClause withClause) { |
| _withClause = _becomeParentOf(withClause as WithClauseImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitClassDeclaration(this); |
| |
| @override |
| ConstructorDeclaration getConstructor(String name) { |
| int length = _members.length; |
| for (int i = 0; i < length; i++) { |
| ClassMember classMember = _members[i]; |
| if (classMember is ConstructorDeclaration) { |
| ConstructorDeclaration constructor = classMember; |
| SimpleIdentifier constructorName = constructor.name; |
| if (name == null && constructorName == null) { |
| return constructor; |
| } |
| if (constructorName != null && constructorName.name == name) { |
| return constructor; |
| } |
| } |
| } |
| return null; |
| } |
| |
| @override |
| VariableDeclaration getField(String name) { |
| int memberLength = _members.length; |
| for (int i = 0; i < memberLength; i++) { |
| ClassMember classMember = _members[i]; |
| if (classMember is FieldDeclaration) { |
| FieldDeclaration fieldDeclaration = classMember; |
| NodeList<VariableDeclaration> fields = |
| fieldDeclaration.fields.variables; |
| int fieldLength = fields.length; |
| for (int i = 0; i < fieldLength; i++) { |
| VariableDeclaration field = fields[i]; |
| SimpleIdentifier fieldName = field.name; |
| if (fieldName != null && name == fieldName.name) { |
| return field; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| @override |
| MethodDeclaration getMethod(String name) { |
| int length = _members.length; |
| for (int i = 0; i < length; i++) { |
| ClassMember classMember = _members[i]; |
| if (classMember is MethodDeclaration) { |
| MethodDeclaration method = classMember; |
| SimpleIdentifier methodName = method.name; |
| if (methodName != null && name == methodName.name) { |
| return method; |
| } |
| } |
| } |
| return null; |
| } |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| super.visitChildren(visitor); |
| _name?.accept(visitor); |
| _typeParameters?.accept(visitor); |
| _extendsClause?.accept(visitor); |
| _withClause?.accept(visitor); |
| _implementsClause?.accept(visitor); |
| _nativeClause?.accept(visitor); |
| members.accept(visitor); |
| } |
| } |
| |
| /** |
| * A node that declares a name within the scope of a class. |
| */ |
| abstract class ClassMemberImpl extends DeclarationImpl implements ClassMember { |
| /** |
| * Initialize a newly created member of a class. Either or both of the |
| * [comment] and [metadata] can be `null` if the member does not have the |
| * corresponding attribute. |
| */ |
| ClassMemberImpl(CommentImpl comment, List<Annotation> metadata) |
| : super(comment, metadata); |
| } |
| |
| /** |
| * A class type alias. |
| * |
| * classTypeAlias ::= |
| * [SimpleIdentifier] [TypeParameterList]? '=' 'abstract'? mixinApplication |
| * |
| * mixinApplication ::= |
| * [TypeName] [WithClause] [ImplementsClause]? ';' |
| */ |
| class ClassTypeAliasImpl extends TypeAliasImpl implements ClassTypeAlias { |
| /** |
| * The type parameters for the class, or `null` if the class does not have any |
| * type parameters. |
| */ |
| TypeParameterListImpl _typeParameters; |
| |
| /** |
| * The token for the '=' separating the name from the definition. |
| */ |
| @override |
| Token equals; |
| |
| /** |
| * The token for the 'abstract' keyword, or `null` if this is not defining an |
| * abstract class. |
| */ |
| @override |
| Token abstractKeyword; |
| |
| /** |
| * The name of the superclass of the class being declared. |
| */ |
| TypeNameImpl _superclass; |
| |
| /** |
| * The with clause for this class. |
| */ |
| WithClauseImpl _withClause; |
| |
| /** |
| * The implements clause for this class, or `null` if there is no implements |
| * clause. |
| */ |
| ImplementsClauseImpl _implementsClause; |
| |
| /** |
| * Initialize a newly created class type alias. Either or both of the |
| * [comment] and [metadata] can be `null` if the class type alias does not |
| * have the corresponding attribute. The [typeParameters] can be `null` if the |
| * class does not have any type parameters. The [abstractKeyword] can be |
| * `null` if the class is not abstract. The [implementsClause] can be `null` |
| * if the class does not implement any interfaces. |
| */ |
| ClassTypeAliasImpl( |
| CommentImpl comment, |
| List<Annotation> metadata, |
| Token keyword, |
| SimpleIdentifierImpl name, |
| TypeParameterListImpl typeParameters, |
| this.equals, |
| this.abstractKeyword, |
| TypeNameImpl superclass, |
| WithClauseImpl withClause, |
| ImplementsClauseImpl implementsClause, |
| Token semicolon) |
| : super(comment, metadata, keyword, name, semicolon) { |
| _typeParameters = _becomeParentOf(typeParameters); |
| _superclass = _becomeParentOf(superclass); |
| _withClause = _becomeParentOf(withClause); |
| _implementsClause = _becomeParentOf(implementsClause); |
| } |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => super._childEntities |
| ..add(typedefKeyword) |
| ..add(_name) |
| ..add(_typeParameters) |
| ..add(equals) |
| ..add(abstractKeyword) |
| ..add(_superclass) |
| ..add(_withClause) |
| ..add(_implementsClause) |
| ..add(semicolon); |
| |
| @override |
| ClassElement get element => _name?.staticElement as ClassElement; |
| |
| @override |
| Token get firstTokenAfterCommentAndMetadata { |
| if (abstractKeyword != null) { |
| return abstractKeyword; |
| } |
| return typedefKeyword; |
| } |
| |
| @override |
| ImplementsClause get implementsClause => _implementsClause; |
| |
| @override |
| void set implementsClause(ImplementsClause implementsClause) { |
| _implementsClause = |
| _becomeParentOf(implementsClause as ImplementsClauseImpl); |
| } |
| |
| @override |
| bool get isAbstract => abstractKeyword != null; |
| |
| @override |
| TypeName get superclass => _superclass; |
| |
| @override |
| void set superclass(TypeName superclass) { |
| _superclass = _becomeParentOf(superclass as TypeNameImpl); |
| } |
| |
| @override |
| TypeParameterList get typeParameters => _typeParameters; |
| |
| @override |
| void set typeParameters(TypeParameterList typeParameters) { |
| _typeParameters = _becomeParentOf(typeParameters as TypeParameterListImpl); |
| } |
| |
| @override |
| WithClause get withClause => _withClause; |
| |
| @override |
| void set withClause(WithClause withClause) { |
| _withClause = _becomeParentOf(withClause as WithClauseImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitClassTypeAlias(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| super.visitChildren(visitor); |
| _name?.accept(visitor); |
| _typeParameters?.accept(visitor); |
| _superclass?.accept(visitor); |
| _withClause?.accept(visitor); |
| _implementsClause?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A combinator associated with an import or export directive. |
| * |
| * combinator ::= |
| * [HideCombinator] |
| * | [ShowCombinator] |
| */ |
| abstract class CombinatorImpl extends AstNodeImpl implements Combinator { |
| /** |
| * The 'hide' or 'show' keyword specifying what kind of processing is to be |
| * done on the names. |
| */ |
| @override |
| Token keyword; |
| |
| /** |
| * Initialize a newly created combinator. |
| */ |
| CombinatorImpl(this.keyword); |
| |
| @override |
| Token get beginToken => keyword; |
| } |
| |
| /** |
| * A comment within the source code. |
| * |
| * comment ::= |
| * endOfLineComment |
| * | blockComment |
| * | documentationComment |
| * |
| * endOfLineComment ::= |
| * '//' (CHARACTER - EOL)* EOL |
| * |
| * blockComment ::= |
| * '/ *' CHARACTER* '*/' |
| * |
| * documentationComment ::= |
| * '/ **' (CHARACTER | [CommentReference])* '*/' |
| * | ('///' (CHARACTER - EOL)* EOL)+ |
| */ |
| class CommentImpl extends AstNodeImpl implements Comment { |
| /** |
| * The tokens representing the comment. |
| */ |
| @override |
| final List<Token> tokens; |
| |
| /** |
| * The type of the comment. |
| */ |
| final CommentType _type; |
| |
| /** |
| * The references embedded within the documentation comment. This list will be |
| * empty unless this is a documentation comment that has references embedded |
| * within it. |
| */ |
| NodeList<CommentReference> _references; |
| |
| /** |
| * Initialize a newly created comment. The list of [tokens] must contain at |
| * least one token. The [_type] is the type of the comment. The list of |
| * [references] can be empty if the comment does not contain any embedded |
| * references. |
| */ |
| CommentImpl(this.tokens, this._type, List<CommentReference> references) { |
| _references = new NodeListImpl<CommentReference>(this, references); |
| } |
| |
| @override |
| Token get beginToken => tokens[0]; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| new ChildEntities()..addAll(tokens); |
| |
| @override |
| Token get endToken => tokens[tokens.length - 1]; |
| |
| @override |
| bool get isBlock => _type == CommentType.BLOCK; |
| |
| @override |
| bool get isDocumentation => _type == CommentType.DOCUMENTATION; |
| |
| @override |
| bool get isEndOfLine => _type == CommentType.END_OF_LINE; |
| |
| @override |
| NodeList<CommentReference> get references => _references; |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitComment(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _references.accept(visitor); |
| } |
| |
| /** |
| * Create a block comment consisting of the given [tokens]. |
| */ |
| static Comment createBlockComment(List<Token> tokens) => |
| new CommentImpl(tokens, CommentType.BLOCK, null); |
| |
| /** |
| * Create a documentation comment consisting of the given [tokens]. |
| */ |
| static Comment createDocumentationComment(List<Token> tokens) => |
| new CommentImpl( |
| tokens, CommentType.DOCUMENTATION, new List<CommentReference>()); |
| |
| /** |
| * Create a documentation comment consisting of the given [tokens] and having |
| * the given [references] embedded within it. |
| */ |
| static Comment createDocumentationCommentWithReferences( |
| List<Token> tokens, List<CommentReference> references) => |
| new CommentImpl(tokens, CommentType.DOCUMENTATION, references); |
| |
| /** |
| * Create an end-of-line comment consisting of the given [tokens]. |
| */ |
| static Comment createEndOfLineComment(List<Token> tokens) => |
| new CommentImpl(tokens, CommentType.END_OF_LINE, null); |
| } |
| |
| /** |
| * A reference to a Dart element that is found within a documentation comment. |
| * |
| * commentReference ::= |
| * '[' 'new'? [Identifier] ']' |
| */ |
| class CommentReferenceImpl extends AstNodeImpl implements CommentReference { |
| /** |
| * The token representing the 'new' keyword, or `null` if there was no 'new' |
| * keyword. |
| */ |
| @override |
| Token newKeyword; |
| |
| /** |
| * The identifier being referenced. |
| */ |
| IdentifierImpl _identifier; |
| |
| /** |
| * Initialize a newly created reference to a Dart element. The [newKeyword] |
| * can be `null` if the reference is not to a constructor. |
| */ |
| CommentReferenceImpl(this.newKeyword, IdentifierImpl identifier) { |
| _identifier = _becomeParentOf(identifier); |
| } |
| |
| @override |
| Token get beginToken => _identifier.beginToken; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| new ChildEntities()..add(newKeyword)..add(_identifier); |
| |
| @override |
| Token get endToken => _identifier.endToken; |
| |
| @override |
| Identifier get identifier => _identifier; |
| |
| @override |
| void set identifier(Identifier identifier) { |
| _identifier = _becomeParentOf(identifier as IdentifierImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitCommentReference(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _identifier?.accept(visitor); |
| } |
| } |
| |
| /** |
| * The possible types of comments that are recognized by the parser. |
| */ |
| class CommentType { |
| /** |
| * A block comment. |
| */ |
| static const CommentType BLOCK = const CommentType('BLOCK'); |
| |
| /** |
| * A documentation comment. |
| */ |
| static const CommentType DOCUMENTATION = const CommentType('DOCUMENTATION'); |
| |
| /** |
| * An end-of-line comment. |
| */ |
| static const CommentType END_OF_LINE = const CommentType('END_OF_LINE'); |
| |
| /** |
| * The name of the comment type. |
| */ |
| final String name; |
| |
| /** |
| * Initialize a newly created comment type to have the given [name]. |
| */ |
| const CommentType(this.name); |
| |
| @override |
| String toString() => name; |
| } |
| |
| /** |
| * A compilation unit. |
| * |
| * While the grammar restricts the order of the directives and declarations |
| * within a compilation unit, this class does not enforce those restrictions. |
| * In particular, the children of a compilation unit will be visited in lexical |
| * order even if lexical order does not conform to the restrictions of the |
| * grammar. |
| * |
| * compilationUnit ::= |
| * directives declarations |
| * |
| * directives ::= |
| * [ScriptTag]? [LibraryDirective]? namespaceDirective* [PartDirective]* |
| * | [PartOfDirective] |
| * |
| * namespaceDirective ::= |
| * [ImportDirective] |
| * | [ExportDirective] |
| * |
| * declarations ::= |
| * [CompilationUnitMember]* |
| */ |
| class CompilationUnitImpl extends AstNodeImpl implements CompilationUnit { |
| /** |
| * The first token in the token stream that was parsed to form this |
| * compilation unit. |
| */ |
| @override |
| Token beginToken; |
| |
| /** |
| * The script tag at the beginning of the compilation unit, or `null` if there |
| * is no script tag in this compilation unit. |
| */ |
| ScriptTagImpl _scriptTag; |
| |
| /** |
| * The directives contained in this compilation unit. |
| */ |
| NodeList<Directive> _directives; |
| |
| /** |
| * The declarations contained in this compilation unit. |
| */ |
| NodeList<CompilationUnitMember> _declarations; |
| |
| /** |
| * The last token in the token stream that was parsed to form this compilation |
| * unit. This token should always have a type of [TokenType.EOF]. |
| */ |
| @override |
| Token endToken; |
| |
| /** |
| * The element associated with this compilation unit, or `null` if the AST |
| * structure has not been resolved. |
| */ |
| @override |
| CompilationUnitElement element; |
| |
| /** |
| * The line information for this compilation unit. |
| */ |
| @override |
| LineInfo lineInfo; |
| |
| Map<int, AstNode> localDeclarations; |
| |
| /** |
| * Initialize a newly created compilation unit to have the given directives |
| * and declarations. The [scriptTag] can be `null` if there is no script tag |
| * in the compilation unit. The list of [directives] can be `null` if there |
| * are no directives in the compilation unit. The list of [declarations] can |
| * be `null` if there are no declarations in the compilation unit. |
| */ |
| CompilationUnitImpl( |
| this.beginToken, |
| ScriptTagImpl scriptTag, |
| List<Directive> directives, |
| List<CompilationUnitMember> declarations, |
| this.endToken) { |
| _scriptTag = _becomeParentOf(scriptTag); |
| _directives = new NodeListImpl<Directive>(this, directives); |
| _declarations = new NodeListImpl<CompilationUnitMember>(this, declarations); |
| } |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities { |
| ChildEntities result = new ChildEntities()..add(_scriptTag); |
| if (_directivesAreBeforeDeclarations) { |
| result..addAll(_directives)..addAll(_declarations); |
| } else { |
| result.addAll(sortedDirectivesAndDeclarations); |
| } |
| return result; |
| } |
| |
| @override |
| NodeList<CompilationUnitMember> get declarations => _declarations; |
| |
| @override |
| NodeList<Directive> get directives => _directives; |
| |
| @override |
| int get length { |
| Token endToken = this.endToken; |
| if (endToken == null) { |
| return 0; |
| } |
| return endToken.offset + endToken.length; |
| } |
| |
| @override |
| int get offset => 0; |
| |
| @override |
| ScriptTag get scriptTag => _scriptTag; |
| |
| @override |
| void set scriptTag(ScriptTag scriptTag) { |
| _scriptTag = _becomeParentOf(scriptTag as ScriptTagImpl); |
| } |
| |
| @override |
| List<AstNode> get sortedDirectivesAndDeclarations { |
| return <AstNode>[] |
| ..addAll(_directives) |
| ..addAll(_declarations) |
| ..sort(AstNode.LEXICAL_ORDER); |
| } |
| |
| /** |
| * Return `true` if all of the directives are lexically before any |
| * declarations. |
| */ |
| bool get _directivesAreBeforeDeclarations { |
| if (_directives.isEmpty || _declarations.isEmpty) { |
| return true; |
| } |
| Directive lastDirective = _directives[_directives.length - 1]; |
| CompilationUnitMember firstDeclaration = _declarations[0]; |
| return lastDirective.offset < firstDeclaration.offset; |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitCompilationUnit(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _scriptTag?.accept(visitor); |
| if (_directivesAreBeforeDeclarations) { |
| _directives.accept(visitor); |
| _declarations.accept(visitor); |
| } else { |
| List<AstNode> sortedMembers = sortedDirectivesAndDeclarations; |
| int length = sortedMembers.length; |
| for (int i = 0; i < length; i++) { |
| AstNode child = sortedMembers[i]; |
| child.accept(visitor); |
| } |
| } |
| } |
| } |
| |
| /** |
| * A node that declares one or more names within the scope of a compilation |
| * unit. |
| * |
| * compilationUnitMember ::= |
| * [ClassDeclaration] |
| * | [TypeAlias] |
| * | [FunctionDeclaration] |
| * | [MethodDeclaration] |
| * | [VariableDeclaration] |
| * | [VariableDeclaration] |
| */ |
| abstract class CompilationUnitMemberImpl extends DeclarationImpl |
| implements CompilationUnitMember { |
| /** |
| * Initialize a newly created generic compilation unit member. Either or both |
| * of the [comment] and [metadata] can be `null` if the member does not have |
| * the corresponding attribute. |
| */ |
| CompilationUnitMemberImpl(CommentImpl comment, List<Annotation> metadata) |
| : super(comment, metadata); |
| } |
| |
| /** |
| * A conditional expression. |
| * |
| * conditionalExpression ::= |
| * [Expression] '?' [Expression] ':' [Expression] |
| */ |
| class ConditionalExpressionImpl extends ExpressionImpl |
| implements ConditionalExpression { |
| /** |
| * The condition used to determine which of the expressions is executed next. |
| */ |
| ExpressionImpl _condition; |
| |
| /** |
| * The token used to separate the condition from the then expression. |
| */ |
| @override |
| Token question; |
| |
| /** |
| * The expression that is executed if the condition evaluates to `true`. |
| */ |
| ExpressionImpl _thenExpression; |
| |
| /** |
| * The token used to separate the then expression from the else expression. |
| */ |
| @override |
| Token colon; |
| |
| /** |
| * The expression that is executed if the condition evaluates to `false`. |
| */ |
| ExpressionImpl _elseExpression; |
| |
| /** |
| * Initialize a newly created conditional expression. |
| */ |
| ConditionalExpressionImpl( |
| ExpressionImpl condition, |
| this.question, |
| ExpressionImpl thenExpression, |
| this.colon, |
| ExpressionImpl elseExpression) { |
| _condition = _becomeParentOf(condition); |
| _thenExpression = _becomeParentOf(thenExpression); |
| _elseExpression = _becomeParentOf(elseExpression); |
| } |
| |
| @override |
| Token get beginToken => _condition.beginToken; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => new ChildEntities() |
| ..add(_condition) |
| ..add(question) |
| ..add(_thenExpression) |
| ..add(colon) |
| ..add(_elseExpression); |
| |
| @override |
| Expression get condition => _condition; |
| |
| @override |
| void set condition(Expression expression) { |
| _condition = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| @override |
| Expression get elseExpression => _elseExpression; |
| |
| @override |
| void set elseExpression(Expression expression) { |
| _elseExpression = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| @override |
| Token get endToken => _elseExpression.endToken; |
| |
| @override |
| int get precedence => 3; |
| |
| @override |
| Expression get thenExpression => _thenExpression; |
| |
| @override |
| void set thenExpression(Expression expression) { |
| _thenExpression = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => |
| visitor.visitConditionalExpression(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _condition?.accept(visitor); |
| _thenExpression?.accept(visitor); |
| _elseExpression?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A configuration in either an import or export directive. |
| * |
| * configuration ::= |
| * 'if' '(' test ')' uri |
| * |
| * test ::= |
| * dottedName ('==' stringLiteral)? |
| * |
| * dottedName ::= |
| * identifier ('.' identifier)* |
| */ |
| class ConfigurationImpl extends AstNodeImpl implements Configuration { |
| @override |
| Token ifKeyword; |
| |
| @override |
| Token leftParenthesis; |
| |
| DottedNameImpl _name; |
| |
| @override |
| Token equalToken; |
| |
| StringLiteralImpl _value; |
| |
| @override |
| Token rightParenthesis; |
| |
| StringLiteralImpl _uri; |
| |
| @override |
| Source uriSource; |
| |
| ConfigurationImpl( |
| this.ifKeyword, |
| this.leftParenthesis, |
| DottedNameImpl name, |
| this.equalToken, |
| StringLiteralImpl value, |
| this.rightParenthesis, |
| StringLiteralImpl libraryUri) { |
| _name = _becomeParentOf(name); |
| _value = _becomeParentOf(value); |
| _uri = _becomeParentOf(libraryUri); |
| } |
| |
| @override |
| Token get beginToken => ifKeyword; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => new ChildEntities() |
| ..add(ifKeyword) |
| ..add(leftParenthesis) |
| ..add(_name) |
| ..add(equalToken) |
| ..add(_value) |
| ..add(rightParenthesis) |
| ..add(_uri); |
| |
| @override |
| Token get endToken => _uri.endToken; |
| |
| @deprecated |
| @override |
| StringLiteral get libraryUri => _uri; |
| |
| @deprecated |
| @override |
| void set libraryUri(StringLiteral libraryUri) { |
| _uri = _becomeParentOf(libraryUri as StringLiteralImpl); |
| } |
| |
| @override |
| DottedName get name => _name; |
| |
| @override |
| void set name(DottedName name) { |
| _name = _becomeParentOf(name as DottedNameImpl); |
| } |
| |
| @override |
| StringLiteral get uri => _uri; |
| |
| @override |
| void set uri(StringLiteral uri) { |
| _uri = _becomeParentOf(uri as StringLiteralImpl); |
| } |
| |
| @override |
| StringLiteral get value => _value; |
| |
| @override |
| void set value(StringLiteral value) { |
| _value = _becomeParentOf(value as StringLiteralImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitConfiguration(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _name?.accept(visitor); |
| _value?.accept(visitor); |
| _uri?.accept(visitor); |
| } |
| } |
| |
| /** |
| * An error listener that only records whether any constant related errors have |
| * been reported. |
| */ |
| class ConstantAnalysisErrorListener extends AnalysisErrorListener { |
| /** |
| * A flag indicating whether any constant related errors have been reported to |
| * this listener. |
| */ |
| bool hasConstError = false; |
| |
| @override |
| void onError(AnalysisError error) { |
| ErrorCode errorCode = error.errorCode; |
| if (errorCode is CompileTimeErrorCode) { |
| switch (errorCode) { |
| case CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL: |
| case CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING: |
| case CompileTimeErrorCode.CONST_EVAL_TYPE_INT: |
| case CompileTimeErrorCode.CONST_EVAL_TYPE_NUM: |
| case CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION: |
| case CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE: |
| case CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT: |
| case CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER: |
| case CompileTimeErrorCode |
| .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST: |
| case CompileTimeErrorCode.INVALID_CONSTANT: |
| case CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL: |
| hasConstError = true; |
| } |
| } |
| } |
| } |
| |
| /** |
| * A constructor declaration. |
| * |
| * constructorDeclaration ::= |
| * constructorSignature [FunctionBody]? |
| * | constructorName formalParameterList ':' 'this' ('.' [SimpleIdentifier])? arguments |
| * |
| * constructorSignature ::= |
| * 'external'? constructorName formalParameterList initializerList? |
| * | 'external'? 'factory' factoryName formalParameterList initializerList? |
| * | 'external'? 'const' constructorName formalParameterList initializerList? |
| * |
| * constructorName ::= |
| * [SimpleIdentifier] ('.' [SimpleIdentifier])? |
| * |
| * factoryName ::= |
| * [Identifier] ('.' [SimpleIdentifier])? |
| * |
| * initializerList ::= |
| * ':' [ConstructorInitializer] (',' [ConstructorInitializer])* |
| */ |
| class ConstructorDeclarationImpl extends ClassMemberImpl |
| implements ConstructorDeclaration { |
| /** |
| * The token for the 'external' keyword, or `null` if the constructor is not |
| * external. |
| */ |
| @override |
| Token externalKeyword; |
| |
| /** |
| * The token for the 'const' keyword, or `null` if the constructor is not a |
| * const constructor. |
| */ |
| @override |
| Token constKeyword; |
| |
| /** |
| * The token for the 'factory' keyword, or `null` if the constructor is not a |
| * factory constructor. |
| */ |
| @override |
| Token factoryKeyword; |
| |
| /** |
| * The type of object being created. This can be different than the type in |
| * which the constructor is being declared if the constructor is the |
| * implementation of a factory constructor. |
| */ |
| IdentifierImpl _returnType; |
| |
| /** |
| * The token for the period before the constructor name, or `null` if the |
| * constructor being declared is unnamed. |
| */ |
| @override |
| Token period; |
| |
| /** |
| * The name of the constructor, or `null` if the constructor being declared is |
| * unnamed. |
| */ |
| SimpleIdentifierImpl _name; |
| |
| /** |
| * The parameters associated with the constructor. |
| */ |
| FormalParameterListImpl _parameters; |
| |
| /** |
| * The token for the separator (colon or equals) before the initializer list |
| * or redirection, or `null` if there are no initializers. |
| */ |
| @override |
| Token separator; |
| |
| /** |
| * The initializers associated with the constructor. |
| */ |
| NodeList<ConstructorInitializer> _initializers; |
| |
| /** |
| * The name of the constructor to which this constructor will be redirected, |
| * or `null` if this is not a redirecting factory constructor. |
| */ |
| ConstructorNameImpl _redirectedConstructor; |
| |
| /** |
| * The body of the constructor, or `null` if the constructor does not have a |
| * body. |
| */ |
| FunctionBodyImpl _body; |
| |
| /** |
| * The element associated with this constructor, or `null` if the AST |
| * structure has not been resolved or if this constructor could not be |
| * resolved. |
| */ |
| @override |
| ConstructorElement element; |
| |
| /** |
| * Initialize a newly created constructor declaration. The [externalKeyword] |
| * can be `null` if the constructor is not external. Either or both of the |
| * [comment] and [metadata] can be `null` if the constructor does not have the |
| * corresponding attribute. The [constKeyword] can be `null` if the |
| * constructor cannot be used to create a constant. The [factoryKeyword] can |
| * be `null` if the constructor is not a factory. The [period] and [name] can |
| * both be `null` if the constructor is not a named constructor. The |
| * [separator] can be `null` if the constructor does not have any initializers |
| * and does not redirect to a different constructor. The list of |
| * [initializers] can be `null` if the constructor does not have any |
| * initializers. The [redirectedConstructor] can be `null` if the constructor |
| * does not redirect to a different constructor. The [body] can be `null` if |
| * the constructor does not have a body. |
| */ |
| ConstructorDeclarationImpl( |
| CommentImpl comment, |
| List<Annotation> metadata, |
| this.externalKeyword, |
| this.constKeyword, |
| this.factoryKeyword, |
| IdentifierImpl returnType, |
| this.period, |
| SimpleIdentifierImpl name, |
| FormalParameterListImpl parameters, |
| this.separator, |
| List<ConstructorInitializer> initializers, |
| ConstructorNameImpl redirectedConstructor, |
| FunctionBodyImpl body) |
| : super(comment, metadata) { |
| _returnType = _becomeParentOf(returnType); |
| _name = _becomeParentOf(name); |
| _parameters = _becomeParentOf(parameters); |
| _initializers = |
| new NodeListImpl<ConstructorInitializer>(this, initializers); |
| _redirectedConstructor = _becomeParentOf(redirectedConstructor); |
| _body = _becomeParentOf(body); |
| } |
| |
| @override |
| FunctionBody get body => _body; |
| |
| @override |
| void set body(FunctionBody functionBody) { |
| _body = _becomeParentOf(functionBody as FunctionBodyImpl); |
| } |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => super._childEntities |
| ..add(externalKeyword) |
| ..add(constKeyword) |
| ..add(factoryKeyword) |
| ..add(_returnType) |
| ..add(period) |
| ..add(_name) |
| ..add(_parameters) |
| ..add(separator) |
| ..addAll(initializers) |
| ..add(_redirectedConstructor) |
| ..add(_body); |
| |
| @override |
| Token get endToken { |
| if (_body != null) { |
| return _body.endToken; |
| } else if (!_initializers.isEmpty) { |
| return _initializers.endToken; |
| } |
| return _parameters.endToken; |
| } |
| |
| @override |
| Token get firstTokenAfterCommentAndMetadata { |
| Token leftMost = |
| Token.lexicallyFirst([externalKeyword, constKeyword, factoryKeyword]); |
| if (leftMost != null) { |
| return leftMost; |
| } |
| return _returnType.beginToken; |
| } |
| |
| @override |
| NodeList<ConstructorInitializer> get initializers => _initializers; |
| |
| @override |
| SimpleIdentifier get name => _name; |
| |
| @override |
| void set name(SimpleIdentifier identifier) { |
| _name = _becomeParentOf(identifier as SimpleIdentifierImpl); |
| } |
| |
| @override |
| FormalParameterList get parameters => _parameters; |
| |
| @override |
| void set parameters(FormalParameterList parameters) { |
| _parameters = _becomeParentOf(parameters as FormalParameterListImpl); |
| } |
| |
| @override |
| ConstructorName get redirectedConstructor => _redirectedConstructor; |
| |
| @override |
| void set redirectedConstructor(ConstructorName redirectedConstructor) { |
| _redirectedConstructor = |
| _becomeParentOf(redirectedConstructor as ConstructorNameImpl); |
| } |
| |
| @override |
| Identifier get returnType => _returnType; |
| |
| @override |
| void set returnType(Identifier typeName) { |
| _returnType = _becomeParentOf(typeName as IdentifierImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => |
| visitor.visitConstructorDeclaration(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| super.visitChildren(visitor); |
| _returnType?.accept(visitor); |
| _name?.accept(visitor); |
| _parameters?.accept(visitor); |
| _initializers.accept(visitor); |
| _redirectedConstructor?.accept(visitor); |
| _body?.accept(visitor); |
| } |
| } |
| |
| /** |
| * The initialization of a field within a constructor's initialization list. |
| * |
| * fieldInitializer ::= |
| * ('this' '.')? [SimpleIdentifier] '=' [Expression] |
| */ |
| class ConstructorFieldInitializerImpl extends ConstructorInitializerImpl |
| implements ConstructorFieldInitializer { |
| /** |
| * The token for the 'this' keyword, or `null` if there is no 'this' keyword. |
| */ |
| @override |
| Token thisKeyword; |
| |
| /** |
| * The token for the period after the 'this' keyword, or `null` if there is no |
| * 'this' keyword. |
| */ |
| @override |
| Token period; |
| |
| /** |
| * The name of the field being initialized. |
| */ |
| SimpleIdentifierImpl _fieldName; |
| |
| /** |
| * The token for the equal sign between the field name and the expression. |
| */ |
| @override |
| Token equals; |
| |
| /** |
| * The expression computing the value to which the field will be initialized. |
| */ |
| ExpressionImpl _expression; |
| |
| /** |
| * Initialize a newly created field initializer to initialize the field with |
| * the given name to the value of the given expression. The [thisKeyword] and |
| * [period] can be `null` if the 'this' keyword was not specified. |
| */ |
| ConstructorFieldInitializerImpl(this.thisKeyword, this.period, |
| SimpleIdentifierImpl fieldName, this.equals, ExpressionImpl expression) { |
| _fieldName = _becomeParentOf(fieldName); |
| _expression = _becomeParentOf(expression); |
| } |
| |
| @override |
| Token get beginToken { |
| if (thisKeyword != null) { |
| return thisKeyword; |
| } |
| return _fieldName.beginToken; |
| } |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => new ChildEntities() |
| ..add(thisKeyword) |
| ..add(period) |
| ..add(_fieldName) |
| ..add(equals) |
| ..add(_expression); |
| |
| @override |
| Token get endToken => _expression.endToken; |
| |
| @override |
| Expression get expression => _expression; |
| |
| @override |
| void set expression(Expression expression) { |
| _expression = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| @override |
| SimpleIdentifier get fieldName => _fieldName; |
| |
| @override |
| void set fieldName(SimpleIdentifier identifier) { |
| _fieldName = _becomeParentOf(identifier as SimpleIdentifierImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => |
| visitor.visitConstructorFieldInitializer(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _fieldName?.accept(visitor); |
| _expression?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A node that can occur in the initializer list of a constructor declaration. |
| * |
| * constructorInitializer ::= |
| * [SuperConstructorInvocation] |
| * | [ConstructorFieldInitializer] |
| * | [RedirectingConstructorInvocation] |
| */ |
| abstract class ConstructorInitializerImpl extends AstNodeImpl |
| implements ConstructorInitializer {} |
| |
| /** |
| * The name of the constructor. |
| * |
| * constructorName ::= |
| * type ('.' identifier)? |
| */ |
| class ConstructorNameImpl extends AstNodeImpl implements ConstructorName { |
| /** |
| * The name of the type defining the constructor. |
| */ |
| TypeNameImpl _type; |
| |
| /** |
| * The token for the period before the constructor name, or `null` if the |
| * specified constructor is the unnamed constructor. |
| */ |
| @override |
| Token period; |
| |
| /** |
| * The name of the constructor, or `null` if the specified constructor is the |
| * unnamed constructor. |
| */ |
| SimpleIdentifierImpl _name; |
| |
| /** |
| * The element associated with this constructor name based on static type |
| * information, or `null` if the AST structure has not been resolved or if |
| * this constructor name could not be resolved. |
| */ |
| @override |
| ConstructorElement staticElement; |
| |
| /** |
| * Initialize a newly created constructor name. The [period] and [name] can be |
| * `null` if the constructor being named is the unnamed constructor. |
| */ |
| ConstructorNameImpl( |
| TypeNameImpl type, this.period, SimpleIdentifierImpl name) { |
| _type = _becomeParentOf(type); |
| _name = _becomeParentOf(name); |
| } |
| |
| @override |
| Token get beginToken => _type.beginToken; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| new ChildEntities()..add(_type)..add(period)..add(_name); |
| |
| @override |
| Token get endToken { |
| if (_name != null) { |
| return _name.endToken; |
| } |
| return _type.endToken; |
| } |
| |
| @override |
| SimpleIdentifier get name => _name; |
| |
| @override |
| void set name(SimpleIdentifier name) { |
| _name = _becomeParentOf(name as SimpleIdentifierImpl); |
| } |
| |
| @override |
| TypeName get type => _type; |
| |
| @override |
| void set type(TypeName type) { |
| _type = _becomeParentOf(type as TypeNameImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitConstructorName(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _type?.accept(visitor); |
| _name?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A continue statement. |
| * |
| * continueStatement ::= |
| * 'continue' [SimpleIdentifier]? ';' |
| */ |
| class ContinueStatementImpl extends StatementImpl implements ContinueStatement { |
| /** |
| * The token representing the 'continue' keyword. |
| */ |
| @override |
| Token continueKeyword; |
| |
| /** |
| * The label associated with the statement, or `null` if there is no label. |
| */ |
| SimpleIdentifierImpl _label; |
| |
| /** |
| * The semicolon terminating the statement. |
| */ |
| @override |
| Token semicolon; |
| |
| /** |
| * The AstNode which this continue statement is continuing to. This will be |
| * either a Statement (in the case of continuing a loop) or a SwitchMember |
| * (in the case of continuing from one switch case to another). Null if the |
| * AST has not yet been resolved or if the target could not be resolved. |
| * Note that if the source code has errors, the target may be invalid (e.g. |
| * the target may be in an enclosing function). |
| */ |
| AstNode target; |
| |
| /** |
| * Initialize a newly created continue statement. The [label] can be `null` if |
| * there is no label associated with the statement. |
| */ |
| ContinueStatementImpl( |
| this.continueKeyword, SimpleIdentifierImpl label, this.semicolon) { |
| _label = _becomeParentOf(label); |
| } |
| |
| @override |
| Token get beginToken => continueKeyword; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| new ChildEntities()..add(continueKeyword)..add(_label)..add(semicolon); |
| |
| @override |
| Token get endToken => semicolon; |
| |
| @override |
| SimpleIdentifier get label => _label; |
| |
| @override |
| void set label(SimpleIdentifier identifier) { |
| _label = _becomeParentOf(identifier as SimpleIdentifierImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitContinueStatement(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _label?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A node that represents the declaration of one or more names. Each declared |
| * name is visible within a name scope. |
| */ |
| abstract class DeclarationImpl extends AnnotatedNodeImpl |
| implements Declaration { |
| /** |
| * Initialize a newly created declaration. Either or both of the [comment] and |
| * [metadata] can be `null` if the declaration does not have the corresponding |
| * attribute. |
| */ |
| DeclarationImpl(CommentImpl comment, List<Annotation> metadata) |
| : super(comment, metadata); |
| } |
| |
| /** |
| * The declaration of a single identifier. |
| * |
| * declaredIdentifier ::= |
| * [Annotation] finalConstVarOrType [SimpleIdentifier] |
| */ |
| class DeclaredIdentifierImpl extends DeclarationImpl |
| implements DeclaredIdentifier { |
| /** |
| * The token representing either the 'final', 'const' or 'var' keyword, or |
| * `null` if no keyword was used. |
| */ |
| @override |
| Token keyword; |
| |
| /** |
| * The name of the declared type of the parameter, or `null` if the parameter |
| * does not have a declared type. |
| */ |
| TypeAnnotationImpl _type; |
| |
| /** |
| * The name of the variable being declared. |
| */ |
| SimpleIdentifierImpl _identifier; |
| |
| /** |
| * Initialize a newly created formal parameter. Either or both of the |
| * [comment] and [metadata] can be `null` if the declaration does not have the |
| * corresponding attribute. The [keyword] can be `null` if a type name is |
| * given. The [type] must be `null` if the keyword is 'var'. |
| */ |
| DeclaredIdentifierImpl(CommentImpl comment, List<Annotation> metadata, |
| this.keyword, TypeAnnotationImpl type, SimpleIdentifierImpl identifier) |
| : super(comment, metadata) { |
| _type = _becomeParentOf(type); |
| _identifier = _becomeParentOf(identifier); |
| } |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| super._childEntities..add(keyword)..add(_type)..add(_identifier); |
| |
| @override |
| LocalVariableElement get element { |
| if (_identifier == null) { |
| return null; |
| } |
| return _identifier.staticElement as LocalVariableElement; |
| } |
| |
| @override |
| Token get endToken => _identifier.endToken; |
| |
| @override |
| Token get firstTokenAfterCommentAndMetadata { |
| if (keyword != null) { |
| return keyword; |
| } else if (_type != null) { |
| return _type.beginToken; |
| } |
| return _identifier.beginToken; |
| } |
| |
| @override |
| SimpleIdentifier get identifier => _identifier; |
| |
| @override |
| void set identifier(SimpleIdentifier identifier) { |
| _identifier = _becomeParentOf(identifier as SimpleIdentifierImpl); |
| } |
| |
| @override |
| bool get isConst => keyword?.keyword == Keyword.CONST; |
| |
| @override |
| bool get isFinal => keyword?.keyword == Keyword.FINAL; |
| |
| @override |
| TypeAnnotation get type => _type; |
| |
| @override |
| void set type(TypeAnnotation type) { |
| _type = _becomeParentOf(type as TypeAnnotationImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => visitor.visitDeclaredIdentifier(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| super.visitChildren(visitor); |
| _type?.accept(visitor); |
| _identifier?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A simple identifier that declares a name. |
| */ |
| // TODO(rnystrom): Consider making this distinct from [SimpleIdentifier] and |
| // get rid of all of the: |
| // |
| // if (node.inDeclarationContext()) { ... } |
| // |
| // code and instead visit this separately. A declaration is semantically pretty |
| // different from a use, so using the same node type doesn't seem to buy us |
| // much. |
| class DeclaredSimpleIdentifier extends SimpleIdentifierImpl { |
| DeclaredSimpleIdentifier(Token token) : super(token); |
| |
| @override |
| bool inDeclarationContext() => true; |
| } |
| |
| /** |
| * A formal parameter with a default value. There are two kinds of parameters |
| * that are both represented by this class: named formal parameters and |
| * positional formal parameters. |
| * |
| * defaultFormalParameter ::= |
| * [NormalFormalParameter] ('=' [Expression])? |
| * |
| * defaultNamedParameter ::= |
| * [NormalFormalParameter] (':' [Expression])? |
| */ |
| class DefaultFormalParameterImpl extends FormalParameterImpl |
| implements DefaultFormalParameter { |
| /** |
| * The formal parameter with which the default value is associated. |
| */ |
| NormalFormalParameterImpl _parameter; |
| |
| /** |
| * The kind of this parameter. |
| */ |
| @override |
| ParameterKind kind; |
| |
| /** |
| * The token separating the parameter from the default value, or `null` if |
| * there is no default value. |
| */ |
| @override |
| Token separator; |
| |
| /** |
| * The expression computing the default value for the parameter, or `null` if |
| * there is no default value. |
| */ |
| ExpressionImpl _defaultValue; |
| |
| /** |
| * Initialize a newly created default formal parameter. The [separator] and |
| * [defaultValue] can be `null` if there is no default value. |
| */ |
| DefaultFormalParameterImpl(NormalFormalParameterImpl parameter, this.kind, |
| this.separator, ExpressionImpl defaultValue) { |
| _parameter = _becomeParentOf(parameter); |
| _defaultValue = _becomeParentOf(defaultValue); |
| } |
| |
| @override |
| Token get beginToken => _parameter.beginToken; |
| |
| @override |
| Iterable<SyntacticEntity> get childEntities => |
| new ChildEntities()..add(_parameter)..add(separator)..add(_defaultValue); |
| |
| @override |
| Token get covariantKeyword => null; |
| |
| @override |
| Expression get defaultValue => _defaultValue; |
| |
| @override |
| void set defaultValue(Expression expression) { |
| _defaultValue = _becomeParentOf(expression as ExpressionImpl); |
| } |
| |
| @override |
| Token get endToken { |
| if (_defaultValue != null) { |
| return _defaultValue.endToken; |
| } |
| return _parameter.endToken; |
| } |
| |
| @override |
| SimpleIdentifier get identifier => _parameter.identifier; |
| |
| @override |
| bool get isConst => _parameter != null && _parameter.isConst; |
| |
| @override |
| bool get isFinal => _parameter != null && _parameter.isFinal; |
| |
| @override |
| NodeList<Annotation> get metadata => _parameter.metadata; |
| |
| @override |
| NormalFormalParameter get parameter => _parameter; |
| |
| @override |
| void set parameter(NormalFormalParameter formalParameter) { |
| _parameter = _becomeParentOf(formalParameter as NormalFormalParameterImpl); |
| } |
| |
| @override |
| E accept<E>(AstVisitor<E> visitor) => |
| visitor.visitDefaultFormalParameter(this); |
| |
| @override |
| void visitChildren(AstVisitor visitor) { |
| _parameter?.accept(visitor); |
| _defaultValue?.accept(visitor); |
| } |
| } |
| |
| /** |
| * A node that represents a directive. |
| * |
| * directive ::= |
| * [ExportDirective] |
| * | [ImportDirective] |
| * | [LibraryDirective] |
| * | [PartDirective] |
| * | [PartOfDirective] |
| */ |
| abstract class DirectiveImpl extends AnnotatedNodeImpl implements Directive { |
| /** |
| * The element associated with this directive, or `null` if the AST structure |
| * has not been resolved or if this directive could not be resolved. |
| */ |
| Element _element; |
| |
| /** |
| * Initialize a newly create directive. Either or both of the [comment] and |
| * [metadata] can be `null` if the directive does not have the corresponding |
| * attribute. |
| */ |
| DirectiveImpl(CommentImpl comment, List<Annotation> metadata) |
| : super(comment, metadata); |
| |
| @override |
| Element get element => _element; |
| |
| /** |
| * Set the element associated with this directive to be the given [element]. |
| */ |
| void set element(Element element) { |
| _element = element; |
| } |
| } |
| |
| /** |
| * A do statement. |
| * |
| * doStatement ::= |
| * 'do' [Statement] 'while' '(' [Expression] ')' ';' |
| */ |
| class DoStatementImpl extends StatementImpl implements DoStatement { |
| /** |
| * The token representing the 'do' keyword. |
| */ |
| @override |
| Token doKeyword; |
| |
|