Files
sdk/pkg/front_end/lib/src/fasta/kernel/forest.dart
T
Johnni Winther 8467186ca0 [kernel] Initial migration of package kernel wave 1
This CL completes the migration of the first wave of
interdependent libraries in package:kernel, including ast.dart.

In order to ensure non-nullability on AST properties, the Transformer
has been split in 2 variants: Transformer which doesn't support
removal of nodes and RemovingTransformer which supports removal where
allowed by the context using 'removal sentinels'.

Start reviewing Transformer and RemovingTransformer in visitors.dart
since many of the changes are caused by the changes here.

Included in the migration are the mixin_deduplication.dart and
unreachable_code_elimination.dart since these needed porting to
the RemovingTransformer which was aided by opting in the libraries
which only depended on ast.dart.

TEST=existing

Change-Id: I9e63b985bd24896c25edd4ee51e37770187bcc17
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184786
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
2021-02-18 16:01:17 +00:00

799 lines
28 KiB
Dart

// 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.
// @dart = 2.9
library fasta.fangorn;
import 'package:kernel/ast.dart';
import 'package:kernel/src/printer.dart';
import '../problems.dart' show unsupported;
import 'collections.dart'
show
ForElement,
ForInElement,
ForInMapEntry,
ForMapEntry,
IfElement,
IfMapEntry,
SpreadElement;
import 'internal_ast.dart';
/// A shadow tree factory.
class Forest {
const Forest();
Arguments createArguments(int fileOffset, List<Expression> positional,
{List<DartType> types,
List<NamedExpression> named,
bool hasExplicitTypeArguments = true}) {
if (!hasExplicitTypeArguments) {
ArgumentsImpl arguments =
new ArgumentsImpl(positional, types: <DartType>[], named: named);
arguments.types.addAll(types);
return arguments;
} else {
return new ArgumentsImpl(positional, types: types, named: named)
..fileOffset = fileOffset ?? TreeNode.noOffset;
}
}
Arguments createArgumentsForExtensionMethod(
int fileOffset,
int extensionTypeParameterCount,
int typeParameterCount,
Expression receiver,
{List<DartType> extensionTypeArguments = const <DartType>[],
int extensionTypeArgumentOffset,
List<DartType> typeArguments = const <DartType>[],
List<Expression> positionalArguments = const <Expression>[],
List<NamedExpression> namedArguments = const <NamedExpression>[]}) {
assert(fileOffset != null);
return new ArgumentsImpl.forExtensionMethod(
extensionTypeParameterCount, typeParameterCount, receiver,
extensionTypeArguments: extensionTypeArguments,
extensionTypeArgumentOffset: extensionTypeArgumentOffset,
typeArguments: typeArguments,
positionalArguments: positionalArguments,
namedArguments: namedArguments)
..fileOffset = fileOffset ?? TreeNode.noOffset;
}
Arguments createArgumentsEmpty(int fileOffset) {
assert(fileOffset != null);
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, types);
}
/// Return a representation of a boolean literal at the given [fileOffset].
/// The literal has the given [value].
BoolLiteral createBoolLiteral(int fileOffset, bool value) {
assert(fileOffset != null);
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) {
assert(fileOffset != null);
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]) {
assert(fileOffset != null);
return new IntJudgment(value, literal)..fileOffset = fileOffset;
}
IntLiteral createIntLiteralLarge(int fileOffset, String literal) {
assert(fileOffset != null);
return new ShadowLargeIntLiteral(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,
{bool isConst}) {
assert(fileOffset != null);
assert(isConst != null);
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,
{bool isConst}) {
assert(fileOffset != null);
assert(isConst != null);
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<MapEntry> entries,
{bool isConst}) {
assert(fileOffset != null);
assert(isConst != null);
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) {
assert(fileOffset != null);
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) {
assert(fileOffset != null);
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) {
assert(fileOffset != null);
return new SymbolLiteral(value)..fileOffset = fileOffset;
}
TypeLiteral createTypeLiteral(int fileOffset, DartType type) {
assert(fileOffset != null);
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.
MapEntry createMapEntry(int fileOffset, Expression key, Expression value) {
assert(fileOffset != null);
return new MapEntry(key, value)..fileOffset = fileOffset;
}
Expression createLoadLibrary(
int fileOffset, LibraryDependency dependency, Arguments arguments) {
assert(fileOffset != null);
return new LoadLibraryImpl(dependency, arguments)..fileOffset = fileOffset;
}
Expression checkLibraryIsLoaded(
int fileOffset, LibraryDependency dependency) {
assert(fileOffset != null);
return new CheckLibraryIsLoaded(dependency)..fileOffset = fileOffset;
}
Expression createAsExpression(
int fileOffset, Expression expression, DartType type,
{bool forNonNullableByDefault}) {
assert(forNonNullableByDefault != null);
assert(fileOffset != null);
return new AsExpression(expression, type)
..fileOffset = fileOffset
..isForNonNullableByDefault = forNonNullableByDefault;
}
Expression createSpreadElement(int fileOffset, Expression expression,
{bool isNullAware}) {
assert(fileOffset != null);
assert(isNullAware != null);
return new SpreadElement(expression, isNullAware)..fileOffset = fileOffset;
}
Expression createIfElement(
int fileOffset, Expression condition, Expression then,
[Expression otherwise]) {
assert(fileOffset != null);
return new IfElement(condition, then, otherwise)..fileOffset = fileOffset;
}
MapEntry createIfMapEntry(int fileOffset, Expression condition, MapEntry then,
[MapEntry otherwise]) {
assert(fileOffset != null);
return new IfMapEntry(condition, then, otherwise)..fileOffset = fileOffset;
}
Expression createForElement(
int fileOffset,
List<VariableDeclaration> variables,
Expression condition,
List<Expression> updates,
Expression body) {
assert(fileOffset != null);
return new ForElement(variables, condition, updates, body)
..fileOffset = fileOffset;
}
MapEntry createForMapEntry(
int fileOffset,
List<VariableDeclaration> variables,
Expression condition,
List<Expression> updates,
MapEntry body) {
assert(fileOffset != null);
return new ForMapEntry(variables, condition, updates, body)
..fileOffset = fileOffset;
}
Expression createForInElement(
int fileOffset,
VariableDeclaration variable,
Expression iterable,
Expression synthesizedAssignment,
Statement expressionEffects,
Expression body,
Expression problem,
{bool isAsync: false}) {
assert(fileOffset != null);
return new ForInElement(variable, iterable, synthesizedAssignment,
expressionEffects, body, problem,
isAsync: isAsync)
..fileOffset = fileOffset;
}
MapEntry createForInMapEntry(
int fileOffset,
VariableDeclaration variable,
Expression iterable,
Expression synthesizedAssignment,
Statement expressionEffects,
MapEntry body,
Expression problem,
{bool isAsync: false}) {
assert(fileOffset != null);
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) {
assert(fileOffset != null);
return new AssertInitializer(assertStatement)..fileOffset = fileOffset;
}
/// Return a representation of an assert that appears as a statement.
Statement createAssertStatement(int fileOffset, Expression condition,
Expression message, int conditionStartOffset, int conditionEndOffset) {
assert(fileOffset != null);
return new AssertStatement(condition,
conditionStartOffset: conditionStartOffset,
conditionEndOffset: conditionEndOffset,
message: message)
..fileOffset = fileOffset;
}
Expression createAwaitExpression(int fileOffset, Expression operand) {
assert(fileOffset != null);
return new AwaitExpression(operand)..fileOffset = fileOffset;
}
/// Return a representation of a block of [statements] at the given
/// [fileOffset].
Statement createBlock(
int fileOffset, int fileEndOffset, List<Statement> statements) {
assert(fileOffset != null);
List<Statement> copy;
for (int i = 0; i < statements.length; i++) {
Statement statement = statements[i];
if (statement is _VariablesDeclaration) {
copy ??= new List<Statement>.from(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) {
assert(fileOffset != null);
// TODO(johnniwinther): Use [label]?
return new BreakStatementImpl(isContinue: false)..fileOffset = fileOffset;
}
/// Return a representation of a catch clause.
Catch createCatch(
int fileOffset,
DartType exceptionType,
VariableDeclaration exceptionParameter,
VariableDeclaration stackTraceParameter,
DartType stackTraceType,
Statement body) {
assert(fileOffset != null);
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.
Expression createConditionalExpression(int fileOffset, Expression condition,
Expression thenExpression, Expression elseExpression) {
return new ConditionalExpression(
condition, thenExpression, elseExpression, null)
..fileOffset = fileOffset;
}
/// Return a representation of a continue statement.
Statement createContinueStatement(int fileOffset, Object label) {
assert(fileOffset != null);
// 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) {
assert(fileOffset != null);
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) {
assert(fileOffset != null);
return new ExpressionStatement(expression)..fileOffset = fileOffset;
}
/// Return a representation of an empty statement at the given [fileOffset].
Statement createEmptyStatement(int fileOffset) {
assert(fileOffset != null);
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) {
assert(fileOffset != null);
return new ForStatement(variables ?? [], condition, updaters, body)
..fileOffset = fileOffset;
}
/// Return a representation of an `if` statement.
Statement createIfStatement(int fileOffset, Expression condition,
Statement thenStatement, Statement elseStatement) {
assert(fileOffset != null);
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,
{bool forNonNullableByDefault, int notFileOffset}) {
assert(forNonNullableByDefault != null);
assert(fileOffset != null);
Expression result = new IsExpression(operand, type)
..fileOffset = fileOffset
..isForNonNullableByDefault = forNonNullableByDefault;
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) {
assert(fileOffset != null);
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) {
assert(fileOffset != null);
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) {
assert(rethrowFileOffset != null);
assert(statementFileOffset != null);
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}) {
assert(fileOffset != null);
return new ReturnStatementImpl(isArrow, expression)
..fileOffset = fileOffset ?? TreeNode.noOffset;
}
Expression createStringConcatenation(
int fileOffset, List<Expression> expressions) {
assert(fileOffset != null);
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.
Statement createLabeledStatement(Statement statement) {
return new LabeledStatement(statement)..fileOffset = statement.fileOffset;
}
Expression createThisExpression(int fileOffset) {
assert(fileOffset != null);
return new ThisExpression()..fileOffset = fileOffset;
}
/// Return a representation of a throw expression at the given [fileOffset].
Expression createThrow(int fileOffset, Expression expression) {
assert(fileOffset != null);
return new Throw(expression)..fileOffset = fileOffset;
}
bool isThrow(Object o) => o is Throw;
Statement createTryStatement(int fileOffset, Statement tryBlock,
List<Catch> catchBlocks, Statement finallyBlock) {
assert(fileOffset != null);
return new TryStatement(tryBlock, catchBlocks ?? <Catch>[], finallyBlock)
..fileOffset = fileOffset;
}
_VariablesDeclaration variablesDeclaration(
List<VariableDeclaration> declarations, Uri uri) {
return new _VariablesDeclaration(declarations, uri);
}
List<VariableDeclaration> variablesDeclarationExtractDeclarations(
_VariablesDeclaration variablesDeclaration) {
return variablesDeclaration.declarations;
}
Statement wrapVariables(Statement statement) {
if (statement is _VariablesDeclaration) {
return new Block(
new List<Statement>.from(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) {
assert(fileOffset != null);
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,
{bool isYieldStar}) {
assert(fileOffset != null);
assert(isYieldStar != null);
return new YieldStatement(expression, isYieldStar: isYieldStar)
..fileOffset = fileOffset;
}
bool isBlock(Object node) => node is Block;
bool isErroneousNode(Object node) {
if (node is ExpressionStatement) {
ExpressionStatement statement = node;
node = statement.expression;
}
if (node is VariableDeclaration) {
VariableDeclaration variable = node;
node = variable.initializer;
}
if (node is Let) {
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, int functionNestingLevel,
{Expression initializer,
DartType type,
bool isFinal: false,
bool isConst: false,
bool isFieldFormal: false,
bool isCovariant: false,
bool isLocalFunction: false}) {
assert(fileOffset != null);
return new VariableDeclarationImpl(name, functionNestingLevel,
type: type,
initializer: initializer,
isFinal: isFinal,
isConst: isConst,
isFieldFormal: isFieldFormal,
isCovariant: isCovariant,
isLocalFunction: isLocalFunction,
hasDeclaredInitializer: initializer != null);
}
VariableDeclaration createVariableDeclarationForValue(Expression initializer,
{DartType type = const DynamicType()}) {
return new VariableDeclarationImpl.forValue(initializer)
..type = type
..fileOffset = initializer.fileOffset;
}
Let createLet(VariableDeclaration variable, Expression body) {
return new Let(variable, body);
}
FunctionNode createFunctionNode(int fileOffset, Statement body,
{List<TypeParameter> typeParameters,
List<VariableDeclaration> positionalParameters,
List<VariableDeclaration> namedParameters,
int requiredParameterCount,
DartType returnType: const DynamicType(),
AsyncMarker asyncMarker: AsyncMarker.Sync,
AsyncMarker dartAsyncMarker}) {
assert(fileOffset != null);
return new FunctionNode(body,
typeParameters: typeParameters,
positionalParameters: positionalParameters,
namedParameters: namedParameters,
requiredParameterCount: requiredParameterCount,
returnType: returnType,
asyncMarker: asyncMarker,
dartAsyncMarker: dartAsyncMarker);
}
TypeParameter createTypeParameter(String name) {
return new TypeParameter(name);
}
TypeParameterType createTypeParameterType(
TypeParameter typeParameter, Nullability nullability) {
return new TypeParameterType(typeParameter, nullability);
}
TypeParameterType createTypeParameterTypeWithDefaultNullabilityForLibrary(
TypeParameter typeParameter, Library library) {
return new TypeParameterType.withDefaultNullabilityForLibrary(
typeParameter, library);
}
FunctionExpression createFunctionExpression(
int fileOffset, FunctionNode function) {
assert(fileOffset != null);
return new FunctionExpression(function)..fileOffset = fileOffset;
}
Expression createExpressionInvocation(
int fileOffset, Expression expression, Arguments arguments) {
assert(fileOffset != null);
return new ExpressionInvocation(expression, arguments)
..fileOffset = fileOffset;
}
MethodInvocation createMethodInvocation(
int fileOffset, Expression expression, Name name, Arguments arguments) {
assert(fileOffset != null);
return new MethodInvocation(expression, name, arguments)
..fileOffset = fileOffset;
}
NamedExpression createNamedExpression(
int fileOffset, String name, Expression expression) {
assert(fileOffset != null);
return new NamedExpression(name, expression)..fileOffset = fileOffset;
}
StaticInvocation createStaticInvocation(
int fileOffset, Procedure procedure, Arguments arguments) {
assert(fileOffset != null);
return new StaticInvocation(procedure, arguments)..fileOffset = fileOffset;
}
SuperMethodInvocation createSuperMethodInvocation(
int fileOffset, Name name, Procedure procedure, Arguments arguments) {
assert(fileOffset != null);
return new SuperMethodInvocation(name, arguments, procedure)
..fileOffset = fileOffset;
}
NullCheck createNullCheck(int fileOffset, Expression expression) {
assert(fileOffset != null);
return new NullCheck(expression)..fileOffset = fileOffset;
}
PropertyGet createPropertyGet(int fileOffset, Expression receiver, Name name,
{Member interfaceTarget}) {
assert(fileOffset != null);
return new PropertyGet(receiver, name, interfaceTarget)
..fileOffset = fileOffset;
}
PropertySet createPropertySet(
int fileOffset, Expression receiver, Name name, Expression value,
{Member interfaceTarget, bool forEffect, bool readOnlyReceiver: false}) {
assert(fileOffset != null);
return new PropertySetImpl(receiver, name, value,
interfaceTarget: interfaceTarget,
forEffect: forEffect,
readOnlyReceiver: readOnlyReceiver)
..fileOffset = fileOffset;
}
IndexGet createIndexGet(
int fileOffset, Expression receiver, Expression index) {
assert(fileOffset != null);
return new IndexGet(receiver, index)..fileOffset = fileOffset;
}
IndexSet createIndexSet(
int fileOffset, Expression receiver, Expression index, Expression value,
{bool forEffect}) {
assert(fileOffset != null);
assert(forEffect != null);
return new IndexSet(receiver, index, value, forEffect: forEffect)
..fileOffset = fileOffset;
}
EqualsExpression createEquals(
int fileOffset, Expression left, Expression right,
{bool isNot}) {
assert(fileOffset != null);
assert(isNot != null);
return new EqualsExpression(left, right, isNot: isNot)
..fileOffset = fileOffset;
}
BinaryExpression createBinary(
int fileOffset, Expression left, Name binaryName, Expression right) {
assert(fileOffset != null);
return new BinaryExpression(left, binaryName, right)
..fileOffset = fileOffset;
}
UnaryExpression createUnary(
int fileOffset, Name unaryName, Expression expression) {
assert(fileOffset != null);
return new UnaryExpression(unaryName, expression)..fileOffset = fileOffset;
}
ParenthesizedExpression createParenthesized(
int fileOffset, Expression expression) {
assert(fileOffset != null);
return new ParenthesizedExpression(expression)..fileOffset = fileOffset;
}
}
class _VariablesDeclaration extends Statement {
final List<VariableDeclaration> declarations;
final Uri uri;
_VariablesDeclaration(this.declarations, this.uri) {
setParents(declarations, this);
}
R accept<R>(v) {
throw unsupported("accept", fileOffset, uri);
}
R accept1<R, A>(v, arg) {
throw unsupported("accept1", fileOffset, uri);
}
visitChildren(v) {
throw unsupported("visitChildren", fileOffset, uri);
}
transformChildren(v) {
throw unsupported("transformChildren", fileOffset, uri);
}
transformOrRemoveChildren(v) {
throw unsupported("transformOrRemoveChildren", fileOffset, uri);
}
@override
String toString() {
return "_VariablesDeclaration(${toStringInternal()})";
}
@override
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(';');
}
}