| // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:kernel/ast.dart'; |
| import 'package:kernel/src/printer.dart'; |
| |
| import '../base/problems.dart' show unsupported; |
| |
| import '../type_inference/type_schema.dart'; |
| |
| import 'collections.dart' |
| show |
| ForElement, |
| ForInElement, |
| ForInMapEntry, |
| ForMapEntry, |
| IfCaseElement, |
| IfCaseMapEntry, |
| IfElement, |
| IfMapEntry, |
| NullAwareElement, |
| NullAwareMapEntry, |
| PatternForElement, |
| PatternForMapEntry, |
| SpreadElement; |
| |
| import 'internal_ast.dart'; |
| |
| /// A shadow tree factory. |
| class Forest { |
| const Forest(); |
| |
| ArgumentsImpl createArguments( |
| int fileOffset, |
| List<Expression> positional, { |
| List<DartType>? types, |
| List<NamedExpression>? named, |
| bool hasExplicitTypeArguments = true, |
| List<Object?>? argumentsOriginalOrder, |
| }) { |
| if (!hasExplicitTypeArguments) { |
| ArgumentsImpl arguments = new ArgumentsImpl( |
| positional, |
| types: <DartType>[], |
| named: named, |
| argumentsOriginalOrder: argumentsOriginalOrder, |
| ); |
| arguments.types.addAll(types!); |
| return arguments; |
| } else { |
| return new ArgumentsImpl( |
| positional, |
| types: types, |
| named: named, |
| argumentsOriginalOrder: argumentsOriginalOrder, |
| )..fileOffset = fileOffset; |
| } |
| } |
| |
| ArgumentsImpl createArgumentsEmpty(int fileOffset) { |
| return createArguments(fileOffset, <Expression>[]); |
| } |
| |
| List<NamedExpression> argumentsNamed(Arguments arguments) { |
| return arguments.named; |
| } |
| |
| List<Expression> argumentsPositional(Arguments arguments) { |
| return arguments.positional; |
| } |
| |
| List<DartType> argumentsTypeArguments(Arguments arguments) { |
| return arguments.types; |
| } |
| |
| void argumentsSetTypeArguments(Arguments arguments, List<DartType> types) { |
| ArgumentsImpl.setNonInferrableArgumentTypes( |
| arguments as ArgumentsImpl, |
| types, |
| ); |
| } |
| |
| /// Return a representation of a boolean literal at the given [fileOffset]. |
| /// The literal has the given [value]. |
| BoolLiteral createBoolLiteral(int fileOffset, bool value) { |
| return new BoolLiteral(value)..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a double literal at the given [fileOffset]. The |
| /// literal has the given [value]. |
| DoubleLiteral createDoubleLiteral(int fileOffset, double value) { |
| return new DoubleLiteral(value)..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of an integer literal at the given [fileOffset]. |
| /// The literal has the given [value]. |
| IntLiteral createIntLiteral(int fileOffset, int value, [String? literal]) { |
| return new IntJudgment(value, literal)..fileOffset = fileOffset; |
| } |
| |
| IntLiteral createIntLiteralLarge( |
| int fileOffset, |
| String strippedLiteral, |
| String literal, |
| ) { |
| return new ShadowLargeIntLiteral(strippedLiteral, literal, fileOffset); |
| } |
| |
| /// Return a representation of a list literal at the given [fileOffset]. The |
| /// [isConst] is `true` if the literal is either explicitly or implicitly a |
| /// constant. The [typeArgument] is the representation of the single valid |
| /// type argument preceding the list literal, or `null` if there is no type |
| /// argument, there is more than one type argument, or if the type argument |
| /// cannot be resolved. The list of [expressions] is a list of the |
| /// representations of the list elements. |
| ListLiteral createListLiteral( |
| int fileOffset, |
| DartType typeArgument, |
| List<Expression> expressions, { |
| required bool isConst, |
| }) { |
| return new ListLiteral( |
| expressions, |
| typeArgument: typeArgument, |
| isConst: isConst, |
| )..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a set literal at the given [fileOffset]. The |
| /// [isConst] is `true` if the literal is either explicitly or implicitly a |
| /// constant. The [typeArgument] is the representation of the single valid |
| /// type argument preceding the set literal, or `null` if there is no type |
| /// argument, there is more than one type argument, or if the type argument |
| /// cannot be resolved. The list of [expressions] is a list of the |
| /// representations of the set elements. |
| SetLiteral createSetLiteral( |
| int fileOffset, |
| DartType typeArgument, |
| List<Expression> expressions, { |
| required bool isConst, |
| }) { |
| return new SetLiteral( |
| expressions, |
| typeArgument: typeArgument, |
| isConst: isConst, |
| )..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a map literal at the given [fileOffset]. The |
| /// [isConst] is `true` if the literal is either explicitly or implicitly a |
| /// constant. The [keyType] is the representation of the first type argument |
| /// preceding the map literal, or `null` if there are not exactly two type |
| /// arguments or if the first type argument cannot be resolved. The |
| /// [valueType] is the representation of the second type argument preceding |
| /// the map literal, or `null` if there are not exactly two type arguments or |
| /// if the second type argument cannot be resolved. The list of [entries] is a |
| /// list of the representations of the map entries. |
| MapLiteral createMapLiteral( |
| int fileOffset, |
| DartType keyType, |
| DartType valueType, |
| List<MapLiteralEntry> entries, { |
| required bool isConst, |
| }) { |
| return new MapLiteral( |
| entries, |
| keyType: keyType, |
| valueType: valueType, |
| isConst: isConst, |
| )..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a null literal at the given [fileOffset]. |
| NullLiteral createNullLiteral(int fileOffset) { |
| return new NullLiteral()..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a simple string literal at the given |
| /// [fileOffset]. The literal has the given [value]. This does not include |
| /// either adjacent strings or interpolated strings. |
| StringLiteral createStringLiteral(int fileOffset, String value) { |
| return new StringLiteral(value)..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a symbol literal defined by [value] at the |
| /// given [fileOffset]. |
| SymbolLiteral createSymbolLiteral(int fileOffset, String value) { |
| return new SymbolLiteral(value)..fileOffset = fileOffset; |
| } |
| |
| TypeLiteral createTypeLiteral(int fileOffset, DartType type) { |
| return new TypeLiteral(type)..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a key/value pair in a literal map at the given |
| /// [fileOffset]. The [key] is the representation of the expression used to |
| /// compute the key. The [value] is the representation of the expression used |
| /// to compute the value. |
| MapLiteralEntry createMapEntry( |
| int fileOffset, |
| Expression key, |
| Expression value, |
| ) { |
| return new MapLiteralEntry(key, value)..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a null-aware key/value pair, were either the |
| /// key or the value might be `null`, in a literal map at the given |
| /// [fileOffset]. The [key] is the representation of the expression used to |
| /// compute the key. The [value] is the representation of the expression used |
| /// to compute the value. |
| NullAwareMapEntry createNullAwareMapEntry( |
| int fileOffset, { |
| required bool isKeyNullAware, |
| required Expression key, |
| required bool isValueNullAware, |
| required Expression value, |
| }) { |
| return new NullAwareMapEntry( |
| isKeyNullAware: isKeyNullAware, |
| key: key, |
| isValueNullAware: isValueNullAware, |
| value: value, |
| )..fileOffset = fileOffset; |
| } |
| |
| LoadLibrary createLoadLibrary( |
| int fileOffset, |
| LibraryDependency dependency, |
| Arguments? arguments, |
| ) { |
| return new LoadLibraryImpl(dependency, arguments)..fileOffset = fileOffset; |
| } |
| |
| Expression checkLibraryIsLoaded( |
| int fileOffset, |
| LibraryDependency dependency, |
| ) { |
| return new CheckLibraryIsLoaded(dependency)..fileOffset = fileOffset; |
| } |
| |
| Expression createAsExpression( |
| int fileOffset, |
| Expression expression, |
| DartType type, { |
| bool forDynamic = false, |
| }) { |
| return new AsExpression(expression, type) |
| ..fileOffset = fileOffset |
| ..isForDynamic = forDynamic; |
| } |
| |
| Expression createSpreadElement( |
| int fileOffset, |
| Expression expression, { |
| required bool isNullAware, |
| }) { |
| return new SpreadElement(expression, isNullAware: isNullAware) |
| ..fileOffset = fileOffset; |
| } |
| |
| Expression createNullAwareElement(int fileOffset, Expression expression) { |
| return new NullAwareElement(expression)..fileOffset = fileOffset; |
| } |
| |
| Expression createIfElement( |
| int fileOffset, |
| Expression condition, |
| Expression then, [ |
| Expression? otherwise, |
| ]) { |
| return new IfElement(condition, then, otherwise)..fileOffset = fileOffset; |
| } |
| |
| Expression createIfCaseElement( |
| int fileOffset, { |
| required List<Statement> prelude, |
| required Expression expression, |
| required PatternGuard patternGuard, |
| required Expression then, |
| Expression? otherwise, |
| }) { |
| return new IfCaseElement( |
| prelude: prelude, |
| expression: expression, |
| patternGuard: patternGuard, |
| then: then, |
| otherwise: otherwise, |
| )..fileOffset = fileOffset; |
| } |
| |
| MapLiteralEntry createIfMapEntry( |
| int fileOffset, |
| Expression condition, |
| MapLiteralEntry then, [ |
| MapLiteralEntry? otherwise, |
| ]) { |
| return new IfMapEntry(condition, then, otherwise)..fileOffset = fileOffset; |
| } |
| |
| MapLiteralEntry createIfCaseMapEntry( |
| int fileOffset, { |
| required List<Statement> prelude, |
| required Expression expression, |
| required PatternGuard patternGuard, |
| required MapLiteralEntry then, |
| MapLiteralEntry? otherwise, |
| }) { |
| return new IfCaseMapEntry( |
| prelude: prelude, |
| expression: expression, |
| patternGuard: patternGuard, |
| then: then, |
| otherwise: otherwise, |
| )..fileOffset = fileOffset; |
| } |
| |
| ForElement createForElement( |
| int fileOffset, |
| List<VariableDeclaration> variables, |
| Expression? condition, |
| List<Expression> updates, |
| Expression body, |
| ) { |
| return new ForElement(variables, condition, updates, body) |
| ..fileOffset = fileOffset; |
| } |
| |
| PatternForElement createPatternForElement( |
| int fileOffset, { |
| required PatternVariableDeclaration patternVariableDeclaration, |
| required List<VariableDeclaration> intermediateVariables, |
| required List<VariableDeclaration> variables, |
| required Expression? condition, |
| required List<Expression> updates, |
| required Expression body, |
| }) { |
| return new PatternForElement( |
| patternVariableDeclaration: patternVariableDeclaration, |
| intermediateVariables: intermediateVariables, |
| variables: variables, |
| condition: condition, |
| updates: updates, |
| body: body, |
| )..fileOffset = fileOffset; |
| } |
| |
| ForMapEntry createForMapEntry( |
| int fileOffset, |
| List<VariableDeclaration> variables, |
| Expression? condition, |
| List<Expression> updates, |
| MapLiteralEntry body, |
| ) { |
| return new ForMapEntry(variables, condition, updates, body) |
| ..fileOffset = fileOffset; |
| } |
| |
| PatternForMapEntry createPatternForMapEntry( |
| int fileOffset, { |
| required PatternVariableDeclaration patternVariableDeclaration, |
| required List<VariableDeclaration> intermediateVariables, |
| required List<VariableDeclaration> variables, |
| required Expression? condition, |
| required List<Expression> updates, |
| required MapLiteralEntry body, |
| }) { |
| return new PatternForMapEntry( |
| patternVariableDeclaration: patternVariableDeclaration, |
| intermediateVariables: intermediateVariables, |
| variables: variables, |
| condition: condition, |
| updates: updates, |
| body: body, |
| )..fileOffset = fileOffset; |
| } |
| |
| ForInElement createForInElement( |
| int fileOffset, |
| VariableDeclaration variable, |
| Expression iterable, |
| Expression? synthesizedAssignment, |
| Statement? expressionEffects, |
| Expression body, |
| Expression? problem, { |
| bool isAsync = false, |
| }) { |
| return new ForInElement( |
| variable, |
| iterable, |
| synthesizedAssignment, |
| expressionEffects, |
| body, |
| problem, |
| isAsync: isAsync, |
| )..fileOffset = fileOffset; |
| } |
| |
| ForInMapEntry createForInMapEntry( |
| int fileOffset, |
| VariableDeclaration variable, |
| Expression iterable, |
| Expression? synthesizedAssignment, |
| Statement? expressionEffects, |
| MapLiteralEntry body, |
| Expression? problem, { |
| bool isAsync = false, |
| }) { |
| return new ForInMapEntry( |
| variable, |
| iterable, |
| synthesizedAssignment, |
| expressionEffects, |
| body, |
| problem, |
| isAsync: isAsync, |
| )..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of an assert that appears in a constructor's |
| /// initializer list. |
| AssertInitializer createAssertInitializer( |
| int fileOffset, |
| AssertStatement assertStatement, |
| ) { |
| return new AssertInitializer(assertStatement)..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of an assert that appears as a statement. |
| AssertStatement createAssertStatement( |
| int fileOffset, |
| Expression condition, |
| Expression? message, |
| int conditionStartOffset, |
| int conditionEndOffset, |
| ) { |
| return new AssertStatement( |
| condition, |
| conditionStartOffset: conditionStartOffset, |
| conditionEndOffset: conditionEndOffset, |
| message: message, |
| )..fileOffset = fileOffset; |
| } |
| |
| Expression createAwaitExpression(int fileOffset, Expression operand) { |
| return new AwaitExpression(operand)..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a block of [statements] at the given |
| /// [fileOffset]. |
| Block createBlock( |
| int fileOffset, |
| int fileEndOffset, |
| List<Statement> statements, |
| ) { |
| List<Statement>? copy; |
| for (int i = 0; i < statements.length; i++) { |
| Statement statement = statements[i]; |
| if (statement is _VariablesDeclaration) { |
| copy ??= new List<Statement>.of(statements.getRange(0, i)); |
| copy.addAll(statement.declarations); |
| } else if (copy != null) { |
| copy.add(statement); |
| } |
| } |
| return new Block(copy ?? statements) |
| ..fileOffset = fileOffset |
| ..fileEndOffset = fileEndOffset; |
| } |
| |
| /// Return a representation of a break statement. |
| Statement createBreakStatement(int fileOffset, Object? label) { |
| // TODO(johnniwinther): Use [label]? |
| return new BreakStatementImpl(isContinue: false) |
| ..fileOffset = fileOffset |
| ..target = label is LabeledStatement ? label : dummyLabeledStatement; |
| } |
| |
| /// Return a representation of a catch clause. |
| Catch createCatch( |
| int fileOffset, |
| DartType exceptionType, |
| VariableDeclaration? exceptionParameter, |
| VariableDeclaration? stackTraceParameter, |
| DartType stackTraceType, |
| Statement body, |
| ) { |
| return new Catch( |
| exceptionParameter, |
| body, |
| guard: exceptionType, |
| stackTrace: stackTraceParameter, |
| )..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a conditional expression at the given |
| /// [fileOffset]. The [condition] is the expression preceding the question |
| /// mark. The [thenExpression] is the expression following the question mark. |
| /// The [elseExpression] is the expression following the colon. |
| ConditionalExpression createConditionalExpression( |
| int fileOffset, |
| Expression condition, |
| Expression thenExpression, |
| Expression elseExpression, |
| ) { |
| return new ConditionalExpression( |
| condition, |
| thenExpression, |
| elseExpression, |
| const UnknownType(), |
| )..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a continue statement. |
| Statement createContinueStatement(int fileOffset, Object? label) { |
| // TODO(johnniwinther): Use [label]? |
| return new BreakStatementImpl(isContinue: true)..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a do statement. |
| Statement createDoStatement( |
| int fileOffset, |
| Statement body, |
| Expression condition, |
| ) { |
| return new DoStatement(body, condition)..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of an expression statement at the given |
| /// [fileOffset] containing the [expression]. |
| Statement createExpressionStatement(int fileOffset, Expression expression) { |
| return new ExpressionStatement(expression)..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of an empty statement at the given [fileOffset]. |
| Statement createEmptyStatement(int fileOffset) { |
| return new EmptyStatement()..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a for statement. |
| Statement createForStatement( |
| int fileOffset, |
| List<VariableDeclaration>? variables, |
| Expression? condition, |
| List<Expression> updaters, |
| Statement body, |
| ) { |
| return new ForStatement( |
| variables ?? // Coverage-ignore(suite): Not run. |
| [], |
| condition, |
| updaters, |
| body, |
| )..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of an `if` statement. |
| Statement createIfStatement( |
| int fileOffset, |
| Expression condition, |
| Statement thenStatement, |
| Statement? elseStatement, |
| ) { |
| return new IfStatement(condition, thenStatement, elseStatement) |
| ..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of an `is` expression at the given [fileOffset]. |
| /// The [operand] is the representation of the left operand. The [type] is a |
| /// representation of the type that is the right operand. If [notFileOffset] |
| /// is non-null the test is negated the that file offset. |
| Expression createIsExpression( |
| int fileOffset, |
| Expression operand, |
| DartType type, { |
| int? notFileOffset, |
| }) { |
| Expression result = new IsExpression(operand, type) |
| ..fileOffset = fileOffset; |
| if (notFileOffset != null) { |
| result = createNot(notFileOffset, result); |
| } |
| return result; |
| } |
| |
| /// Return a representation of a logical expression at the given [fileOffset] |
| /// having the [leftOperand], [rightOperand] and the [operatorString] |
| /// (either `&&` or `||`). |
| Expression createLogicalExpression( |
| int fileOffset, |
| Expression leftOperand, |
| String operatorString, |
| Expression rightOperand, |
| ) { |
| LogicalExpressionOperator operator; |
| if (operatorString == '&&') { |
| operator = LogicalExpressionOperator.AND; |
| } else if (operatorString == '||') { |
| operator = LogicalExpressionOperator.OR; |
| } else { |
| throw new UnsupportedError( |
| "Unhandled logical operator '$operatorString'", |
| ); |
| } |
| |
| return new LogicalExpression(leftOperand, operator, rightOperand) |
| ..fileOffset = fileOffset; |
| } |
| |
| Expression createNot(int fileOffset, Expression operand) { |
| return new Not(operand)..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a rethrow statement consisting of the |
| /// rethrow at [rethrowFileOffset] and the statement at [statementFileOffset]. |
| Statement createRethrowStatement( |
| int rethrowFileOffset, |
| int statementFileOffset, |
| ) { |
| return new ExpressionStatement( |
| new Rethrow()..fileOffset = rethrowFileOffset, |
| )..fileOffset = statementFileOffset; |
| } |
| |
| /// Return a representation of a return statement. |
| Statement createReturnStatement( |
| int fileOffset, |
| Expression? expression, { |
| bool isArrow = true, |
| }) { |
| return new ReturnStatementImpl(isArrow, expression) |
| ..fileOffset = fileOffset; |
| } |
| |
| Expression createStringConcatenation( |
| int fileOffset, |
| List<Expression> expressions, |
| ) { |
| assert(fileOffset != TreeNode.noOffset); |
| return new StringConcatenation(expressions)..fileOffset = fileOffset; |
| } |
| |
| /// The given [statement] is being used as the target of either a break or |
| /// continue statement. Return the statement that should be used as the actual |
| /// target. |
| LabeledStatement createLabeledStatement(Statement statement) { |
| return new LabeledStatement(statement)..fileOffset = statement.fileOffset; |
| } |
| |
| Expression createThisExpression(int fileOffset) { |
| return new ThisExpression()..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a throw expression at the given [fileOffset]. |
| Expression createThrow(int fileOffset, Expression expression) { |
| return new Throw(expression)..fileOffset = fileOffset; |
| } |
| |
| bool isThrow(Object? o) => o is Throw; |
| |
| Statement createTryStatement( |
| int fileOffset, |
| Statement tryBlock, |
| List<Catch>? catchBlocks, |
| Statement? finallyBlock, |
| ) { |
| return new TryStatement(tryBlock, catchBlocks ?? <Catch>[], finallyBlock) |
| ..fileOffset = fileOffset; |
| } |
| |
| _VariablesDeclaration variablesDeclaration( |
| List<VariableDeclaration> declarations, |
| Uri uri, |
| ) { |
| return new _VariablesDeclaration(declarations, uri); |
| } |
| |
| List<VariableDeclaration> variablesDeclarationExtractDeclarations( |
| Object? variablesDeclaration, |
| ) { |
| return (variablesDeclaration as _VariablesDeclaration).declarations; |
| } |
| |
| Statement wrapVariables(Statement statement) { |
| if (statement is _VariablesDeclaration) { |
| return new Block( |
| new List<Statement>.of(statement.declarations, growable: true), |
| )..fileOffset = statement.fileOffset; |
| } else if (statement is VariableDeclaration) { |
| return new Block(<Statement>[statement]) |
| ..fileOffset = statement.fileOffset; |
| } else { |
| return statement; |
| } |
| } |
| |
| /// Return a representation of a while statement at the given [fileOffset] |
| /// consisting of the given [condition] and [body]. |
| Statement createWhileStatement( |
| int fileOffset, |
| Expression condition, |
| Statement body, |
| ) { |
| return new WhileStatement(condition, body)..fileOffset = fileOffset; |
| } |
| |
| /// Return a representation of a yield statement at the given [fileOffset] |
| /// of the given [expression]. If [isYieldStar] is `true` the created |
| /// statement is a yield* statement. |
| Statement createYieldStatement( |
| int fileOffset, |
| Expression expression, { |
| required bool isYieldStar, |
| }) { |
| return new YieldStatement(expression, isYieldStar: isYieldStar) |
| ..fileOffset = fileOffset; |
| } |
| |
| bool isErroneousNode(Object? node) { |
| if (node is ExpressionStatement) { |
| // Coverage-ignore-block(suite): Not run. |
| ExpressionStatement statement = node; |
| node = statement.expression; |
| } |
| if (node is VariableDeclaration) { |
| // Coverage-ignore-block(suite): Not run. |
| VariableDeclaration variable = node; |
| node = variable.initializer; |
| } |
| if (node is Let) { |
| // Coverage-ignore-block(suite): Not run. |
| Let let = node; |
| node = let.variable.initializer; |
| } |
| return node is InvalidExpression; |
| } |
| |
| bool isThisExpression(Object node) => node is ThisExpression; |
| |
| bool isVariablesDeclaration(Object? node) => node is _VariablesDeclaration; |
| |
| /// Creates [VariableDeclaration] for a variable named [name] at the given |
| /// [functionNestingLevel]. |
| VariableDeclaration createVariableDeclaration( |
| int fileOffset, |
| String? name, { |
| Expression? initializer, |
| DartType? type, |
| bool isFinal = false, |
| bool isConst = false, |
| bool isInitializingFormal = false, |
| bool isSuperInitializingFormal = false, |
| bool isCovariantByDeclaration = false, |
| bool isLocalFunction = false, |
| bool isSynthesized = false, |
| }) { |
| return new VariableDeclarationImpl( |
| name, |
| type: type, |
| initializer: initializer, |
| isFinal: isFinal, |
| isConst: isConst, |
| isInitializingFormal: isInitializingFormal, |
| isSuperInitializingFormal: isSuperInitializingFormal, |
| isCovariantByDeclaration: isCovariantByDeclaration, |
| isLocalFunction: isLocalFunction, |
| isSynthesized: isSynthesized, |
| hasDeclaredInitializer: initializer != null, |
| )..fileOffset = fileOffset; |
| } |
| |
| VariableDeclarationImpl createVariableDeclarationForValue( |
| Expression initializer, { |
| DartType type = const DynamicType(), |
| }) { |
| return new VariableDeclarationImpl.forValue(initializer) |
| ..type = type |
| ..fileOffset = initializer.fileOffset; |
| } |
| |
| TypeParameterType createTypeParameterTypeWithDefaultNullabilityForLibrary( |
| TypeParameter typeParameter, |
| Library library, |
| ) { |
| return new TypeParameterType.withDefaultNullability(typeParameter); |
| } |
| |
| Expression createExpressionInvocation( |
| int fileOffset, |
| Expression expression, |
| Arguments arguments, |
| ) { |
| return new ExpressionInvocation(expression, arguments) |
| ..fileOffset = fileOffset; |
| } |
| |
| Expression createMethodInvocation( |
| int fileOffset, |
| Expression expression, |
| Name name, |
| Arguments arguments, { |
| required bool isNullAware, |
| }) { |
| return new MethodInvocation( |
| expression, |
| name, |
| arguments, |
| isNullAware: isNullAware, |
| )..fileOffset = fileOffset; |
| } |
| |
| SuperMethodInvocation createSuperMethodInvocation( |
| int fileOffset, |
| Name name, |
| Procedure procedure, |
| Arguments arguments, |
| ) { |
| return new SuperMethodInvocation(name, arguments, procedure) |
| ..fileOffset = fileOffset; |
| } |
| |
| NullCheck createNullCheck(int fileOffset, Expression expression) { |
| return new NullCheck(expression)..fileOffset = fileOffset; |
| } |
| |
| Expression createPropertyGet( |
| int fileOffset, |
| Expression receiver, |
| Name name, { |
| required bool isNullAware, |
| }) { |
| return new PropertyGet(receiver, name, isNullAware: isNullAware) |
| ..fileOffset = fileOffset; |
| } |
| |
| Expression createPropertySet( |
| int fileOffset, |
| Expression receiver, |
| Name name, |
| Expression value, { |
| required bool forEffect, |
| bool readOnlyReceiver = false, |
| required bool isNullAware, |
| }) { |
| return new PropertySet( |
| receiver, |
| name, |
| value, |
| forEffect: forEffect, |
| readOnlyReceiver: readOnlyReceiver, |
| isNullAware: isNullAware, |
| )..fileOffset = fileOffset; |
| } |
| |
| IndexGet createIndexGet( |
| int fileOffset, |
| Expression receiver, |
| Expression index, { |
| required bool isNullAware, |
| }) { |
| return new IndexGet(receiver, index, isNullAware: isNullAware) |
| ..fileOffset = fileOffset; |
| } |
| |
| IndexSet createIndexSet( |
| int fileOffset, |
| Expression receiver, |
| Expression index, |
| Expression value, { |
| required bool forEffect, |
| required bool isNullAware, |
| }) { |
| return new IndexSet( |
| receiver, |
| index, |
| value, |
| forEffect: forEffect, |
| isNullAware: isNullAware, |
| )..fileOffset = fileOffset; |
| } |
| |
| VariableGet createVariableGet(int fileOffset, VariableDeclaration variable) { |
| return new VariableGet(variable)..fileOffset = fileOffset; |
| } |
| |
| EqualsExpression createEquals( |
| int fileOffset, |
| Expression left, |
| Expression right, { |
| required bool isNot, |
| }) { |
| return new EqualsExpression(left, right, isNot: isNot) |
| ..fileOffset = fileOffset; |
| } |
| |
| BinaryExpression createBinary( |
| int fileOffset, |
| Expression left, |
| Name binaryName, |
| Expression right, |
| ) { |
| return new BinaryExpression(left, binaryName, right) |
| ..fileOffset = fileOffset; |
| } |
| |
| UnaryExpression createUnary( |
| int fileOffset, |
| Name unaryName, |
| Expression expression, |
| ) { |
| return new UnaryExpression(unaryName, expression)..fileOffset = fileOffset; |
| } |
| |
| ParenthesizedExpression createParenthesized( |
| int fileOffset, |
| Expression expression, |
| ) { |
| return new ParenthesizedExpression(expression)..fileOffset = fileOffset; |
| } |
| |
| ConstructorTearOff createConstructorTearOff(int fileOffset, Member target) { |
| assert( |
| target is Constructor || (target is Procedure && target.isFactory), |
| "Unexpected constructor tear off target: $target", |
| ); |
| return new ConstructorTearOff(target)..fileOffset = fileOffset; |
| } |
| |
| StaticTearOff createStaticTearOff(int fileOffset, Procedure procedure) { |
| assert( |
| procedure.kind == ProcedureKind.Method, |
| "Unexpected static tear off target: $procedure", |
| ); |
| assert( |
| !procedure.isRedirectingFactory, |
| "Unexpected static tear off target: $procedure", |
| ); |
| return new StaticTearOff(procedure)..fileOffset = fileOffset; |
| } |
| |
| StaticGet createStaticGet(int fileOffset, Member target) { |
| assert(target is Field || (target is Procedure && target.isGetter)); |
| return new StaticGet(target)..fileOffset = fileOffset; |
| } |
| |
| RedirectingFactoryTearOff createRedirectingFactoryTearOff( |
| int fileOffset, |
| Procedure procedure, |
| ) { |
| assert(procedure.isRedirectingFactory); |
| return new RedirectingFactoryTearOff(procedure)..fileOffset = fileOffset; |
| } |
| |
| Instantiation createInstantiation( |
| int fileOffset, |
| Expression expression, |
| List<DartType> typeArguments, |
| ) { |
| return new Instantiation(expression, typeArguments) |
| ..fileOffset = fileOffset; |
| } |
| |
| TypedefTearOff createTypedefTearOff( |
| int fileOffset, |
| List<StructuralParameter> typeParameters, |
| Expression expression, |
| List<DartType> typeArguments, |
| ) { |
| return new TypedefTearOff(typeParameters, expression, typeArguments) |
| ..fileOffset = fileOffset; |
| } |
| |
| AndPattern createAndPattern(int fileOffset, Pattern left, Pattern right) { |
| return new AndPattern(left, right)..fileOffset = fileOffset; |
| } |
| |
| AssignedVariablePattern createAssignedVariablePattern( |
| int fileOffset, |
| VariableDeclaration variable, |
| ) { |
| return new AssignedVariablePattern(variable)..fileOffset = fileOffset; |
| } |
| |
| CastPattern createCastPattern( |
| int fileOffset, |
| Pattern pattern, |
| DartType type, |
| ) { |
| return new CastPattern(pattern, type)..fileOffset = fileOffset; |
| } |
| |
| ConstantPattern createConstantPattern(Expression expression) { |
| return new ConstantPattern(expression)..fileOffset = expression.fileOffset; |
| } |
| |
| InvalidPattern createInvalidPattern( |
| Expression expression, { |
| required List<VariableDeclaration> declaredVariables, |
| }) { |
| return new InvalidPattern(expression, declaredVariables: declaredVariables) |
| ..fileOffset = expression.fileOffset; |
| } |
| |
| ListPattern createListPattern( |
| int fileOffset, |
| DartType? typeArgument, |
| List<Pattern> patterns, |
| ) { |
| return new ListPattern(typeArgument, patterns)..fileOffset = fileOffset; |
| } |
| |
| MapPattern createMapPattern( |
| int fileOffset, |
| DartType? keyType, |
| DartType? valueType, |
| List<MapPatternEntry> entries, |
| ) { |
| return new MapPattern(keyType, valueType, entries)..fileOffset = fileOffset; |
| } |
| |
| MapPatternEntry createMapPatternEntry( |
| int fileOffset, |
| Expression key, |
| Pattern value, |
| ) { |
| return new MapPatternEntry(key, value)..fileOffset = fileOffset; |
| } |
| |
| MapPatternRestEntry createMapPatternRestEntry(int fileOffset) { |
| return new MapPatternRestEntry()..fileOffset = fileOffset; |
| } |
| |
| NamedPattern createNamedPattern( |
| int fileOffset, |
| String name, |
| Pattern pattern, |
| ) { |
| return new NamedPattern(name, pattern)..fileOffset = fileOffset; |
| } |
| |
| NullAssertPattern createNullAssertPattern(int fileOffset, Pattern pattern) { |
| return new NullAssertPattern(pattern)..fileOffset = fileOffset; |
| } |
| |
| NullCheckPattern createNullCheckPattern(int fileOffset, Pattern pattern) { |
| return new NullCheckPattern(pattern)..fileOffset = fileOffset; |
| } |
| |
| OrPattern createOrPattern( |
| int fileOffset, |
| Pattern left, |
| Pattern right, { |
| required List<VariableDeclaration> orPatternJointVariables, |
| }) { |
| return new OrPattern( |
| left, |
| right, |
| orPatternJointVariables: orPatternJointVariables, |
| )..fileOffset = fileOffset; |
| } |
| |
| RecordPattern createRecordPattern(int fileOffset, List<Pattern> patterns) { |
| return new RecordPattern(patterns)..fileOffset = fileOffset; |
| } |
| |
| RelationalPattern createRelationalPattern( |
| int fileOffset, |
| RelationalPatternKind kind, |
| Expression expression, |
| ) { |
| return new RelationalPattern(kind, expression)..fileOffset = fileOffset; |
| } |
| |
| RestPattern createRestPattern(int fileOffset, Pattern? subPattern) { |
| return new RestPattern(subPattern)..fileOffset = fileOffset; |
| } |
| |
| VariablePattern createVariablePattern( |
| int fileOffset, |
| DartType? type, |
| VariableDeclaration variable, |
| ) { |
| return new VariablePattern(type, variable)..fileOffset = fileOffset; |
| } |
| |
| WildcardPattern createWildcardPattern(int fileOffset, DartType? type) { |
| return new WildcardPattern(type)..fileOffset = fileOffset; |
| } |
| |
| PatternGuard createPatternGuard( |
| int fileOffset, |
| Pattern pattern, [ |
| Expression? guard, |
| ]) { |
| return new PatternGuard(pattern, guard)..fileOffset = fileOffset; |
| } |
| |
| PatternSwitchCase createPatternSwitchCase( |
| int fileOffset, |
| List<int> caseOffsets, |
| List<PatternGuard> patternGuards, |
| Statement body, { |
| required bool isDefault, |
| required bool hasLabel, |
| required List<VariableDeclaration> jointVariables, |
| required List<int>? jointVariableFirstUseOffsets, |
| }) { |
| return new PatternSwitchCase( |
| caseOffsets, |
| patternGuards, |
| body, |
| isDefault: isDefault, |
| hasLabel: hasLabel, |
| jointVariables: jointVariables, |
| jointVariableFirstUseOffsets: jointVariableFirstUseOffsets, |
| )..fileOffset = fileOffset; |
| } |
| |
| PatternSwitchStatement createPatternSwitchStatement( |
| int fileOffset, |
| Expression expression, |
| List<PatternSwitchCase> cases, |
| ) { |
| return new PatternSwitchStatement(expression, cases) |
| ..fileOffset = fileOffset; |
| } |
| |
| SwitchExpressionCase createSwitchExpressionCase( |
| int fileOffset, |
| PatternGuard patternGuard, |
| Expression expression, |
| ) { |
| return new SwitchExpressionCase(patternGuard, expression) |
| ..fileOffset = fileOffset; |
| } |
| |
| SwitchExpression createSwitchExpression( |
| int fileOffset, |
| Expression expression, |
| List<SwitchExpressionCase> cases, |
| ) { |
| return new SwitchExpression(expression, cases)..fileOffset = fileOffset; |
| } |
| |
| PatternVariableDeclaration createPatternVariableDeclaration( |
| int fileOffset, |
| Pattern pattern, |
| Expression initializer, { |
| required bool isFinal, |
| }) { |
| return new PatternVariableDeclaration( |
| pattern, |
| initializer, |
| isFinal: isFinal, |
| )..fileOffset = fileOffset; |
| } |
| |
| PatternAssignment createPatternAssignment( |
| int fileOffset, |
| Pattern pattern, |
| Expression expression, |
| ) { |
| return new PatternAssignment(pattern, expression)..fileOffset = fileOffset; |
| } |
| |
| IfCaseStatement createIfCaseStatement( |
| int fileOffset, |
| Expression expression, |
| PatternGuard patternGuard, |
| Statement then, |
| Statement? otherwise, |
| ) { |
| return new IfCaseStatement(expression, patternGuard, then, otherwise) |
| ..fileOffset = fileOffset; |
| } |
| |
| DotShorthand createDotShorthandContext( |
| int fileOffset, |
| Expression innerExpression, |
| ) { |
| return new DotShorthand(innerExpression)..fileOffset = fileOffset; |
| } |
| |
| DotShorthandInvocation createDotShorthandInvocation( |
| int fileOffset, |
| Name name, |
| Arguments arguments, { |
| required int nameOffset, |
| required bool isConst, |
| }) { |
| return new DotShorthandInvocation( |
| name, |
| arguments, |
| nameOffset: nameOffset, |
| isConst: isConst, |
| )..fileOffset = fileOffset; |
| } |
| |
| DotShorthandPropertyGet createDotShorthandPropertyGet( |
| int fileOffset, |
| Name name, { |
| required int nameOffset, |
| }) { |
| return new DotShorthandPropertyGet(name, nameOffset: nameOffset) |
| ..fileOffset = fileOffset; |
| } |
| } |
| |
| class _VariablesDeclaration extends AuxiliaryStatement { |
| final List<VariableDeclaration> declarations; |
| final Uri uri; |
| |
| _VariablesDeclaration(this.declarations, this.uri) { |
| setParents(declarations, this); |
| } |
| |
| @override |
| // Coverage-ignore(suite): Not run. |
| R accept<R>(v) { |
| throw unsupported("accept", fileOffset, uri); |
| } |
| |
| @override |
| // Coverage-ignore(suite): Not run. |
| R accept1<R, A>(v, arg) { |
| throw unsupported("accept1", fileOffset, uri); |
| } |
| |
| @override |
| // Coverage-ignore(suite): Not run. |
| Never visitChildren(v) { |
| throw unsupported("visitChildren", fileOffset, uri); |
| } |
| |
| @override |
| // Coverage-ignore(suite): Not run. |
| Never transformChildren(v) { |
| throw unsupported("transformChildren", fileOffset, uri); |
| } |
| |
| @override |
| // Coverage-ignore(suite): Not run. |
| Never transformOrRemoveChildren(v) { |
| throw unsupported("transformOrRemoveChildren", fileOffset, uri); |
| } |
| |
| @override |
| String toString() { |
| return "_VariablesDeclaration(${toStringInternal()})"; |
| } |
| |
| @override |
| // Coverage-ignore(suite): Not run. |
| void toTextInternal(AstPrinter printer) { |
| for (int index = 0; index < declarations.length; index++) { |
| if (index > 0) { |
| printer.write(', '); |
| } |
| printer.writeVariableDeclaration( |
| declarations[index], |
| includeModifiersAndType: index == 0, |
| ); |
| } |
| printer.write(';'); |
| } |
| } |