[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>
This commit is contained in:
Johnni Winther
2021-02-18 16:01:17 +00:00
committed by commit-bot@chromium.org
parent 07ddd00e1b
commit 8467186ca0
40 changed files with 5209 additions and 1931 deletions
+10
View File
@@ -203,11 +203,21 @@ class ConstantReference extends ir.TreeNode {
throw new UnsupportedError("ConstantReference.accept");
}
@override
R accept1<R, A>(ir.TreeVisitor1<R, A> v, A arg) {
throw new UnsupportedError("ConstantReference.accept");
}
@override
transformChildren(ir.Transformer v) {
throw new UnsupportedError("ConstantReference.transformChildren");
}
@override
transformOrRemoveChildren(ir.RemovingTransformer v) {
throw new UnsupportedError("ConstantReference.transformOrRemoveChildren");
}
@override
int get hashCode => 13 * constant.hashCode;
@@ -6,19 +6,7 @@
library fasta.collections;
import 'package:kernel/ast.dart'
show
DartType,
Expression,
ExpressionStatement,
MapEntry,
NullLiteral,
Statement,
TreeNode,
VariableDeclaration,
setParents,
transformList,
visitList;
import 'package:kernel/ast.dart';
import 'package:kernel/src/printer.dart';
@@ -90,14 +78,22 @@ class SpreadElement extends Expression with ControlFlowElement {
}
@override
visitChildren(Visitor<Object> v) {
void visitChildren(Visitor<Object> v) {
expression?.accept(v);
}
@override
transformChildren(Transformer v) {
void transformChildren(Transformer v) {
if (expression != null) {
expression = expression.accept<TreeNode>(v);
expression = v.transform(expression);
expression?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (expression != null) {
expression = v.transformOrRemoveExpression(expression);
expression?.parent = this;
}
}
@@ -136,24 +132,40 @@ class IfElement extends Expression with ControlFlowElement {
}
@override
visitChildren(Visitor<Object> v) {
void visitChildren(Visitor<Object> v) {
condition?.accept(v);
then?.accept(v);
otherwise?.accept(v);
}
@override
transformChildren(Transformer v) {
void transformChildren(Transformer v) {
if (condition != null) {
condition = condition.accept<TreeNode>(v);
condition = v.transform(condition);
condition?.parent = this;
}
if (then != null) {
then = then.accept<TreeNode>(v);
then = v.transform(then);
then?.parent = this;
}
if (otherwise != null) {
otherwise = otherwise.accept<TreeNode>(v);
otherwise = v.transform(otherwise);
otherwise?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (condition != null) {
condition = v.transformOrRemoveExpression(condition);
condition?.parent = this;
}
if (then != null) {
then = v.transformOrRemoveExpression(then);
then?.parent = this;
}
if (otherwise != null) {
otherwise = v.transformOrRemoveExpression(otherwise);
otherwise?.parent = this;
}
}
@@ -211,7 +223,7 @@ class ForElement extends Expression with ControlFlowElement {
}
@override
visitChildren(Visitor<Object> v) {
void visitChildren(Visitor<Object> v) {
visitList(variables, v);
condition?.accept(v);
visitList(updates, v);
@@ -219,15 +231,29 @@ class ForElement extends Expression with ControlFlowElement {
}
@override
transformChildren(Transformer v) {
transformList(variables, v, this);
void transformChildren(Transformer v) {
v.transformList(variables, this);
if (condition != null) {
condition = condition.accept<TreeNode>(v);
condition = v.transform(condition);
condition?.parent = this;
}
transformList(updates, v, this);
v.transformList(updates, this);
if (body != null) {
body = body.accept<TreeNode>(v);
body = v.transform(body);
body?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
v.transformVariableDeclarationList(variables, this);
if (condition != null) {
condition = v.transformOrRemoveExpression(condition);
condition?.parent = this;
}
v.transformExpressionList(updates, this);
if (body != null) {
body = v.transformOrRemoveExpression(body);
body?.parent = this;
}
}
@@ -284,7 +310,7 @@ class ForInElement extends Expression with ControlFlowElement {
..fileOffset = syntheticAssignment.fileOffset)
: expressionEffects;
visitChildren(Visitor<Object> v) {
void visitChildren(Visitor<Object> v) {
variable?.accept(v);
iterable?.accept(v);
syntheticAssignment?.accept(v);
@@ -293,29 +319,57 @@ class ForInElement extends Expression with ControlFlowElement {
problem?.accept(v);
}
transformChildren(Transformer v) {
void transformChildren(Transformer v) {
if (variable != null) {
variable = variable.accept<TreeNode>(v);
variable = v.transform(variable);
variable?.parent = this;
}
if (iterable != null) {
iterable = iterable.accept<TreeNode>(v);
iterable = v.transform(iterable);
iterable?.parent = this;
}
if (syntheticAssignment != null) {
syntheticAssignment = syntheticAssignment.accept<TreeNode>(v);
syntheticAssignment = v.transform(syntheticAssignment);
syntheticAssignment?.parent = this;
}
if (expressionEffects != null) {
expressionEffects = expressionEffects.accept<TreeNode>(v);
expressionEffects = v.transform(expressionEffects);
expressionEffects?.parent = this;
}
if (body != null) {
body = body.accept<TreeNode>(v);
body = v.transform(body);
body?.parent = this;
}
if (problem != null) {
problem = problem.accept<TreeNode>(v);
problem = v.transform(problem);
problem?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (variable != null) {
variable = v.transformOrRemoveVariableDeclaration(variable);
variable?.parent = this;
}
if (iterable != null) {
iterable = v.transformOrRemoveExpression(iterable);
iterable?.parent = this;
}
if (syntheticAssignment != null) {
syntheticAssignment = v.transformOrRemoveExpression(syntheticAssignment);
syntheticAssignment?.parent = this;
}
if (expressionEffects != null) {
expressionEffects = v.transformOrRemoveStatement(expressionEffects);
expressionEffects?.parent = this;
}
if (body != null) {
body = v.transformOrRemoveExpression(body);
body?.parent = this;
}
if (problem != null) {
problem = v.transformOrRemoveExpression(problem);
problem?.parent = this;
}
}
@@ -371,6 +425,9 @@ mixin ControlFlowMapEntry implements MapEntry {
@override
R accept<R>(TreeVisitor<R> v) => v.defaultTreeNode(this);
@override
R accept1<R, A>(TreeVisitor1<R, A> v, A arg) => v.defaultTreeNode(this, arg);
@override
String toStringInternal() => toText(defaultAstTextStrategy);
@@ -398,14 +455,22 @@ class SpreadMapEntry extends TreeNode with ControlFlowMapEntry {
}
@override
visitChildren(Visitor<Object> v) {
void visitChildren(Visitor<Object> v) {
expression?.accept(v);
}
@override
transformChildren(Transformer v) {
void transformChildren(Transformer v) {
if (expression != null) {
expression = expression.accept<TreeNode>(v);
expression = v.transform(expression);
expression?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (expression != null) {
expression = v.transformOrRemoveExpression(expression);
expression?.parent = this;
}
}
@@ -434,24 +499,40 @@ class IfMapEntry extends TreeNode with ControlFlowMapEntry {
}
@override
visitChildren(Visitor<Object> v) {
void visitChildren(Visitor<Object> v) {
condition?.accept(v);
then?.accept(v);
otherwise?.accept(v);
}
@override
transformChildren(Transformer v) {
void transformChildren(Transformer v) {
if (condition != null) {
condition = condition.accept<TreeNode>(v);
condition = v.transform(condition);
condition?.parent = this;
}
if (then != null) {
then = then.accept<TreeNode>(v);
then = v.transform(then);
then?.parent = this;
}
if (otherwise != null) {
otherwise = otherwise.accept<TreeNode>(v);
otherwise = v.transform(otherwise);
otherwise?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (condition != null) {
condition = v.transformOrRemoveExpression(condition);
condition?.parent = this;
}
if (then != null) {
then = v.transformOrRemove(then, dummyMapEntry);
then?.parent = this;
}
if (otherwise != null) {
otherwise = v.transformOrRemove(otherwise, dummyMapEntry);
otherwise?.parent = this;
}
}
@@ -482,7 +563,7 @@ class ForMapEntry extends TreeNode with ControlFlowMapEntry {
}
@override
visitChildren(Visitor<Object> v) {
void visitChildren(Visitor<Object> v) {
visitList(variables, v);
condition?.accept(v);
visitList(updates, v);
@@ -490,15 +571,29 @@ class ForMapEntry extends TreeNode with ControlFlowMapEntry {
}
@override
transformChildren(Transformer v) {
transformList(variables, v, this);
void transformChildren(Transformer v) {
v.transformList(variables, this);
if (condition != null) {
condition = condition.accept<TreeNode>(v);
condition = v.transform(condition);
condition?.parent = this;
}
transformList(updates, v, this);
v.transformList(updates, this);
if (body != null) {
body = body.accept<TreeNode>(v);
body = v.transform(body);
body?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
v.transformVariableDeclarationList(variables, this);
if (condition != null) {
condition = v.transformOrRemoveExpression(condition);
condition?.parent = this;
}
v.transformExpressionList(updates, this);
if (body != null) {
body = v.transformOrRemove(body, dummyMapEntry);
body?.parent = this;
}
}
@@ -541,7 +636,7 @@ class ForInMapEntry extends TreeNode with ControlFlowMapEntry {
..fileOffset = syntheticAssignment.fileOffset)
: expressionEffects;
visitChildren(Visitor<Object> v) {
void visitChildren(Visitor<Object> v) {
variable?.accept(v);
iterable?.accept(v);
syntheticAssignment?.accept(v);
@@ -550,29 +645,57 @@ class ForInMapEntry extends TreeNode with ControlFlowMapEntry {
problem?.accept(v);
}
transformChildren(Transformer v) {
void transformChildren(Transformer v) {
if (variable != null) {
variable = variable.accept<TreeNode>(v);
variable = v.transform(variable);
variable?.parent = this;
}
if (iterable != null) {
iterable = iterable.accept<TreeNode>(v);
iterable = v.transform(iterable);
iterable?.parent = this;
}
if (syntheticAssignment != null) {
syntheticAssignment = syntheticAssignment.accept<TreeNode>(v);
syntheticAssignment = v.transform(syntheticAssignment);
syntheticAssignment?.parent = this;
}
if (expressionEffects != null) {
expressionEffects = expressionEffects.accept<TreeNode>(v);
expressionEffects = v.transform(expressionEffects);
expressionEffects?.parent = this;
}
if (body != null) {
body = body.accept<TreeNode>(v);
body = v.transform(body);
body?.parent = this;
}
if (problem != null) {
problem = problem.accept<TreeNode>(v);
problem = v.transform(problem);
problem?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (variable != null) {
variable = v.transformOrRemoveVariableDeclaration(variable);
variable?.parent = this;
}
if (iterable != null) {
iterable = v.transformOrRemoveExpression(iterable);
iterable?.parent = this;
}
if (syntheticAssignment != null) {
syntheticAssignment = v.transformOrRemoveExpression(syntheticAssignment);
syntheticAssignment?.parent = this;
}
if (expressionEffects != null) {
expressionEffects = v.transformOrRemoveStatement(expressionEffects);
expressionEffects?.parent = this;
}
if (body != null) {
body = v.transformOrRemove(body, dummyMapEntry);
body?.parent = this;
}
if (problem != null) {
problem = v.transformOrRemoveExpression(problem);
problem?.parent = this;
}
}
@@ -155,7 +155,7 @@ void transformProcedure(
typeEnvironment,
errorReporter,
evaluationMode);
constantsTransformer.visitProcedure(procedure);
constantsTransformer.visitProcedure(procedure, null);
}
enum EvaluationMode {
@@ -327,7 +327,7 @@ class ConstantWeakener extends ComputeOnceConstantVisitor<Constant> {
Constant visitUnevaluatedConstant(UnevaluatedConstant node) => null;
}
class ConstantsTransformer extends Transformer {
class ConstantsTransformer extends RemovingTransformer {
final ConstantsBackend backend;
final ConstantEvaluator constantEvaluator;
final TypeEnvironment typeEnvironment;
@@ -367,12 +367,12 @@ class ConstantsTransformer extends Transformer {
transformAnnotations(library.annotations, library);
transformList(library.dependencies, this, library);
transformList(library.parts, this, library);
transformList(library.typedefs, this, library);
transformList(library.classes, this, library);
transformList(library.procedures, this, library);
transformList(library.fields, this, library);
transformLibraryDependencyList(library.dependencies, library);
transformLibraryPartList(library.parts, library);
transformTypedefList(library.typedefs, library);
transformClassList(library.classes, library);
transformProcedureList(library.procedures, library);
transformFieldList(library.fields, library);
if (!keepFields) {
// The transformer API does not iterate over `Library.additionalExports`,
@@ -385,7 +385,7 @@ class ConstantsTransformer extends Transformer {
}
@override
LibraryPart visitLibraryPart(LibraryPart node) {
LibraryPart visitLibraryPart(LibraryPart node, TreeNode removalSentinel) {
constantEvaluator.withNewEnvironment(() {
transformAnnotations(node.annotations, node);
});
@@ -393,7 +393,8 @@ class ConstantsTransformer extends Transformer {
}
@override
LibraryDependency visitLibraryDependency(LibraryDependency node) {
LibraryDependency visitLibraryDependency(
LibraryDependency node, TreeNode removalSentinel) {
constantEvaluator.withNewEnvironment(() {
transformAnnotations(node.annotations, node);
});
@@ -401,78 +402,80 @@ class ConstantsTransformer extends Transformer {
}
@override
Class visitClass(Class node) {
Class visitClass(Class node, TreeNode removalSentinel) {
StaticTypeContext oldStaticTypeContext = _staticTypeContext;
_staticTypeContext = new StaticTypeContext.forAnnotations(
node.enclosingLibrary, typeEnvironment);
constantEvaluator.withNewEnvironment(() {
transformAnnotations(node.annotations, node);
transformList(node.fields, this, node);
transformList(node.typeParameters, this, node);
transformList(node.constructors, this, node);
transformList(node.procedures, this, node);
transformList(node.redirectingFactoryConstructors, this, node);
transformFieldList(node.fields, node);
transformTypeParameterList(node.typeParameters, node);
transformConstructorList(node.constructors, node);
transformProcedureList(node.procedures, node);
transformRedirectingFactoryConstructorList(
node.redirectingFactoryConstructors, node);
});
_staticTypeContext = oldStaticTypeContext;
return node;
}
@override
Procedure visitProcedure(Procedure node) {
Procedure visitProcedure(Procedure node, TreeNode removalSentinel) {
StaticTypeContext oldStaticTypeContext = _staticTypeContext;
_staticTypeContext = new StaticTypeContext(node, typeEnvironment);
constantEvaluator.withNewEnvironment(() {
transformAnnotations(node.annotations, node);
node.function = node.function.accept<TreeNode>(this)..parent = node;
node.function = transform(node.function)..parent = node;
});
_staticTypeContext = oldStaticTypeContext;
return node;
}
@override
Constructor visitConstructor(Constructor node) {
Constructor visitConstructor(Constructor node, TreeNode removalSentinel) {
StaticTypeContext oldStaticTypeContext = _staticTypeContext;
_staticTypeContext = new StaticTypeContext(node, typeEnvironment);
constantEvaluator.withNewEnvironment(() {
transformAnnotations(node.annotations, node);
transformList(node.initializers, this, node);
node.function = node.function.accept<TreeNode>(this)..parent = node;
transformInitializerList(node.initializers, node);
node.function = transform(node.function)..parent = node;
});
_staticTypeContext = oldStaticTypeContext;
return node;
}
@override
Typedef visitTypedef(Typedef node) {
Typedef visitTypedef(Typedef node, TreeNode removalSentinel) {
constantEvaluator.withNewEnvironment(() {
transformAnnotations(node.annotations, node);
transformList(node.typeParameters, this, node);
transformList(node.typeParametersOfFunctionType, this, node);
transformList(node.positionalParameters, this, node);
transformList(node.namedParameters, this, node);
transformTypeParameterList(node.typeParameters, node);
transformTypeParameterList(node.typeParametersOfFunctionType, node);
transformVariableDeclarationList(node.positionalParameters, node);
transformVariableDeclarationList(node.namedParameters, node);
});
return node;
}
@override
RedirectingFactoryConstructor visitRedirectingFactoryConstructor(
RedirectingFactoryConstructor node) {
RedirectingFactoryConstructor node, TreeNode removalSentinel) {
// Currently unreachable as the compiler doesn't produce
// RedirectingFactoryConstructor.
StaticTypeContext oldStaticTypeContext = _staticTypeContext;
_staticTypeContext = new StaticTypeContext(node, typeEnvironment);
constantEvaluator.withNewEnvironment(() {
transformAnnotations(node.annotations, node);
transformList(node.typeParameters, this, node);
transformList(node.positionalParameters, this, node);
transformList(node.namedParameters, this, node);
transformTypeParameterList(node.typeParameters, node);
transformVariableDeclarationList(node.positionalParameters, node);
transformVariableDeclarationList(node.namedParameters, node);
});
_staticTypeContext = oldStaticTypeContext;
return node;
}
@override
TypeParameter visitTypeParameter(TypeParameter node) {
TypeParameter visitTypeParameter(
TypeParameter node, TreeNode removalSentinel) {
transformAnnotations(node.annotations, node);
return node;
}
@@ -495,8 +498,8 @@ class ConstantsTransformer extends Transformer {
// Handle definition of constants:
@override
FunctionNode visitFunctionNode(FunctionNode node) {
transformList(node.typeParameters, this, node);
FunctionNode visitFunctionNode(FunctionNode node, TreeNode removalSentinel) {
transformTypeParameterList(node.typeParameters, node);
final int positionalParameterCount = node.positionalParameters.length;
for (int i = 0; i < positionalParameterCount; ++i) {
final VariableDeclaration variable = node.positionalParameters[i];
@@ -516,13 +519,14 @@ class ConstantsTransformer extends Transformer {
}
}
if (node.body != null) {
node.body = node.body.accept<TreeNode>(this)..parent = node;
node.body = transform(node.body)..parent = node;
}
return node;
}
@override
VariableDeclaration visitVariableDeclaration(VariableDeclaration node) {
Statement visitVariableDeclaration(
VariableDeclaration node, TreeNode removalSentinel) {
transformAnnotations(node.annotations, node);
if (node.initializer != null) {
@@ -538,19 +542,18 @@ class ConstantsTransformer extends Transformer {
// If the constant is unevaluated we need to keep the expression,
// so that, in the case the constant contains error but the local
// is unused, the error will still be reported.
return null;
return removalSentinel /*!*/ ?? node;
}
}
} else {
node.initializer = node.initializer.accept<TreeNode>(this)
..parent = node;
node.initializer = transform(node.initializer)..parent = node;
}
}
return node;
}
@override
Field visitField(Field node) {
Field visitField(Field node, TreeNode removalSentinel) {
StaticTypeContext oldStaticTypeContext = _staticTypeContext;
_staticTypeContext = new StaticTypeContext(node, typeEnvironment);
Field field = constantEvaluator.withNewEnvironment(() {
@@ -562,13 +565,12 @@ class ConstantsTransformer extends Transformer {
// If this constant is inlined, remove it.
if (!keepFields && shouldInline(node.initializer)) {
return null;
return removalSentinel;
}
} else {
transformAnnotations(node.annotations, node);
if (node.initializer != null) {
node.initializer = node.initializer.accept<TreeNode>(this)
..parent = node;
node.initializer = transform(node.initializer)..parent = node;
}
}
return node;
@@ -580,7 +582,7 @@ class ConstantsTransformer extends Transformer {
// Handle use-sites of constants (and "inline" constant expressions):
@override
Expression visitSymbolLiteral(SymbolLiteral node) {
Expression visitSymbolLiteral(SymbolLiteral node, TreeNode removalSentinel) {
return makeConstantExpression(
constantEvaluator.evaluate(_staticTypeContext, node), node);
}
@@ -591,9 +593,9 @@ class ConstantsTransformer extends Transformer {
}
@override
Expression visitEqualsCall(EqualsCall node) {
Expression left = node.left.accept<TreeNode>(this);
Expression right = node.right.accept<TreeNode>(this);
Expression visitEqualsCall(EqualsCall node, TreeNode removalSentinel) {
Expression left = transform(node.left);
Expression right = transform(node.right);
if (_isNull(left)) {
return new EqualsNull(right, isNot: node.isNot)
..fileOffset = node.fileOffset;
@@ -607,7 +609,7 @@ class ConstantsTransformer extends Transformer {
}
@override
Expression visitStaticGet(StaticGet node) {
Expression visitStaticGet(StaticGet node, TreeNode removalSentinel) {
final Member target = node.target;
if (target is Field && target.isConst) {
// Make sure the initializer is evaluated first.
@@ -623,27 +625,28 @@ class ConstantsTransformer extends Transformer {
} else if (target is Procedure && target.kind == ProcedureKind.Method) {
return evaluateAndTransformWithContext(node, node);
}
return super.visitStaticGet(node);
return super.visitStaticGet(node, removalSentinel);
}
@override
Expression visitStaticTearOff(StaticTearOff node) {
Expression visitStaticTearOff(StaticTearOff node, TreeNode removalSentinel) {
final Member target = node.target;
if (target is Procedure && target.kind == ProcedureKind.Method) {
return evaluateAndTransformWithContext(node, node);
}
return super.visitStaticTearOff(node);
return super.visitStaticTearOff(node, removalSentinel);
}
@override
SwitchCase visitSwitchCase(SwitchCase node) {
SwitchCase visitSwitchCase(SwitchCase node, TreeNode removalSentinel) {
transformExpressions(node.expressions, node);
return super.visitSwitchCase(node);
return super.visitSwitchCase(node, removalSentinel);
}
@override
SwitchStatement visitSwitchStatement(SwitchStatement node) {
SwitchStatement result = super.visitSwitchStatement(node);
SwitchStatement visitSwitchStatement(
SwitchStatement node, TreeNode removalSentinel) {
SwitchStatement result = super.visitSwitchStatement(node, removalSentinel);
Library library = constantEvaluator.libraryOf(node);
if (library != null && library.isNonNullableByDefault) {
for (SwitchCase switchCase in node.cases) {
@@ -670,7 +673,7 @@ class ConstantsTransformer extends Transformer {
}
@override
Expression visitVariableGet(VariableGet node) {
Expression visitVariableGet(VariableGet node, TreeNode removalSentinel) {
final VariableDeclaration variable = node.variable;
if (variable.isConst) {
variable.initializer =
@@ -680,74 +683,80 @@ class ConstantsTransformer extends Transformer {
return evaluateAndTransformWithContext(node, node);
}
}
return super.visitVariableGet(node);
return super.visitVariableGet(node, removalSentinel);
}
@override
Expression visitListLiteral(ListLiteral node) {
Expression visitListLiteral(ListLiteral node, TreeNode removalSentinel) {
if (node.isConst) {
return evaluateAndTransformWithContext(node, node);
}
return super.visitListLiteral(node);
return super.visitListLiteral(node, removalSentinel);
}
@override
Expression visitListConcatenation(ListConcatenation node) {
Expression visitListConcatenation(
ListConcatenation node, TreeNode removalSentinel) {
return evaluateAndTransformWithContext(node, node);
}
@override
Expression visitSetLiteral(SetLiteral node) {
Expression visitSetLiteral(SetLiteral node, TreeNode removalSentinel) {
if (node.isConst) {
return evaluateAndTransformWithContext(node, node);
}
return super.visitSetLiteral(node);
return super.visitSetLiteral(node, removalSentinel);
}
@override
Expression visitSetConcatenation(SetConcatenation node) {
Expression visitSetConcatenation(
SetConcatenation node, TreeNode removalSentinel) {
return evaluateAndTransformWithContext(node, node);
}
@override
Expression visitMapLiteral(MapLiteral node) {
Expression visitMapLiteral(MapLiteral node, TreeNode removalSentinel) {
if (node.isConst) {
return evaluateAndTransformWithContext(node, node);
}
return super.visitMapLiteral(node);
return super.visitMapLiteral(node, removalSentinel);
}
@override
Expression visitTypeLiteral(TypeLiteral node) {
Expression visitTypeLiteral(TypeLiteral node, TreeNode removalSentinel) {
if (!containsFreeTypeVariables(node.type)) {
return evaluateAndTransformWithContext(node, node);
}
return super.visitTypeLiteral(node);
return super.visitTypeLiteral(node, removalSentinel);
}
@override
Expression visitMapConcatenation(MapConcatenation node) {
Expression visitMapConcatenation(
MapConcatenation node, TreeNode removalSentinel) {
return evaluateAndTransformWithContext(node, node);
}
@override
Expression visitConstructorInvocation(ConstructorInvocation node) {
Expression visitConstructorInvocation(
ConstructorInvocation node, TreeNode removalSentinel) {
if (node.isConst) {
return evaluateAndTransformWithContext(node, node);
}
return super.visitConstructorInvocation(node);
return super.visitConstructorInvocation(node, removalSentinel);
}
@override
Expression visitStaticInvocation(StaticInvocation node) {
Expression visitStaticInvocation(
StaticInvocation node, TreeNode removalSentinel) {
if (node.isConst) {
return evaluateAndTransformWithContext(node, node);
}
return super.visitStaticInvocation(node);
return super.visitStaticInvocation(node, removalSentinel);
}
@override
Expression visitConstantExpression(ConstantExpression node) {
Expression visitConstantExpression(
ConstantExpression node, TreeNode removalSentinel) {
Constant constant = node.constant;
if (constant is UnevaluatedConstant) {
Expression expression = constant.expression;
@@ -775,6 +775,10 @@ class _VariablesDeclaration extends Statement {
throw unsupported("transformChildren", fileOffset, uri);
}
transformOrRemoveChildren(v) {
throw unsupported("transformOrRemoveChildren", fileOffset, uri);
}
@override
String toString() {
return "_VariablesDeclaration(${toStringInternal()})";
@@ -260,23 +260,47 @@ class ForInStatementWithSynthesizedVariable extends InternalStatement {
@override
void transformChildren(Transformer v) {
if (variable != null) {
variable = variable.accept<TreeNode>(v);
variable = v.transform(variable);
variable?.parent = this;
}
if (iterable != null) {
iterable = iterable.accept<TreeNode>(v);
iterable = v.transform(iterable);
iterable?.parent = this;
}
if (syntheticAssignment != null) {
syntheticAssignment = syntheticAssignment.accept<TreeNode>(v);
syntheticAssignment = v.transform(syntheticAssignment);
syntheticAssignment?.parent = this;
}
if (expressionEffects != null) {
expressionEffects = expressionEffects.accept<TreeNode>(v);
expressionEffects = v.transform(expressionEffects);
expressionEffects?.parent = this;
}
if (body != null) {
body = body.accept<TreeNode>(v);
body = v.transform(body);
body?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (variable != null) {
variable = v.transform(variable);
variable?.parent = this;
}
if (iterable != null) {
iterable = v.transform(iterable);
iterable?.parent = this;
}
if (syntheticAssignment != null) {
syntheticAssignment = v.transform(syntheticAssignment);
syntheticAssignment?.parent = this;
}
if (expressionEffects != null) {
expressionEffects = v.transform(expressionEffects);
expressionEffects?.parent = this;
}
if (body != null) {
body = v.transform(body);
body?.parent = this;
}
}
@@ -318,12 +342,25 @@ class TryStatement extends InternalStatement {
@override
void transformChildren(Transformer v) {
if (tryBlock != null) {
tryBlock = tryBlock.accept<TreeNode>(v);
tryBlock = v.transform(tryBlock);
tryBlock?.parent = this;
}
transformList(catchBlocks, v, this);
v.transformList(catchBlocks, this);
if (finallyBlock != null) {
finallyBlock = finallyBlock.accept<TreeNode>(v);
finallyBlock = v.transform(finallyBlock);
finallyBlock?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (tryBlock != null) {
tryBlock = v.transformOrRemoveStatement(tryBlock);
tryBlock?.parent = this;
}
v.transformCatchList(catchBlocks, this);
if (finallyBlock != null) {
finallyBlock = v.transformOrRemoveStatement(finallyBlock);
finallyBlock?.parent = this;
}
}
@@ -584,10 +621,19 @@ class Cascade extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (variable != null) {
variable = variable.accept<TreeNode>(v);
variable = v.transform(variable);
variable?.parent = this;
}
transformList(expressions, v, this);
v.transformList(expressions, this);
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (variable != null) {
variable = v.transformOrRemoveVariableDeclaration(variable);
variable?.parent = this;
}
v.transformExpressionList(expressions, this);
}
@override
@@ -644,11 +690,23 @@ class DeferredCheck extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (variable != null) {
variable = variable.accept<TreeNode>(v);
variable = v.transform(variable);
variable?.parent = this;
}
if (expression != null) {
expression = expression.accept<TreeNode>(v);
expression = v.transform(expression);
expression?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (variable != null) {
variable = v.transformOrRemoveVariableDeclaration(variable);
variable?.parent = this;
}
if (expression != null) {
expression = v.transformOrRemoveExpression(expression);
expression?.parent = this;
}
}
@@ -847,11 +905,23 @@ class IfNullExpression extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (left != null) {
left = left.accept<TreeNode>(v);
left = v.transform(left);
left?.parent = this;
}
if (right != null) {
right = right.accept<TreeNode>(v);
right = v.transform(right);
right?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (left != null) {
left = v.transformOrRemoveExpression(left);
left?.parent = this;
}
if (right != null) {
right = v.transformOrRemoveExpression(right);
right?.parent = this;
}
}
@@ -1038,11 +1108,23 @@ class ExpressionInvocation extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (expression != null) {
expression = expression.accept<TreeNode>(v);
expression = v.transform(expression);
expression?.parent = this;
}
if (arguments != null) {
arguments = arguments.accept<TreeNode>(v);
arguments = v.transform(arguments);
arguments?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (expression != null) {
expression = v.transformOrRemoveExpression(expression);
expression?.parent = this;
}
if (arguments != null) {
arguments = v.transformOrRemove(arguments, dummyArguments);
arguments?.parent = this;
}
}
@@ -1120,13 +1202,25 @@ class NullAwareMethodInvocation extends InternalExpression {
}
@override
transformChildren(Transformer v) {
void transformChildren(Transformer v) {
if (variable != null) {
variable = variable.accept<TreeNode>(v);
variable = v.transform(variable);
variable?.parent = this;
}
if (invocation != null) {
invocation = invocation.accept<TreeNode>(v);
invocation = v.transform(invocation);
invocation?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (variable != null) {
variable = v.transformOrRemoveVariableDeclaration(variable);
variable?.parent = this;
}
if (invocation != null) {
invocation = v.transformOrRemoveExpression(invocation);
invocation?.parent = this;
}
}
@@ -1193,13 +1287,25 @@ class NullAwarePropertyGet extends InternalExpression {
}
@override
transformChildren(Transformer v) {
void transformChildren(Transformer v) {
if (variable != null) {
variable = variable.accept<TreeNode>(v);
variable = v.transform(variable);
variable?.parent = this;
}
if (read != null) {
read = read.accept<TreeNode>(v);
read = v.transform(read);
read?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (variable != null) {
variable = v.transform(variable);
variable?.parent = this;
}
if (read != null) {
read = v.transform(read);
read?.parent = this;
}
}
@@ -1265,13 +1371,25 @@ class NullAwarePropertySet extends InternalExpression {
}
@override
transformChildren(Transformer v) {
void transformChildren(Transformer v) {
if (variable != null) {
variable = variable.accept<TreeNode>(v);
variable = v.transform(variable);
variable?.parent = this;
}
if (write != null) {
write = write.accept<TreeNode>(v);
write = v.transform(write);
write?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (variable != null) {
variable = v.transformOrRemoveVariableDeclaration(variable);
variable?.parent = this;
}
if (write != null) {
write = v.transformOrRemoveExpression(write);
write?.parent = this;
}
}
@@ -1508,6 +1626,11 @@ class VariableDeclarationImpl extends VariableDeclaration {
isLate: isLate || lateGetter != null, type: lateType ?? type);
printer.write(';');
}
@override
String toString() {
return "VariableDeclarationImpl(${toStringInternal()})";
}
}
/// Front end specific implementation of [VariableGet].
@@ -1568,19 +1691,14 @@ class LoadLibraryTearOff extends InternalExpression {
@override
void visitChildren(Visitor<dynamic> v) {
import?.accept(v);
target?.accept(v);
v.visitProcedureReference(target);
}
@override
void transformChildren(Transformer v) {
if (import != null) {
import = import.accept<TreeNode>(v);
}
if (target != null) {
target = target.accept<TreeNode>(v);
}
}
void transformChildren(Transformer v) {}
@override
void transformOrRemoveChildren(RemovingTransformer v) {}
@override
String toString() {
@@ -1649,11 +1767,23 @@ class IfNullPropertySet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (rhs != null) {
rhs = rhs.accept<TreeNode>(v);
rhs = v.transform(rhs);
rhs?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transformOrRemoveExpression(receiver);
receiver?.parent = this;
}
if (rhs != null) {
rhs = v.transformOrRemoveExpression(rhs);
rhs?.parent = this;
}
}
@@ -1718,11 +1848,23 @@ class IfNullSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (read != null) {
read = read.accept<TreeNode>(v);
read = v.transform(read);
read?.parent = this;
}
if (write != null) {
write = write.accept<TreeNode>(v);
write = v.transform(write);
write?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (read != null) {
read = v.transformOrRemoveExpression(read);
read?.parent = this;
}
if (write != null) {
write = v.transformOrRemoveExpression(write);
write?.parent = this;
}
}
@@ -1841,11 +1983,23 @@ class CompoundExtensionSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (rhs != null) {
rhs = rhs.accept<TreeNode>(v);
rhs = v.transform(rhs);
rhs?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transformOrRemoveExpression(receiver);
receiver?.parent = this;
}
if (rhs != null) {
rhs = v.transformOrRemoveExpression(rhs);
rhs?.parent = this;
}
}
@@ -1921,11 +2075,23 @@ class CompoundPropertySet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (rhs != null) {
rhs = rhs.accept<TreeNode>(v);
rhs = v.transform(rhs);
rhs?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transformOrRemoveExpression(receiver);
receiver?.parent = this;
}
if (rhs != null) {
rhs = v.transformOrRemoveExpression(rhs);
rhs?.parent = this;
}
}
@@ -1997,11 +2163,23 @@ class PropertyPostIncDec extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (variable != null) {
variable = variable.accept<TreeNode>(v);
variable = v.transform(variable);
variable?.parent = this;
}
if (write != null) {
write = write.accept<TreeNode>(v);
write = v.transform(write);
write?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (variable != null) {
variable = v.transformOrRemoveVariableDeclaration(variable);
variable?.parent = this;
}
if (write != null) {
write = v.transformOrRemoveVariableDeclaration(write);
write?.parent = this;
}
}
@@ -2050,11 +2228,23 @@ class LocalPostIncDec extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (read != null) {
read = read.accept<TreeNode>(v);
read = v.transform(read);
read?.parent = this;
}
if (write != null) {
write = write.accept<TreeNode>(v);
write = v.transform(write);
write?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (read != null) {
read = v.transformOrRemoveVariableDeclaration(read);
read?.parent = this;
}
if (write != null) {
write = v.transformOrRemoveVariableDeclaration(write);
write?.parent = this;
}
}
@@ -2103,11 +2293,23 @@ class StaticPostIncDec extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (read != null) {
read = read.accept<TreeNode>(v);
read = v.transform(read);
read?.parent = this;
}
if (write != null) {
write = write.accept<TreeNode>(v);
write = v.transform(write);
write?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (read != null) {
read = v.transform(read);
read?.parent = this;
}
if (write != null) {
write = v.transform(write);
write?.parent = this;
}
}
@@ -2156,11 +2358,23 @@ class SuperPostIncDec extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (read != null) {
read = read.accept<TreeNode>(v);
read = v.transform(read);
read?.parent = this;
}
if (write != null) {
write = write.accept<TreeNode>(v);
write = v.transform(write);
write?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (read != null) {
read = v.transformOrRemoveVariableDeclaration(read);
read?.parent = this;
}
if (write != null) {
write = v.transformOrRemoveVariableDeclaration(write);
write?.parent = this;
}
}
@@ -2202,11 +2416,23 @@ class IndexGet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (index != null) {
index = index.accept<TreeNode>(v);
index = v.transform(index);
index?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transformOrRemoveExpression(receiver);
receiver?.parent = this;
}
if (index != null) {
index = v.transformOrRemoveExpression(index);
index?.parent = this;
}
}
@@ -2268,15 +2494,31 @@ class IndexSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (index != null) {
index = index.accept<TreeNode>(v);
index = v.transform(index);
index?.parent = this;
}
if (value != null) {
value = value.accept<TreeNode>(v);
value = v.transform(value);
value?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transformOrRemoveExpression(receiver);
receiver?.parent = this;
}
if (index != null) {
index = v.transformOrRemoveExpression(index);
index?.parent = this;
}
if (value != null) {
value = v.transformOrRemoveExpression(value);
value?.parent = this;
}
}
@@ -2333,11 +2575,23 @@ class SuperIndexSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (index != null) {
index = index.accept<TreeNode>(v);
index = v.transform(index);
index?.parent = this;
}
if (value != null) {
value = value.accept<TreeNode>(v);
value = v.transform(value);
value?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (index != null) {
index = v.transformOrRemoveExpression(index);
index?.parent = this;
}
if (value != null) {
value = v.transformOrRemoveExpression(value);
value?.parent = this;
}
}
@@ -2414,15 +2668,31 @@ class ExtensionIndexSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (index != null) {
index = index.accept<TreeNode>(v);
index = v.transform(index);
index?.parent = this;
}
if (value != null) {
value = value.accept<TreeNode>(v);
value = v.transform(value);
value?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transformOrRemoveExpression(receiver);
receiver?.parent = this;
}
if (index != null) {
index = v.transformOrRemoveExpression(index);
index?.parent = this;
}
if (value != null) {
value = v.transformOrRemoveExpression(value);
value?.parent = this;
}
}
@@ -2522,15 +2792,31 @@ class IfNullIndexSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (index != null) {
index = index.accept<TreeNode>(v);
index = v.transform(index);
index?.parent = this;
}
if (value != null) {
value = value.accept<TreeNode>(v);
value = v.transform(value);
value?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transformOrRemoveExpression(receiver);
receiver?.parent = this;
}
if (index != null) {
index = v.transformOrRemoveExpression(index);
index?.parent = this;
}
if (value != null) {
value = v.transformOrRemoveExpression(value);
value?.parent = this;
}
}
@@ -2613,11 +2899,23 @@ class IfNullSuperIndexSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (index != null) {
index = index.accept<TreeNode>(v);
index = v.transform(index);
index?.parent = this;
}
if (value != null) {
value = value.accept<TreeNode>(v);
value = v.transform(value);
value?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (index != null) {
index = v.transformOrRemoveExpression(index);
index?.parent = this;
}
if (value != null) {
value = v.transformOrRemoveExpression(value);
value?.parent = this;
}
}
@@ -2713,15 +3011,31 @@ class IfNullExtensionIndexSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (index != null) {
index = index.accept<TreeNode>(v);
index = v.transform(index);
index?.parent = this;
}
if (value != null) {
value = value.accept<TreeNode>(v);
value = v.transform(value);
value?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transformOrRemoveExpression(receiver);
receiver?.parent = this;
}
if (index != null) {
index = v.transformOrRemoveExpression(index);
index?.parent = this;
}
if (value != null) {
value = v.transformOrRemoveExpression(value);
value?.parent = this;
}
}
@@ -2806,15 +3120,31 @@ class CompoundIndexSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (index != null) {
index = index.accept<TreeNode>(v);
index = v.transform(index);
index?.parent = this;
}
if (rhs != null) {
rhs = rhs.accept<TreeNode>(v);
rhs = v.transform(rhs);
rhs?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transformOrRemoveExpression(receiver);
receiver?.parent = this;
}
if (index != null) {
index = v.transformOrRemoveExpression(index);
index?.parent = this;
}
if (rhs != null) {
rhs = v.transformOrRemoveExpression(rhs);
rhs?.parent = this;
}
}
@@ -2945,11 +3275,23 @@ class NullAwareCompoundSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (rhs != null) {
rhs = rhs.accept<TreeNode>(v);
rhs = v.transform(rhs);
rhs?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transformOrRemoveExpression(receiver);
receiver?.parent = this;
}
if (rhs != null) {
rhs = v.transformOrRemoveExpression(rhs);
rhs?.parent = this;
}
}
@@ -3054,11 +3396,23 @@ class NullAwareIfNullSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (value != null) {
value = value.accept<TreeNode>(v);
value = v.transform(value);
value?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transformOrRemoveExpression(receiver);
receiver?.parent = this;
}
if (value != null) {
value = v.transformOrRemoveExpression(value);
value?.parent = this;
}
}
@@ -3154,11 +3508,23 @@ class CompoundSuperIndexSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (index != null) {
index = index.accept<TreeNode>(v);
index = v.transform(index);
index?.parent = this;
}
if (rhs != null) {
rhs = rhs.accept<TreeNode>(v);
rhs = v.transform(rhs);
rhs?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (index != null) {
index = v.transformOrRemoveExpression(index);
index?.parent = this;
}
if (rhs != null) {
rhs = v.transformOrRemoveExpression(rhs);
rhs?.parent = this;
}
}
@@ -3272,15 +3638,31 @@ class CompoundExtensionIndexSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (index != null) {
index = index.accept<TreeNode>(v);
index = v.transform(index);
index?.parent = this;
}
if (rhs != null) {
rhs = rhs.accept<TreeNode>(v);
rhs = v.transform(rhs);
rhs?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transformOrRemoveExpression(receiver);
receiver?.parent = this;
}
if (index != null) {
index = v.transformOrRemoveExpression(index);
index?.parent = this;
}
if (rhs != null) {
rhs = v.transformOrRemoveExpression(rhs);
rhs?.parent = this;
}
}
@@ -3358,11 +3740,23 @@ class ExtensionSet extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (receiver != null) {
receiver = receiver.accept<TreeNode>(v);
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (value != null) {
value = value.accept<TreeNode>(v);
value = v.transform(value);
value?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (receiver != null) {
receiver = v.transform(receiver);
receiver?.parent = this;
}
if (value != null) {
value = v.transform(value);
value?.parent = this;
}
}
@@ -3409,11 +3803,23 @@ class NullAwareExtension extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (variable != null) {
variable = variable.accept<TreeNode>(v);
variable = v.transform(variable);
variable?.parent = this;
}
if (expression != null) {
expression = expression.accept<TreeNode>(v);
expression = v.transform(expression);
expression?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (variable != null) {
variable = v.transformOrRemoveVariableDeclaration(variable);
variable?.parent = this;
}
if (expression != null) {
expression = v.transformOrRemoveExpression(expression);
expression?.parent = this;
}
}
@@ -3484,7 +3890,15 @@ class ExtensionTearOff extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (arguments != null) {
arguments = arguments.accept<TreeNode>(v);
arguments = v.transform(arguments);
arguments?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (arguments != null) {
arguments = v.transformOrRemove(arguments, dummyArguments);
arguments?.parent = this;
}
}
@@ -3525,11 +3939,23 @@ class EqualsExpression extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (left != null) {
left = left.accept<TreeNode>(v);
left = v.transform(left);
left?.parent = this;
}
if (right != null) {
right = right.accept<TreeNode>(v);
right = v.transform(right);
right?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (left != null) {
left = v.transformOrRemoveExpression(left);
left?.parent = this;
}
if (right != null) {
right = v.transformOrRemoveExpression(right);
right?.parent = this;
}
}
@@ -3580,11 +4006,23 @@ class BinaryExpression extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (left != null) {
left = left.accept<TreeNode>(v);
left = v.transform(left);
left?.parent = this;
}
if (right != null) {
right = right.accept<TreeNode>(v);
right = v.transform(right);
right?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (left != null) {
left = v.transformOrRemoveExpression(left);
left?.parent = this;
}
if (right != null) {
right = v.transformOrRemoveExpression(right);
right?.parent = this;
}
}
@@ -3631,7 +4069,15 @@ class UnaryExpression extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (expression != null) {
expression = expression.accept<TreeNode>(v);
expression = v.transform(expression);
expression?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (expression != null) {
expression = v.transformOrRemoveExpression(expression);
expression?.parent = this;
}
}
@@ -3680,7 +4126,15 @@ class ParenthesizedExpression extends InternalExpression {
@override
void transformChildren(Transformer v) {
if (expression != null) {
expression = expression.accept<TreeNode>(v);
expression = v.transform(expression);
expression?.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
if (expression != null) {
expression = v.transformOrRemoveExpression(expression);
expression?.parent = this;
}
}
@@ -279,8 +279,8 @@ class CollectionTransformer extends Transformer {
element.condition?.accept<TreeNode>(this),
element.updates,
loopBody);
transformList(loop.variables, this, loop);
transformList(loop.updates, this, loop);
transformList(loop.variables, loop);
transformList(loop.updates, loop);
_dataForTesting?.registerAlias(element, loop);
body.add(loop);
}
@@ -531,8 +531,8 @@ class CollectionTransformer extends Transformer {
ForStatement loop = _createForStatement(entry.fileOffset, entry.variables,
entry.condition?.accept<TreeNode>(this), entry.updates, loopBody);
_dataForTesting?.registerAlias(entry, loop);
transformList(loop.variables, this, loop);
transformList(loop.updates, this, loop);
transformList(loop.variables, loop);
transformList(loop.updates, loop);
body.add(loop);
}
@@ -375,6 +375,7 @@ end'ed
enforce
enforced
enforces
enforcing
enumerates
env
eof
@@ -85,7 +85,7 @@ void testTypes() {
void testMembers() {
testExpression(new PropertyGet(new IntLiteral(0), new Name('foo')), '''
0.foo''');
testExpression(new StaticGet(null), '''
testExpression(new StaticGet.byReference(null), '''
<missing-member-reference>''');
Reference unlinkedMemberName = new Reference();
@@ -63,8 +63,6 @@ String generateKernelFile() {
// 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
// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
//
// Instead modify 'tools/experimental_features.yaml' and run
+3186 -1177
View File
File diff suppressed because it is too large Load Diff
+34 -32
View File
@@ -2,8 +2,6 @@
// 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 kernel.canonical_name;
import 'ast.dart';
@@ -69,25 +67,27 @@ import 'ast.dart';
/// The "qualified name" allows a member to have a name that is private to
/// a library other than the one containing that member.
class CanonicalName {
CanonicalName _parent;
CanonicalName? _parent;
CanonicalName get parent => _parent;
CanonicalName? get parent => _parent;
final String name;
CanonicalName _nonRootTop;
CanonicalName? _nonRootTop;
Map<String, CanonicalName> _children;
Map<String, CanonicalName>? _children;
/// The library, class, or member bound to this name.
Reference reference;
Reference? reference;
/// Temporary index used during serialization.
int index = -1;
CanonicalName._(this._parent, this.name) {
CanonicalName._(CanonicalName parent, this.name) : _parent = parent {
// ignore: unnecessary_null_comparison
assert(name != null);
// ignore: unnecessary_null_comparison
assert(parent != null);
_nonRootTop = _parent.isRoot ? this : _parent._nonRootTop;
_nonRootTop = parent.isRoot ? this : parent._nonRootTop;
}
CanonicalName.root()
@@ -96,15 +96,16 @@ class CanonicalName {
name = '';
bool get isRoot => _parent == null;
CanonicalName get nonRootTop => _nonRootTop;
CanonicalName? get nonRootTop => _nonRootTop;
Iterable<CanonicalName> get children =>
_children?.values ?? const <CanonicalName>[];
Iterable<CanonicalName> get childrenOrNull => _children?.values;
Iterable<CanonicalName>? get childrenOrNull => _children?.values;
bool hasChild(String name) {
return _children != null && _children.containsKey(name);
return _children != null && _children!.containsKey(name);
}
CanonicalName getChild(String name) {
@@ -121,32 +122,32 @@ class CanonicalName {
CanonicalName getChildFromQualifiedName(Name name) {
return name.isPrivate
? getChildFromUri(name.library.importUri).getChild(name.text)
? getChildFromUri(name.library!.importUri).getChild(name.text)
: getChild(name.text);
}
CanonicalName getChildFromProcedure(Procedure procedure) {
return getChild(getProcedureQualifier(procedure))
.getChildFromQualifiedName(procedure.name);
.getChildFromQualifiedName(procedure.name!);
}
CanonicalName getChildFromField(Field field) {
return getChild('@fields').getChildFromQualifiedName(field.name);
return getChild('@fields').getChildFromQualifiedName(field.name!);
}
CanonicalName getChildFromFieldSetter(Field field) {
return getChild('@=fields').getChildFromQualifiedName(field.name);
return getChild('@=fields').getChildFromQualifiedName(field.name!);
}
CanonicalName getChildFromConstructor(Constructor constructor) {
return getChild('@constructors')
.getChildFromQualifiedName(constructor.name);
.getChildFromQualifiedName(constructor.name!);
}
CanonicalName getChildFromRedirectingFactoryConstructor(
RedirectingFactoryConstructor redirectingFactoryConstructor) {
return getChild('@factories')
.getChildFromQualifiedName(redirectingFactoryConstructor.name);
.getChildFromQualifiedName(redirectingFactoryConstructor.name!);
}
CanonicalName getChildFromFieldWithName(Name name) {
@@ -175,26 +176,27 @@ class CanonicalName {
/// the same name.
void adoptChild(CanonicalName child) {
if (child._parent == this) return;
if (_children != null && _children.containsKey(child.name)) {
if (_children != null && _children!.containsKey(child.name)) {
throw 'Cannot add a child to $this because this name already has a '
'child named ${child.name}';
}
child._parent.removeChild(child.name);
child._parent?.removeChild(child.name);
child._parent = this;
if (_children == null) _children = <String, CanonicalName>{};
_children[child.name] = child;
_children ??= <String, CanonicalName>{};
_children![child.name] = child;
}
void removeChild(String name) {
if (_children != null) {
_children.remove(name);
if (_children.isEmpty) {
_children!.remove(name);
if (_children!.isEmpty) {
_children = null;
}
}
}
void bindTo(Reference target) {
// ignore: unnecessary_null_comparison
if (target == null) {
throw '$this cannot be bound to null';
}
@@ -217,25 +219,25 @@ class CanonicalName {
// canonical name tree. We need to establish better invariants about the
// state of the canonical name tree, since for instance [unbindAll] doesn't
// remove unneeded leaf nodes.
_parent.removeChild(name);
_parent?.removeChild(name);
}
void _unbindInternal() {
if (reference == null) return;
assert(reference.canonicalName == this);
if (reference.node is Class) {
assert(reference!.canonicalName == this);
if (reference!.node is Class) {
// TODO(jensj): Get rid of this. This is only needed because pkg:vm does
// weird stuff in transformations. `unbind` should probably be private.
Class c = reference.node;
Class c = reference!.asClass;
c.ensureLoaded();
}
reference.canonicalName = null;
reference!.canonicalName = null;
reference = null;
}
void unbindAll() {
_unbindInternal();
Iterable<CanonicalName> children_ = childrenOrNull;
Iterable<CanonicalName>? children_ = childrenOrNull;
if (children_ != null) {
for (CanonicalName child in children_) {
child.unbindAll();
@@ -246,8 +248,8 @@ class CanonicalName {
String toString() => _parent == null ? 'root' : '$parent::$name';
String toStringInternal() {
if (isRoot) return "";
if (parent.isRoot) return "$name";
return "${parent.toStringInternal()}::$name";
if (parent!.isRoot) return "$name";
return "${parent!.toStringInternal()}::$name";
}
Reference getReference() {
+32 -22
View File
@@ -8,7 +8,6 @@ import 'dart:collection';
import 'dart:math';
import 'dart:typed_data';
// ignore: import_of_legacy_library_into_null_safe
import 'ast.dart' hide MapEntry;
import 'core_types.dart';
import 'type_algebra.dart';
@@ -283,7 +282,7 @@ abstract class ClassHierarchy implements ClassHierarchyBase {
/// [getDeclaredMembers] and [getInterfaceMembers].
static int compareMembers(Member first, Member second) {
if (first == second) return 0;
return compareNames(first.name, second.name);
return compareNames(first.name!, second.name!);
}
/// Compares names, using the same sort order as [getDeclaredMembers] and
@@ -329,7 +328,7 @@ abstract class ClassHierarchy implements ClassHierarchyBase {
while (low <= high) {
int mid = low + ((high - low) >> 1);
Member pivot = members[mid];
int comparison = compareNames(name, pivot.name);
int comparison = compareNames(name, pivot.name!);
if (comparison < 0) {
high = mid - 1;
} else if (comparison > 0) {
@@ -418,9 +417,9 @@ class _ClosedWorldClassHierarchySubtypes implements ClassHierarchySubtypes {
Member? getSingleTargetForInterfaceInvocation(Member interfaceTarget,
{bool setter: false}) {
if (invalidated) throw "This data structure has been invalidated";
Name name = interfaceTarget.name;
Name name = interfaceTarget.name!;
Member? target = null;
ClassSet subtypes = getSubtypesOf(interfaceTarget.enclosingClass);
ClassSet subtypes = getSubtypesOf(interfaceTarget.enclosingClass!);
for (Class c in subtypes) {
if (!c.isAbstract) {
Member? candidate =
@@ -591,8 +590,14 @@ class ClosedWorldClassHierarchy implements ClassHierarchy {
heap.add(infoFor(supertype.classNode));
}
if (classNode.supertype != null) addToHeap(classNode.supertype);
if (classNode.mixedInType != null) addToHeap(classNode.mixedInType);
Supertype? supertype = classNode.supertype;
if (supertype != null) {
addToHeap(supertype);
}
Supertype? mixedInType = classNode.mixedInType;
if (mixedInType != null) {
addToHeap(mixedInType);
}
classNode.implementedTypes.forEach(addToHeap);
}
return chain;
@@ -861,11 +866,13 @@ class ClosedWorldClassHierarchy implements ClassHierarchy {
void removeClass(Class cls) {
_ClassInfo? info = _infoMap[cls];
if (info == null) return;
if (cls.supertype != null) {
_infoMap[cls.supertype.classNode]?.directExtenders.remove(info);
Supertype? supertype = cls.supertype;
if (supertype != null) {
_infoMap[supertype.classNode]?.directExtenders.remove(info);
}
if (cls.mixedInType != null) {
_infoMap[cls.mixedInType.classNode]?.directMixers.remove(info);
Supertype? mixedInType = cls.mixedInType;
if (mixedInType != null) {
_infoMap[mixedInType.classNode]?.directMixers.remove(info);
}
for (Supertype supertype in cls.implementedTypes) {
_infoMap[supertype.classNode]?.directImplementers.remove(info);
@@ -1095,12 +1102,14 @@ class ClosedWorldClassHierarchy implements ClassHierarchy {
}
_collectSupersForClass(class_);
if (class_.supertype != null) {
_recordSuperTypes(info, class_.supertype);
Supertype? supertype = class_.supertype;
if (supertype != null) {
_recordSuperTypes(info, supertype);
}
if (class_.mixedInType != null) {
Supertype? mixedInType = class_.mixedInType;
if (mixedInType != null) {
mixinInferrer?.infer(this, class_);
_recordSuperTypes(info, class_.mixedInType);
_recordSuperTypes(info, mixedInType);
}
for (Supertype supertype in class_.implementedTypes) {
_recordSuperTypes(info, supertype);
@@ -1169,10 +1178,11 @@ class ClosedWorldClassHierarchy implements ClassHierarchy {
if (members != null) return members;
List<Member> inherited;
if (classNode.supertype == null) {
Supertype? supertype = classNode.supertype;
if (supertype == null) {
inherited = const <Member>[];
} else {
Class superClassNode = classNode.supertype.classNode;
Class superClassNode = supertype.classNode;
_ClassInfo superInfo = _infoMap[superClassNode]!;
inherited =
_buildImplementedMembers(superClassNode, superInfo, setters: setters);
@@ -1208,7 +1218,7 @@ class ClosedWorldClassHierarchy implements ClassHierarchy {
setters: setters)) {
if (mixinMember is! Procedure ||
(mixinMember is Procedure && !mixinMember.isSynthetic)) {
memberMap[mixinMember.name] = mixinMember;
memberMap[mixinMember.name!] = mixinMember;
}
}
}
@@ -1217,21 +1227,21 @@ class ClosedWorldClassHierarchy implements ClassHierarchy {
if (procedure.isStatic) continue;
if (procedure.kind == ProcedureKind.Setter) {
if (setters) {
memberMap[procedure.name] = procedure;
memberMap[procedure.name!] = procedure;
}
} else {
if (!setters) {
memberMap[procedure.name] = procedure;
memberMap[procedure.name!] = procedure;
}
}
}
for (Field field in classNode.fields) {
if (field.isStatic) continue;
if (!setters) {
memberMap[field.name] = field;
memberMap[field.name!] = field;
}
if (setters && field.hasSetter) {
memberMap[field.name] = field;
memberMap[field.name!] = field;
}
}
+2 -3
View File
@@ -4,7 +4,6 @@
library kernel.core_types;
// ignore: import_of_legacy_library_into_null_safe
import 'ast.dart';
import 'library_index.dart';
import 'type_algebra.dart';
@@ -1137,13 +1136,13 @@ class CoreTypes {
if (type is TypeParameterType &&
type.promotedBound != null &&
type.isPotentiallyNonNullable) {
return isBottom(type.promotedBound);
return isBottom(type.promotedBound!);
}
// BOTTOM(X extends T) is true iff BOTTOM(T).
if (type is TypeParameterType && type.isPotentiallyNonNullable) {
assert(type.promotedBound == null);
return isBottom(type.parameter.bound);
return isBottom(type.parameter.bound!);
}
if (type is BottomType) return true;
@@ -2,8 +2,6 @@
// 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
// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
//
// Instead modify 'tools/experimental_features.yaml' and run
+1 -2
View File
@@ -4,7 +4,6 @@
library kernel.import_table;
// ignore: import_of_legacy_library_into_null_safe
import 'ast.dart';
abstract class ImportTable {
@@ -111,7 +110,7 @@ class _ImportTableBuilder extends RecursiveVisitor {
visitLibrary(Library node) {
super.visitLibrary(node);
for (Reference exportedReference in node.additionalExports) {
addLibraryImport(exportedReference.node.parent as Library);
addLibraryImport(exportedReference.node!.parent as Library);
}
}
+11 -12
View File
@@ -4,7 +4,6 @@
library kernel.library_index;
// ignore: import_of_legacy_library_into_null_safe
import 'ast.dart';
/// Provides name-based access to library, class, and member AST nodes.
@@ -142,18 +141,18 @@ class _ClassTable {
_classes = <String, _MemberTable>{};
_classes![LibraryIndex.topLevel] = new _MemberTable.topLevel(this);
for (Class class_ in library.classes) {
_classes![class_.name] = new _MemberTable.fromClass(this, class_);
_classes![class_.name!] = new _MemberTable.fromClass(this, class_);
}
for (Extension extension_ in library.extensions) {
_classes![extension_.name] =
_classes![extension_.name!] =
new _MemberTable.fromExtension(this, extension_);
}
for (Reference reference in library.additionalExports) {
NamedNode node = reference.node;
NamedNode? node = reference.node;
if (node is Class) {
_classes![node.name] = new _MemberTable.fromClass(this, node);
_classes![node.name!] = new _MemberTable.fromClass(this, node);
} else if (node is Extension) {
_classes![node.name] = new _MemberTable.fromExtension(this, node);
_classes![node.name!] = new _MemberTable.fromExtension(this, node);
}
}
}
@@ -222,14 +221,14 @@ class _MemberTable {
String getDisambiguatedName(Member member) {
if (member is Procedure) {
if (member.isGetter) return LibraryIndex.getterPrefix + member.name.text;
if (member.isSetter) return LibraryIndex.setterPrefix + member.name.text;
if (member.isGetter) return LibraryIndex.getterPrefix + member.name!.text;
if (member.isSetter) return LibraryIndex.setterPrefix + member.name!.text;
}
return member.name.text;
return member.name!.text;
}
void _addMember(Member member) {
if (member.name.isPrivate && member.name.library != library) {
if (member.name!.isPrivate && member.name!.library != library) {
// Members whose name is private to other libraries cannot currently
// be found with the LibraryIndex class.
return;
@@ -252,10 +251,10 @@ class _MemberTable {
}
void _addExtensionMember(ExtensionMemberDescriptor extensionMember) {
final NamedNode replacement = extensionMember.member.node;
final NamedNode? replacement = extensionMember.member.node;
if (replacement is! Member) return;
Member member = replacement;
if (member.name.isPrivate && member.name.library != library) {
if (member.name!.isPrivate && member.name!.library != library) {
// Members whose name is private to other libraries cannot currently
// be found with the LibraryIndex class.
return;
-1
View File
@@ -2,7 +2,6 @@
// 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.
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart';
/// Pairs of [TypeParameter]s that are currently assumed to be
@@ -4,7 +4,6 @@
library kernel.hierarchy_based_type_environment;
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart' show Class, DartType, InterfaceType, Library, Member, Name;
import '../class_hierarchy.dart' show ClassHierarchyBase;
-2
View File
@@ -2,9 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE.md file.
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart';
import 'replacement_visitor.dart';
/// Returns legacy erasure of [type], that is, the type in which all nnbd
+10 -9
View File
@@ -2,7 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE.md file.
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart';
import '../type_algebra.dart';
@@ -73,13 +72,13 @@ class MergeVisitor implements DartTypeVisitor1<DartType?, DartType> {
for (int i = 0; i < newTypeParameters.length; i++) {
DartType? newBound =
mergeTypes(a.typeParameters[i].bound, b.typeParameters[i].bound);
mergeTypes(a.typeParameters[i].bound!, b.typeParameters[i].bound!);
if (newBound == null) {
return null;
}
newTypeParameters[i].bound = newBound;
DartType? newDefaultType = mergeTypes(
a.typeParameters[i].defaultType, b.typeParameters[i].defaultType);
a.typeParameters[i].defaultType!, b.typeParameters[i].defaultType!);
if (newDefaultType == null) {
return null;
}
@@ -90,7 +89,7 @@ class MergeVisitor implements DartTypeVisitor1<DartType?, DartType> {
DartType? newReturnType = mergeTypes(a.returnType, b.returnType);
if (newReturnType == null) return null;
List<DartType> newPositionalParameters =
new List<DartType>.filled(a.positionalParameters.length, dartTypeDummy);
new List<DartType>.filled(a.positionalParameters.length, dummyDartType);
for (int i = 0; i < a.positionalParameters.length; i++) {
DartType? newType =
mergeTypes(a.positionalParameters[i], b.positionalParameters[i]);
@@ -100,7 +99,7 @@ class MergeVisitor implements DartTypeVisitor1<DartType?, DartType> {
newPositionalParameters[i] = newType;
}
List<NamedType> newNamedParameters =
new List<NamedType>.filled(a.namedParameters.length, namedTypeDummy);
new List<NamedType>.filled(a.namedParameters.length, dummyNamedType);
for (int i = 0; i < a.namedParameters.length; i++) {
DartType? newType =
mergeTypes(a.namedParameters[i].type, b.namedParameters[i].type);
@@ -116,7 +115,8 @@ class MergeVisitor implements DartTypeVisitor1<DartType?, DartType> {
}
TypedefType? newTypedefType;
if (a.typedefType != null && b.typedefType != null) {
newTypedefType = mergeTypes(a.typedefType, b.typedefType) as TypedefType?;
newTypedefType =
mergeTypes(a.typedefType!, b.typedefType!) as TypedefType?;
// If the typedef couldn't be merged we just omit it from the resulting
// function type since the typedef type is only informational.
}
@@ -157,7 +157,7 @@ class MergeVisitor implements DartTypeVisitor1<DartType?, DartType> {
return new InterfaceType(a.classNode, nullability);
}
List<DartType> newTypeArguments =
new List<DartType>.filled(a.typeArguments.length, dartTypeDummy);
new List<DartType>.filled(a.typeArguments.length, dummyDartType);
for (int i = 0; i < a.typeArguments.length; i++) {
DartType? newType = a.typeArguments[i].accept1(this, b.typeArguments[i]);
if (newType == null) {
@@ -259,7 +259,8 @@ class MergeVisitor implements DartTypeVisitor1<DartType?, DartType> {
assert(a.parameter == b.parameter);
assert(a.promotedBound != null);
assert(b.promotedBound != null);
DartType? newPromotedBound = a.promotedBound.accept1(this, b.promotedBound);
DartType? newPromotedBound =
a.promotedBound!.accept1(this, b.promotedBound);
if (newPromotedBound == null) {
return null;
}
@@ -287,7 +288,7 @@ class MergeVisitor implements DartTypeVisitor1<DartType?, DartType> {
return new TypedefType(a.typedefNode, nullability);
}
List<DartType> newTypeArguments =
new List<DartType>.filled(a.typeArguments.length, dartTypeDummy);
new List<DartType>.filled(a.typeArguments.length, dummyDartType);
for (int i = 0; i < a.typeArguments.length; i++) {
DartType? newType = a.typeArguments[i].accept1(this, b.typeArguments[i]);
if (newType == null) return null;
+1 -2
View File
@@ -2,7 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE.md file.
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart';
import '../core_types.dart';
@@ -17,7 +16,7 @@ Supertype? nnbdTopMergeSupertype(
return a;
}
List<DartType> newTypeArguments =
new List<DartType>.filled(a.typeArguments.length, dartTypeDummy);
new List<DartType>.filled(a.typeArguments.length, dummyDartType);
for (int i = 0; i < a.typeArguments.length; i++) {
DartType? newTypeArgument =
nnbdTopMerge(coreTypes, a.typeArguments[i], b.typeArguments[i]);
+3 -4
View File
@@ -2,7 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE.md file.
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart';
/// Returns the type defines as `NonNull(type)` in the nnbd specification.
@@ -78,12 +77,12 @@ class _NonNullVisitor implements DartTypeVisitor<DartType?> {
return null;
}
if (node.promotedBound != null) {
if (node.promotedBound.nullability == Nullability.nonNullable) {
if (node.promotedBound!.nullability == Nullability.nonNullable) {
// The promoted bound is already non-nullable so we set the declared
// nullability to non-nullable.
return node.withDeclaredNullability(Nullability.nonNullable);
}
DartType? promotedBound = node.promotedBound.accept(this);
DartType? promotedBound = node.promotedBound!.accept(this);
if (promotedBound == null) {
// The promoted bound could not be made non-nullable so we set the
// declared nullability to undetermined.
@@ -91,7 +90,7 @@ class _NonNullVisitor implements DartTypeVisitor<DartType?> {
return null;
}
return new TypeParameterType.intersection(
node.parameter, Nullability.undetermined, node.promotedBound);
node.parameter, Nullability.undetermined, node.promotedBound!);
} else if (promotedBound.nullability == Nullability.nonNullable) {
// The bound could be made non-nullable so we use it as the promoted
// bound.
+5 -6
View File
@@ -2,7 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE.md file.
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart';
import '../core_types.dart';
import '../type_algebra.dart';
@@ -94,7 +93,7 @@ class _Norm extends ReplacementVisitor {
@override
DartType? visitTypeParameterType(TypeParameterType node, int variance) {
if (node.promotedBound == null) {
DartType bound = node.parameter.bound;
DartType bound = node.parameter.bound!;
if (normalizesToNever(bound)) {
DartType result = NeverType.fromNullability(node.nullability);
return result.accept1(this, variance) ?? result;
@@ -103,7 +102,7 @@ class _Norm extends ReplacementVisitor {
// If the bound isn't Never, the type is already normalized.
return null;
} else {
DartType bound = node.promotedBound;
DartType bound = node.promotedBound!;
bound = bound.accept1(this, variance) ?? bound;
if (bound is NeverType && bound.nullability == Nullability.nonNullable) {
return bound;
@@ -119,7 +118,7 @@ class _Norm extends ReplacementVisitor {
assert(!coreTypes.isTop(bound));
return new TypeParameterType(node.parameter, node.declaredNullability);
} else if (bound == coreTypes.objectNonNullableRawType &&
norm(coreTypes, node.parameter.bound) ==
norm(coreTypes, node.parameter.bound!) ==
coreTypes.objectNonNullableRawType) {
return new TypeParameterType(node.parameter, node.declaredNullability);
} else if (identical(bound, node.promotedBound)) {
@@ -144,9 +143,9 @@ class _Norm extends ReplacementVisitor {
return true;
} else if (type is TypeParameterType) {
if (type.promotedBound == null) {
return normalizesToNever(type.parameter.bound);
return normalizesToNever(type.parameter.bound!);
} else {
return normalizesToNever(type.promotedBound);
return normalizesToNever(type.promotedBound!);
}
}
return false;
+11 -11
View File
@@ -2,7 +2,6 @@
// 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.
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart';
import 'text_util.dart';
@@ -157,8 +156,9 @@ class AstPrinter {
}
String getVariableName(VariableDeclaration node) {
if (node.name != null) {
return node.name;
String? name = node.name;
if (name != null) {
return name;
}
return _variableNames[node] ??= '#${_variableNames.length}';
}
@@ -259,22 +259,22 @@ class AstPrinter {
for (TypeParameter typeParameter in typeParameters) {
_sb.write(comma);
_sb.write(typeParameter.name);
DartType bound = typeParameter.bound;
DartType bound = typeParameter.bound!;
bool isTopObject(DartType type) {
if (type is InterfaceType &&
type.className.node != null &&
type.classNode.name == 'Object') {
Uri? uri = type.classNode.enclosingLibrary?.importUri;
return uri?.scheme == 'dart' &&
uri?.path == 'core' &&
Uri uri = type.classNode.enclosingLibrary.importUri;
return uri.scheme == 'dart' &&
uri.path == 'core' &&
(type.nullability == Nullability.legacy ||
type.nullability == Nullability.nullable);
}
return false;
}
if (!isTopObject(bound) || isTopObject(typeParameter.defaultType)) {
if (!isTopObject(bound) || isTopObject(typeParameter.defaultType!)) {
// Include explicit bounds only.
_sb.write(' extends ');
writeType(bound);
@@ -385,7 +385,7 @@ class AstPrinter {
_sb.write(getVariableName(node));
if (includeInitializer && node.initializer != null && !node.isRequired) {
_sb.write(' = ');
writeExpression(node.initializer);
writeExpression(node.initializer!);
}
}
@@ -401,7 +401,7 @@ class AstPrinter {
}
_sb.write(node.typeParameters[index].name);
_sb.write(' extends ');
writeType(node.typeParameters[index].bound);
writeType(node.typeParameters[index].bound!);
}
_sb.write('>');
}
@@ -437,7 +437,7 @@ class AstPrinter {
if (body != null) {
if (body is ReturnStatement) {
_sb.write(' => ');
writeExpression(body.expression);
writeExpression(body.expression!);
} else {
_sb.write(' ');
writeStatement(body);
+2 -3
View File
@@ -2,7 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE.md file.
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart';
import '../type_algebra.dart';
@@ -49,7 +48,7 @@ class ReplacementVisitor implements DartTypeVisitor1<DartType?, int> {
Substitution.fromPairs(node.typeParameters, typeParameterTypes);
for (int i = 0; i < newTypeParameters.length; i++) {
newTypeParameters[i].bound =
substitution.substituteType(newTypeParameters[i].bound);
substitution.substituteType(newTypeParameters[i].bound!);
}
}
@@ -211,7 +210,7 @@ class ReplacementVisitor implements DartTypeVisitor1<DartType?, int> {
DartType? visitTypeParameterType(TypeParameterType node, int variance) {
Nullability? newNullability = visitNullability(node);
if (node.promotedBound != null) {
DartType newPromotedBound = node.promotedBound.accept1(this, variance);
DartType? newPromotedBound = node.promotedBound!.accept1(this, variance);
return createPromotedTypeParameterType(
node, newNullability, newPromotedBound);
}
+17 -18
View File
@@ -4,7 +4,6 @@
import 'dart:math' as math;
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart';
import '../class_hierarchy.dart';
import '../core_types.dart';
@@ -216,7 +215,7 @@ mixin StandardBounds {
s.promotedBound != null &&
t is TypeParameterType &&
t.promotedBound != null) {
return morebottom(s.promotedBound, t.promotedBound);
return morebottom(s.promotedBound!, t.promotedBound!);
}
// MOREBOTTOM(X&S, T) = true.
@@ -233,7 +232,7 @@ mixin StandardBounds {
if (s is TypeParameterType && t is TypeParameterType) {
assert(s.promotedBound == null);
assert(t.promotedBound == null);
return morebottom(s.parameter.bound, t.parameter.bound);
return morebottom(s.parameter.bound!, t.parameter.bound!);
}
throw new UnsupportedError("morebottom($s, $t)");
@@ -950,8 +949,8 @@ mixin StandardBounds {
// TODO(dmitryas): Figure out if a procedure for syntactic equality
// should be used instead.
if (!areMutualSubtypes(
f.typeParameters[i].bound,
substitution.substituteType(g.typeParameters[i].bound),
f.typeParameters[i].bound!,
substitution.substituteType(g.typeParameters[i].bound!),
SubtypeCheckMode.withNullabilities)) {
boundsMatch = false;
}
@@ -967,7 +966,7 @@ mixin StandardBounds {
List<TypeParameter> typeParameters = f.typeParameters;
List<DartType> positionalParameters =
new List<DartType>.filled(maxPos, dartTypeDummy);
new List<DartType>.filled(maxPos, dummyDartType);
for (int i = 0; i < minPos; ++i) {
positionalParameters[i] = _getNullabilityAwareStandardUpperBound(
f.positionalParameters[i],
@@ -1149,8 +1148,8 @@ mixin StandardBounds {
// TODO(dmitryas): Figure out if a procedure for syntactic
// equality should be used instead.
if (!areMutualSubtypes(
f.typeParameters[i].bound,
substitution.substituteType(g.typeParameters[i].bound),
f.typeParameters[i].bound!,
substitution.substituteType(g.typeParameters[i].bound!),
SubtypeCheckMode.withNullabilities)) {
boundsMatch = false;
}
@@ -1164,7 +1163,7 @@ mixin StandardBounds {
List<TypeParameter> typeParameters = f.typeParameters;
List<DartType> positionalParameters =
new List<DartType>.filled(minPos, dartTypeDummy);
new List<DartType>.filled(minPos, dummyDartType);
for (int i = 0; i < minPos; ++i) {
positionalParameters[i] = _getNullabilityAwareStandardLowerBound(
f.positionalParameters[i],
@@ -1233,12 +1232,12 @@ mixin StandardBounds {
topFunctionType: coreTypes.functionNonNullableRawType,
unhandledTypeHandler: (type, recursor) => false);
return _getNullabilityAwareStandardUpperBound(
eliminator.eliminateToGreatest(type1.parameter.bound),
eliminator.eliminateToGreatest(type1.parameter.bound!),
type2,
clientLibrary)
.withDeclaredNullability(uniteNullabilities(
type1.declaredNullability,
uniteNullabilities(type1.parameter.bound.declaredNullability,
uniteNullabilities(type1.parameter.bound!.declaredNullability,
type2.declaredNullability)));
} else {
// UP(X1 & B1, T2) =
@@ -1265,11 +1264,11 @@ mixin StandardBounds {
topFunctionType: coreTypes.functionNonNullableRawType,
unhandledTypeHandler: (type, recursor) => false);
return _getNullabilityAwareStandardUpperBound(
eliminator.eliminateToGreatest(type1.promotedBound),
eliminator.eliminateToGreatest(type1.promotedBound!),
type2,
clientLibrary)
.withDeclaredNullability(uniteNullabilities(
type1.promotedBound.declaredNullability,
type1.promotedBound!.declaredNullability,
type2.declaredNullability));
}
}
@@ -1419,7 +1418,7 @@ mixin StandardBounds {
int totalPositional =
math.max(f.positionalParameters.length, g.positionalParameters.length);
List<DartType> positionalParameters =
new List<DartType>.filled(totalPositional, dartTypeDummy);
new List<DartType>.filled(totalPositional, dummyDartType);
for (int i = 0; i < totalPositional; i++) {
if (i < f.positionalParameters.length) {
DartType fType = f.positionalParameters[i];
@@ -1523,7 +1522,7 @@ mixin StandardBounds {
int totalPositional =
math.min(f.positionalParameters.length, g.positionalParameters.length);
List<DartType> positionalParameters =
new List<DartType>.filled(totalPositional, dartTypeDummy);
new List<DartType>.filled(totalPositional, dummyDartType);
for (int i = 0; i < totalPositional; i++) {
positionalParameters[i] = getStandardLowerBound(
f.positionalParameters[i], g.positionalParameters[i], clientLibrary);
@@ -1602,7 +1601,7 @@ mixin StandardBounds {
assert(tArgs1.length == tArgs2.length);
assert(tArgs1.length == tParams.length);
List<DartType> tArgs = new List.filled(tArgs1.length, dartTypeDummy);
List<DartType> tArgs = new List.filled(tArgs1.length, dummyDartType);
for (int i = 0; i < tArgs1.length; i++) {
if (tParams[i].variance == Variance.contravariant) {
tArgs[i] = getStandardLowerBound(tArgs1[i], tArgs2[i], clientLibrary);
@@ -1675,14 +1674,14 @@ mixin StandardBounds {
// we need to replicate that behavior?
return getStandardUpperBound(
Substitution.fromMap({type1.parameter: coreTypes.objectLegacyRawType})
.substituteType(type1.parameter.bound),
.substituteType(type1.parameter.bound!),
type2,
clientLibrary);
} else if (type2 is TypeParameterType) {
return getStandardUpperBound(
type1,
Substitution.fromMap({type2.parameter: coreTypes.objectLegacyRawType})
.substituteType(type2.parameter.bound),
.substituteType(type2.parameter.bound!),
clientLibrary);
} else {
// We should only be called when at least one of the types is a
+7 -10
View File
@@ -2,7 +2,6 @@
// 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.
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart';
String nullabilityToString(Nullability nullability) {
@@ -47,17 +46,17 @@ String qualifiedCanonicalNameToString(CanonicalName canonicalName,
{bool includeLibraryName: false}) {
if (canonicalName.isRoot) {
return '<root>';
} else if (canonicalName.parent.isRoot) {
} else if (canonicalName.parent!.isRoot) {
return canonicalName.name;
} else if (canonicalName.parent.parent.isRoot) {
} else if (canonicalName.parent!.parent!.isRoot) {
if (!includeLibraryName) {
return canonicalName.name;
}
String parentName = qualifiedCanonicalNameToString(canonicalName.parent,
String parentName = qualifiedCanonicalNameToString(canonicalName.parent!,
includeLibraryName: includeLibraryName);
return '$parentName::${canonicalName.name}';
} else {
String parentName = qualifiedCanonicalNameToString(canonicalName.parent,
String parentName = qualifiedCanonicalNameToString(canonicalName.parent!,
includeLibraryName: includeLibraryName);
return '$parentName.${canonicalName.name}';
}
@@ -165,15 +164,13 @@ String qualifiedTypedefNameToStringByReference(Reference? reference,
}
String typedefNameToString(Typedef? node) {
return node == null
? 'null'
: node.name ?? 'null-named typedef ${node.runtimeType} ${node.hashCode}';
return node == null ? 'null' : node.name;
}
String qualifiedMemberNameToString(Member node,
{bool includeLibraryName: false}) {
if (node.enclosingClass != null) {
return qualifiedClassNameToString(node.enclosingClass,
return qualifiedClassNameToString(node.enclosingClass!,
includeLibraryName: includeLibraryName) +
'.' +
memberNameToString(node);
@@ -215,7 +212,7 @@ String memberNameToString(Member node) {
String qualifiedTypeParameterNameToString(TypeParameter node,
{bool includeLibraryName: false}) {
TreeNode parent = node.parent;
TreeNode? parent = node.parent;
if (parent is Class) {
return qualifiedClassNameToString(parent,
includeLibraryName: includeLibraryName) +
+15 -16
View File
@@ -2,7 +2,6 @@
// 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.
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart'
show
BottomType,
@@ -381,7 +380,7 @@ class IsInterfaceSubtypeOf extends TypeRelation<InterfaceType> {
IsSubtypeOf isTypeParameterRelated(
TypeParameterType s, InterfaceType t, Types types) {
return types
.performNullabilityAwareSubtypeCheck(s.parameter.bound, t)
.performNullabilityAwareSubtypeCheck(s.parameter.bound!, t)
.and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
}
@@ -402,7 +401,7 @@ class IsInterfaceSubtypeOf extends TypeRelation<InterfaceType> {
IsSubtypeOf isIntersectionRelated(
TypeParameterType intersection, InterfaceType t, Types types) {
return types.performNullabilityAwareSubtypeCheck(
intersection.promotedBound, t); // Rule 12.
intersection.promotedBound!, t); // Rule 12.
}
@override
@@ -454,7 +453,7 @@ class IsFunctionSubtypeOf extends TypeRelation<FunctionType> {
TypeParameter sTypeVariable = sTypeVariables[i];
TypeParameter tTypeVariable = tTypeVariables[i];
result = result.and(types.performNullabilityAwareMutualSubtypesCheck(
sTypeVariable.bound, tTypeVariable.bound));
sTypeVariable.bound!, tTypeVariable.bound!));
typeVariableSubstitution.add(new TypeParameterType.forAlphaRenaming(
sTypeVariable, tTypeVariable));
}
@@ -468,8 +467,8 @@ class IsFunctionSubtypeOf extends TypeRelation<FunctionType> {
TypeParameter sTypeVariable = sTypeVariables[i];
TypeParameter tTypeVariable = tTypeVariables[i];
result = result.and(types.performNullabilityAwareMutualSubtypesCheck(
substitution.substituteType(sTypeVariable.bound),
tTypeVariable.bound));
substitution.substituteType(sTypeVariable.bound!),
tTypeVariable.bound!));
if (!result.isSubtypeWhenIgnoringNullabilities()) {
return const IsSubtypeOf.never();
}
@@ -582,7 +581,7 @@ class IsFunctionSubtypeOf extends TypeRelation<FunctionType> {
TypeParameterType intersection, FunctionType t, Types types) {
// Rule 12.
return types.performNullabilityAwareSubtypeCheck(
intersection.promotedBound, t);
intersection.promotedBound!, t);
}
@override
@@ -590,7 +589,7 @@ class IsFunctionSubtypeOf extends TypeRelation<FunctionType> {
TypeParameterType s, FunctionType t, Types types) {
// Rule 13.
return types
.performNullabilityAwareSubtypeCheck(s.parameter.bound, t)
.performNullabilityAwareSubtypeCheck(s.parameter.bound!, t)
.and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
}
@@ -645,7 +644,7 @@ class IsTypeParameterSubtypeOf extends TypeRelation<TypeParameterType> {
// Rule 12.
return types.performNullabilityAwareSubtypeCheck(
intersection.promotedBound
intersection.promotedBound!
.withDeclaredNullability(intersection.nullability),
t);
}
@@ -826,9 +825,9 @@ class IsFutureOrSubtypeOf extends TypeRelation<FutureOrType> {
s, t.typeArgument.withDeclaredNullability(t.nullability))
// Rule 13.
.orSubtypeCheckFor(
s.parameter.bound.withDeclaredNullability(
s.parameter.bound!.withDeclaredNullability(
combineNullabilitiesForSubstitution(
s.parameter.bound.nullability, s.nullability)),
s.parameter.bound!.nullability, s.nullability)),
t,
types)
// Rule 10.
@@ -850,7 +849,7 @@ class IsFutureOrSubtypeOf extends TypeRelation<FutureOrType> {
IsSubtypeOf isIntersectionRelated(
TypeParameterType intersection, FutureOrType t, Types types) {
return isTypeParameterRelated(intersection, t, types) // Rule 8.
.orSubtypeCheckFor(intersection.promotedBound, t, types); // Rule 12.
.orSubtypeCheckFor(intersection.promotedBound!, t, types); // Rule 12.
}
@override
@@ -868,7 +867,7 @@ class IsIntersectionSubtypeOf extends TypeRelation<TypeParameterType> {
// Rule 9.
return const IsTypeParameterSubtypeOf()
.isIntersectionRelated(sIntersection, tIntersection, types)
.andSubtypeCheckFor(sIntersection, tIntersection.promotedBound, types);
.andSubtypeCheckFor(sIntersection, tIntersection.promotedBound!, types);
}
@override
@@ -877,7 +876,7 @@ class IsIntersectionSubtypeOf extends TypeRelation<TypeParameterType> {
// Rule 9.
return const IsTypeParameterSubtypeOf()
.isTypeParameterRelated(s, intersection, types)
.andSubtypeCheckFor(s, intersection.promotedBound, types);
.andSubtypeCheckFor(s, intersection.promotedBound!, types);
}
@override
@@ -936,7 +935,7 @@ class IsNullTypeSubtypeOf implements TypeRelation<NullType> {
IsSubtypeOf isIntersectionRelated(
TypeParameterType intersection, NullType t, Types types) {
return types.performNullabilityAwareMutualSubtypesCheck(
intersection.promotedBound, t);
intersection.promotedBound!, t);
}
IsSubtypeOf isFunctionRelated(FunctionType s, NullType t, Types types) {
@@ -978,7 +977,7 @@ class IsNeverTypeSubtypeOf implements TypeRelation<NeverType> {
IsSubtypeOf isIntersectionRelated(
TypeParameterType intersection, NeverType t, Types types) {
return types.performNullabilityAwareSubtypeCheck(
intersection.promotedBound, t);
intersection.promotedBound!, t);
}
IsSubtypeOf isFunctionRelated(FunctionType s, NeverType t, Types types) {
+183 -143
View File
@@ -2,8 +2,6 @@
// 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 kernel.ast_to_text;
import 'dart:core' hide MapEntry;
@@ -26,11 +24,13 @@ abstract class Namer<T> {
class NormalNamer<T> extends Namer<T> {
final String prefix;
NormalNamer(this.prefix);
}
class ConstantNamer extends RecursiveResultVisitor<Null> with Namer<Constant> {
final String prefix;
ConstantNamer(this.prefix);
String getName(Constant constant) {
@@ -78,7 +78,7 @@ class Disambiguator<T, U> {
final Map<U, String> namesU = <U, String>{};
final Set<String> usedNames = new Set<String>();
String disambiguate(T key1, U key2, String proposeName()) {
String disambiguate(T? key1, U? key2, String proposeName()) {
String getNewName() {
String proposedName = proposeName();
if (usedNames.add(proposedName)) return proposedName;
@@ -90,12 +90,12 @@ class Disambiguator<T, U> {
}
if (key1 != null) {
String result = namesT[key1];
String? result = namesT[key1];
if (result != null) return result;
return namesT[key1] = getNewName();
}
if (key2 != null) {
String result = namesU[key2];
String? result = namesU[key2];
if (result != null) return result;
return namesU[key2] = getNewName();
}
@@ -105,13 +105,13 @@ class Disambiguator<T, U> {
NameSystem globalDebuggingNames = new NameSystem();
String debugLibraryName(Library node) {
String debugLibraryName(Library? node) {
return node == null
? 'null'
: node.name ?? globalDebuggingNames.nameLibrary(node);
}
String debugClassName(Class node) {
String debugClassName(Class? node) {
return node == null
? 'null'
: node.name ?? globalDebuggingNames.nameClass(node);
@@ -127,7 +127,7 @@ String debugMemberName(Member node) {
String debugQualifiedMemberName(Member node) {
if (node.enclosingClass != null) {
return debugQualifiedClassName(node.enclosingClass) +
return debugQualifiedClassName(node.enclosingClass!) +
'::' +
debugMemberName(node);
} else {
@@ -142,13 +142,14 @@ String debugTypeParameterName(TypeParameter node) {
}
String debugQualifiedTypeParameterName(TypeParameter node) {
if (node.parent is Class) {
return debugQualifiedClassName(node.parent) +
TreeNode? parent = node.parent;
if (parent is Class) {
return debugQualifiedClassName(parent) +
'::' +
debugTypeParameterName(node);
}
if (node.parent is Member) {
return debugQualifiedMemberName(node.parent) +
if (parent is Member) {
return debugQualifiedMemberName(parent) +
'::' +
debugTypeParameterName(node);
}
@@ -212,11 +213,17 @@ class NameSystem {
final RegExp pathSeparator = new RegExp('[\\/]');
String nameLibraryPrefix(Library node, {String proposedName}) {
String nameLibraryPrefix(Library node, {String? proposedName}) {
return prefixes.disambiguate(node.reference, node.reference.canonicalName,
() {
if (proposedName != null) return proposedName;
if (node.name != null) return abbreviateName(node.name);
if (proposedName != null) {
return proposedName;
}
String? name = node.name;
if (name != null) {
return abbreviateName(name);
}
// ignore: unnecessary_null_comparison
if (node.importUri != null) {
String path = node.importUri.hasEmptyPath
? '${node.importUri}'
@@ -230,13 +237,13 @@ class NameSystem {
});
}
nameCanonicalNameAsLibraryPrefix(Reference node, CanonicalName name,
{String proposedName}) {
nameCanonicalNameAsLibraryPrefix(Reference? node, CanonicalName? name,
{String? proposedName}) {
return prefixes.disambiguate(node, name, () {
if (proposedName != null) return proposedName;
CanonicalName canonicalName = name ?? node.canonicalName;
CanonicalName? canonicalName = name ?? node?.canonicalName;
if (canonicalName?.name != null) {
String path = canonicalName.name;
String path = canonicalName!.name;
int slash = path.lastIndexOf(pathSeparator);
if (slash >= 0) {
path = path.substring(slash + 1);
@@ -274,9 +281,9 @@ abstract class Annotator {
class Printer extends Visitor<void> with VisitorVoidMixin {
final NameSystem syntheticNames;
final StringSink sink;
final Annotator annotator;
final Map<String, MetadataRepository<Object>> metadata;
ImportTable importTable;
final Annotator? annotator;
final Map<String, MetadataRepository<dynamic>>? metadata;
ImportTable? importTable;
int indentation = 0;
int column = 0;
bool showOffsets;
@@ -288,7 +295,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
int state = SPACE;
Printer(this.sink,
{NameSystem syntheticNames,
{NameSystem? syntheticNames,
this.showOffsets: false,
this.showMetadata: false,
this.importTable,
@@ -297,7 +304,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
: this.syntheticNames = syntheticNames ?? new NameSystem();
Printer createInner(ImportTable importTable,
Map<String, MetadataRepository<Object>> metadata) {
Map<String, MetadataRepository<dynamic>>? metadata) {
return new Printer(sink,
importTable: importTable,
metadata: metadata,
@@ -319,8 +326,9 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
String getLibraryReference(Library node) {
// ignore: unnecessary_null_comparison
if (node == null) return '<No Library>';
if (importTable != null && importTable.getImportIndex(node) != -1) {
if (importTable != null && importTable?.getImportIndex(node) != -1) {
return syntheticNames.nameLibraryPrefix(node);
}
return getLibraryName(node);
@@ -335,6 +343,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
String getClassReference(Class node) {
// ignore: unnecessary_null_comparison
if (node == null) return '<No Class>';
String name = getClassName(node);
String library = getLibraryReference(node.enclosingLibrary);
@@ -342,6 +351,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
String getTypedefReference(Typedef node) {
// ignore: unnecessary_null_comparison
if (node == null) return '<No Typedef>';
String library = getLibraryReference(node.enclosingLibrary);
return '$library::${node.name}';
@@ -352,15 +362,17 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
Name getMemberName(Member node) {
if (node.name?.text == '') return emptyName;
if (node.name != null) return node.name;
if (node.name != null) return node.name!;
return new Name(syntheticNames.nameMember(node));
}
String getMemberReference(Member node) {
// ignore: unnecessary_null_comparison
if (node == null) return '<No Member>';
String name = getMemberName(node).text;
if (node.parent is Class) {
String className = getClassReference(node.parent);
Class? enclosingClass = node.enclosingClass;
if (enclosingClass != null) {
String className = getClassReference(enclosingClass);
return '$className::$name';
} else {
String library = getLibraryReference(node.enclosingLibrary);
@@ -373,6 +385,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
String getVariableReference(VariableDeclaration node) {
// ignore: unnecessary_null_comparison
if (node == null) return '<No VariableDeclaration>';
return getVariableName(node);
}
@@ -382,13 +395,15 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
String getTypeParameterReference(TypeParameter node) {
// ignore: unnecessary_null_comparison
if (node == null) return '<No TypeParameter>';
String name = getTypeParameterName(node);
if (node.parent is FunctionNode && node.parent.parent is Member) {
String member = getMemberReference(node.parent.parent);
TreeNode? parent = node.parent;
if (parent is FunctionNode && parent.parent is Member) {
String member = getMemberReference(parent.parent as Member);
return '$member::$name';
} else if (node.parent is Class) {
String className = getClassReference(node.parent);
} else if (parent is Class) {
String className = getClassReference(parent);
return '$className::$name';
} else {
return name; // Bound inside a function type.
@@ -399,8 +414,8 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeProblemsAsJson("Problems in component", component.problemsAsJson);
}
void writeProblemsAsJson(String header, List<String> problemsAsJson) {
if (problemsAsJson?.isEmpty == false) {
void writeProblemsAsJson(String header, List<String>? problemsAsJson) {
if (problemsAsJson != null && problemsAsJson.isNotEmpty) {
endLine("//");
write("// ");
write(header);
@@ -408,7 +423,8 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
endLine("//");
for (String s in problemsAsJson) {
Map<String, Object> decoded = json.decode(s);
List<Object> plainTextFormatted = decoded["plainTextFormatted"];
List<Object> plainTextFormatted =
decoded["plainTextFormatted"] as List<Object>;
List<String> lines = plainTextFormatted.join("\n").split("\n");
for (int i = 0; i < lines.length; i++) {
write("//");
@@ -424,8 +440,9 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
void writeLibraryFile(Library library) {
writeAnnotationList(library.annotations);
writeWord('library');
if (library.name != null) {
writeWord(library.name);
String? name = library.name;
if (name != null) {
writeWord(name);
}
if (library.isNonNullableByDefault) {
writeWord("/*isNonNullableByDefault*/");
@@ -453,7 +470,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
void writeStandardLibraryContent(Library library,
{Printer outerPrinter, LibraryImportTable importsToPrint}) {
{Printer? outerPrinter, LibraryImportTable? importsToPrint}) {
outerPrinter ??= this;
outerPrinter.writeProblemsAsJson(
"Problems in library", library.problemsAsJson);
@@ -479,23 +496,23 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
write('additionalExports = (');
for (int i = 0; i < additionalExports.length; i++) {
Reference reference = additionalExports[i];
NamedNode node = reference.node;
NamedNode? node = reference.node;
if (node is Class) {
Library nodeLibrary = node.enclosingLibrary;
String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
write(prefix + '::' + node.name);
write(prefix + '::' + node.name!);
} else if (node is Extension) {
Library nodeLibrary = node.enclosingLibrary;
String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
write(prefix + '::' + node.name);
write(prefix + '::' + node.name!);
} else if (node is Field) {
Library nodeLibrary = node.enclosingLibrary;
String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
write(prefix + '::' + node.name.text);
write(prefix + '::' + node.name!.text);
} else if (node is Procedure) {
Library nodeLibrary = node.enclosingLibrary;
String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
write(prefix + '::' + node.name.text);
write(prefix + '::' + node.name!.text);
} else if (node is Typedef) {
Library nodeLibrary = node.enclosingLibrary;
String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
@@ -532,9 +549,11 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
writeAnnotationList(library.annotations);
writeWord('library');
if (library.name != null) {
writeWord(library.name);
String? name = library.name;
if (name != null) {
writeWord(name);
}
// ignore: unnecessary_null_comparison
if (library.importUri != null) {
writeSpaced('from');
writeWord('"${library.importUri}"');
@@ -567,7 +586,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
endLine('}');
}
int getPrecedence(TreeNode node) {
int getPrecedence(Expression node) {
return Precedence.of(node);
}
@@ -618,7 +637,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeSpace(' ' * indentation);
}
void writeNode(Node node) {
void writeNode(Node? node) {
if (node == null) {
writeSymbol("<Null>");
} else {
@@ -642,16 +661,10 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
}
void writeOptionalNode(Node node) {
if (node != null) {
node.accept(this);
}
}
void writeMetadata(TreeNode node) {
if (metadata != null) {
for (MetadataRepository<Object> md in metadata.values) {
final Object nodeMetadata = md.mapping[node];
for (MetadataRepository<dynamic> md in metadata!.values) {
final dynamic nodeMetadata = md.mapping[node];
if (nodeMetadata != null) {
writeWord("[@${md.tag}=${nodeMetadata}]");
}
@@ -659,7 +672,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
}
void writeAnnotatedType(DartType type, String annotation) {
void writeAnnotatedType(DartType type, String? annotation) {
writeType(type);
if (annotation != null) {
write('/');
@@ -669,6 +682,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
void writeType(DartType type) {
// ignore: unnecessary_null_comparison
if (type == null) {
write('<No DartType>');
} else {
@@ -677,12 +691,14 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
void writeOptionalType(DartType type) {
// ignore: unnecessary_null_comparison
if (type != null) {
type.accept(this);
}
}
visitSupertype(Supertype type) {
// ignore: unnecessary_null_comparison
if (type == null) {
write('<No Supertype>');
} else {
@@ -711,14 +727,14 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
void writeName(Name name) {
if (name?.text == '') {
if (name.text == '') {
writeWord(emptyNameString);
} else {
writeWord(name?.text ?? '<anonymous>'); // TODO: write library name
writeWord(name.text); // TODO: write library name
}
}
void endLine([String string]) {
void endLine([String? string]) {
if (string != null) {
write(string);
}
@@ -728,7 +744,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
void writeFunction(FunctionNode function,
{name, List<Initializer> initializers, bool terminateLine: true}) {
{name, List<Initializer>? initializers, bool terminateLine: true}) {
if (name is String) {
writeWord(name);
} else if (name is Name) {
@@ -758,8 +774,9 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeSpaced(getAsyncMarkerKeyword(function.dartAsyncMarker));
writeSpaced("*/");
}
if (function.body != null) {
writeFunctionBody(function.body, terminateLine: terminateLine);
Statement? body = function.body;
if (body != null) {
writeFunctionBody(body, terminateLine: terminateLine);
} else if (terminateLine) {
endLine(';');
} else {
@@ -806,15 +823,15 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
} else if (body is ReturnStatement && !terminateLine) {
writeSpaced('=>');
writeExpression(body.expression);
writeExpression(body.expression!);
} else {
writeBody(body);
}
}
writeFunctionType(FunctionType node,
{List<VariableDeclaration> typedefPositional,
List<VariableDeclaration> typedefNamed}) {
{List<VariableDeclaration>? typedefPositional,
List<VariableDeclaration>? typedefNamed}) {
if (state == WORD) {
ensureSpace();
}
@@ -892,7 +909,8 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
}
void writeReturnType(DartType type, String annotation) {
void writeReturnType(DartType type, String? annotation) {
// ignore: unnecessary_null_comparison
if (type == null) return;
writeSpaced('');
writeAnnotatedType(type, annotation);
@@ -949,23 +967,24 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
String getClassReferenceFromReference(Reference reference) {
// ignore: unnecessary_null_comparison
if (reference == null) return '<No Class>';
if (reference.node != null) return getClassReference(reference.asClass);
if (reference.canonicalName != null) {
return getCanonicalNameString(reference.canonicalName);
return getCanonicalNameString(reference.canonicalName!);
}
throw "Neither node nor canonical name found";
}
void writeMemberReferenceFromReference(Reference reference) {
void writeMemberReferenceFromReference(Reference? reference) {
writeWord(getMemberReferenceFromReference(reference));
}
String getMemberReferenceFromReference(Reference reference) {
String getMemberReferenceFromReference(Reference? reference) {
if (reference == null) return '<No Member>';
if (reference.node != null) return getMemberReference(reference.asMember);
if (reference.canonicalName != null) {
return getCanonicalNameString(reference.canonicalName);
return getCanonicalNameString(reference.canonicalName!);
}
throw "Neither node nor canonical name found";
}
@@ -976,28 +995,28 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
String libraryString(CanonicalName lib) {
if (lib.reference?.node != null) {
return getLibraryReference(lib.reference.asLibrary);
return getLibraryReference(lib.reference!.asLibrary);
}
return syntheticNames.nameCanonicalNameAsLibraryPrefix(
lib.reference, lib);
}
String classString(CanonicalName cls) =>
libraryString(cls.parent) + '::' + cls.name;
libraryString(cls.parent!) + '::' + cls.name;
if (name.parent.isRoot) return libraryString(name);
if (name.parent.parent.isRoot) return classString(name);
if (name.parent!.isRoot) return libraryString(name);
if (name.parent!.parent!.isRoot) return classString(name);
CanonicalName atNode = name.parent;
CanonicalName atNode = name.parent!;
while (!atNode.name.startsWith('@')) {
atNode = atNode.parent;
atNode = atNode.parent!;
}
String parent = "";
if (atNode.parent.parent.isRoot) {
parent = libraryString(atNode.parent);
if (atNode.parent!.parent!.isRoot) {
parent = libraryString(atNode.parent!);
} else {
parent = classString(atNode.parent);
parent = classString(atNode.parent!);
}
if (name.name == '') return "$parent::$emptyNameString";
@@ -1023,7 +1042,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeWord(getTypeParameterReference(node));
}
void writeExpression(Expression node, [int minimumPrecedence]) {
void writeExpression(Expression node, [int? minimumPrecedence]) {
final bool highlight = shouldHighlight(node);
if (highlight) {
startHighlight(node);
@@ -1087,9 +1106,10 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeSpace();
writeAnnotatedType(node.type, annotator?.annotateField(this, node));
writeName(getMemberName(node));
if (node.initializer != null) {
Expression? initializer = node.initializer;
if (initializer != null) {
writeSpaced('=');
writeExpression(node.initializer);
writeExpression(initializer);
}
List<String> features = <String>[];
if (node.enclosingLibrary.isNonNullableByDefault !=
@@ -1100,10 +1120,10 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
features.add("isLegacy");
}
}
if ((node.enclosingClass == null &&
Class? enclosingClass = node.enclosingClass;
if ((enclosingClass == null &&
node.enclosingLibrary.fileUri != node.fileUri) ||
(node.enclosingClass != null &&
node.enclosingClass.fileUri != node.fileUri)) {
(enclosingClass != null && enclosingClass.fileUri != node.fileUri)) {
features.add(" from ${node.fileUri} ");
}
if (features.isNotEmpty) {
@@ -1148,10 +1168,10 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
features.add("isLegacy");
}
}
if ((node.enclosingClass == null &&
Class? enclosingClass = node.enclosingClass;
if ((enclosingClass == null &&
node.enclosingLibrary.fileUri != node.fileUri) ||
(node.enclosingClass != null &&
node.enclosingClass.fileUri != node.fileUri)) {
(enclosingClass != null && enclosingClass.fileUri != node.fileUri)) {
features.add(" from ${node.fileUri} ");
}
if (features.isNotEmpty) {
@@ -1163,17 +1183,17 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
case ProcedureStubKind.ConcreteForwardingStub:
case ProcedureStubKind.NoSuchMethodForwarder:
case ProcedureStubKind.ConcreteMixinStub:
writeFunction(node.function, name: getMemberName(node));
writeFunction(node.function!, name: getMemberName(node));
break;
case ProcedureStubKind.MemberSignature:
case ProcedureStubKind.AbstractMixinStub:
writeFunction(node.function,
writeFunction(node.function!,
name: getMemberName(node), terminateLine: false);
if (node.function.body is ReturnStatement) {
if (node.function!.body is ReturnStatement) {
writeSymbol(';');
}
writeSymbol(' -> ');
writeMemberReferenceFromReference(node.stubTargetReference);
writeMemberReferenceFromReference(node.stubTargetReference!);
endLine();
break;
}
@@ -1198,7 +1218,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
if (features.isNotEmpty) {
writeWord("/*${features.join(',')}*/");
}
writeFunction(node.function,
writeFunction(node.function!,
name: node.name, initializers: node.initializers);
}
@@ -1210,13 +1230,13 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeWord('redirecting_factory');
if (node.name != null) {
writeName(node.name);
writeName(node.name!);
}
writeTypeParameterList(node.typeParameters);
writeParameterList(node.positionalParameters, node.namedParameters,
node.requiredParameterCount);
writeSpaced('=');
writeMemberReferenceFromReference(node.targetReference);
writeMemberReferenceFromReference(node.targetReference!);
if (node.typeArguments.isNotEmpty) {
writeSymbol('<');
writeList(node.typeArguments, writeType);
@@ -1246,12 +1266,12 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeTypeParameterList(node.typeParameters);
if (node.isMixinApplication) {
writeSpaced('=');
visitSupertype(node.supertype);
visitSupertype(node.supertype!);
writeSpaced('with');
visitSupertype(node.mixedInType);
visitSupertype(node.mixedInType!);
} else if (node.supertype != null) {
writeSpaced('extends');
visitSupertype(node.supertype);
visitSupertype(node.supertype!);
}
if (node.implementedTypes.isNotEmpty) {
writeSpaced('implements');
@@ -1297,7 +1317,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeWord(getExtensionName(node));
writeTypeParameterList(node.typeParameters);
writeSpaced('on');
writeType(node.onType);
writeType(node.onType!);
String endLineString = ' {';
if (node.enclosingLibrary.fileUri != node.fileUri) {
endLineString += ' // from ${node.fileUri}';
@@ -1352,18 +1372,20 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeWord(node.name);
writeTypeParameterList(node.typeParameters);
writeSpaced('=');
if (node.type is FunctionType) {
writeFunctionType(node.type,
DartType? type = node.type;
if (type is FunctionType) {
writeFunctionType(type,
typedefPositional: node.positionalParameters,
typedefNamed: node.namedParameters);
} else {
writeNode(node.type);
writeNode(type);
}
endLine(';');
}
visitInvalidExpression(InvalidExpression node) {
writeWord('invalid-expression');
// ignore: unnecessary_null_comparison
if (node.message != null) {
writeWord('"${escapeString(node.message)}"');
}
@@ -1415,7 +1437,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeNode(node.arguments);
if (node.functionType != null) {
writeSymbol('{');
writeType(node.functionType);
writeType(node.functionType!);
writeSymbol('}');
}
}
@@ -1530,8 +1552,8 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
visitLogicalExpression(LogicalExpression node) {
int precedence = Precedence
.binaryPrecedence[logicalExpressionOperatorToString(node.operatorEnum)];
int precedence = Precedence.binaryPrecedence[
logicalExpressionOperatorToString(node.operatorEnum)]!;
writeExpression(node.left, precedence);
writeSpaced(logicalExpressionOperatorToString(node.operatorEnum));
writeExpression(node.right, precedence + 1);
@@ -1606,7 +1628,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
if (!first) {
writeComma();
}
writeWord('${fieldRef.asField.name.text}');
writeWord('${fieldRef.asField.name!.text}');
writeSymbol(':');
writeExpression(value);
first = false;
@@ -1617,9 +1639,10 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
write('assert(');
writeExpression(assert_.condition);
if (assert_.message != null) {
Expression? message = assert_.message;
if (message != null) {
writeComma();
writeExpression(assert_.message);
writeExpression(message);
}
write(')');
first = false;
@@ -1692,6 +1715,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeWord('const');
writeSpace();
}
// ignore: unnecessary_null_comparison
if (node.typeArgument != null) {
writeSymbol('<');
writeType(node.typeArgument);
@@ -1707,6 +1731,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeWord('const');
writeSpace();
}
// ignore: unnecessary_null_comparison
if (node.typeArgument != null) {
writeSymbol('<');
writeType(node.typeArgument);
@@ -1722,6 +1747,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeWord('const');
writeSpace();
}
// ignore: unnecessary_null_comparison
if (node.keyType != null) {
writeSymbol('<');
writeList([node.keyType, node.valueType], writeType);
@@ -1791,7 +1817,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
visitLoadLibrary(LoadLibrary node) {
writeWord('LoadLibrary');
writeSymbol('(');
writeWord(node.import.name);
writeWord(node.import.name!);
writeSymbol(')');
state = WORD;
}
@@ -1799,7 +1825,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
writeWord('CheckLibraryIsLoaded');
writeSymbol('(');
writeWord(node.import.name);
writeWord(node.import.name!);
writeSymbol(')');
state = WORD;
}
@@ -1816,20 +1842,21 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeIndentation();
writeWord(node.isImport ? 'import' : 'export');
String uriString;
if (node.importedLibraryReference?.node != null) {
if (node.importedLibraryReference.node != null) {
uriString = '${node.targetLibrary.importUri}';
} else {
uriString = '${node.importedLibraryReference?.canonicalName?.name}';
uriString = '${node.importedLibraryReference.canonicalName?.name}';
}
writeWord('"$uriString"');
if (node.isDeferred) {
writeWord('deferred');
}
if (node.name != null) {
String? name = node.name;
if (name != null) {
writeWord('as');
writeWord(node.name);
writeWord(name);
}
String last;
String? last;
final String show = 'show';
final String hide = 'hide';
if (node.combinators.isNotEmpty) {
@@ -1859,9 +1886,10 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
visitVariableGet(VariableGet node) {
writeVariableReference(node.variable);
if (node.promotedType != null) {
DartType? promotedType = node.promotedType;
if (promotedType != null) {
writeSymbol('{');
writeNode(node.promotedType);
writeNode(promotedType);
writeSymbol('}');
state = WORD;
}
@@ -1873,7 +1901,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeExpression(node.value);
}
void writeInterfaceTarget(Name name, Reference target) {
void writeInterfaceTarget(Name name, Reference? target) {
if (target != null) {
writeSymbol('{');
writeMemberReferenceFromReference(target);
@@ -1884,6 +1912,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
void writeStaticType(DartType type) {
// ignore: unnecessary_null_comparison
if (type != null) {
writeSymbol('{');
writeType(type);
@@ -2024,9 +2053,10 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeWord('assert');
writeSymbol('(');
writeExpression(node.condition);
if (node.message != null) {
Expression? message = node.message;
if (message != null) {
writeComma();
writeExpression(node.message);
writeExpression(message);
}
if (!asExpression) {
endLine(');');
@@ -2075,8 +2105,9 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeSymbol('(');
writeList(node.variables, writeVariableDeclaration);
writeComma(';');
if (node.condition != null) {
writeExpression(node.condition);
Expression? condition = node.condition;
if (condition != null) {
writeExpression(condition);
}
writeComma(';');
writeList(node.updates, writeExpression);
@@ -2146,19 +2177,21 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeExpression(node.condition);
writeSymbol(')');
writeBody(node.then);
if (node.otherwise != null) {
Statement? otherwise = node.otherwise;
if (otherwise != null) {
writeIndentation();
writeWord('else');
writeBody(node.otherwise);
writeBody(otherwise);
}
}
visitReturnStatement(ReturnStatement node) {
writeIndentation();
writeWord('return');
if (node.expression != null) {
Expression? expression = node.expression;
if (expression != null) {
writeSpace();
writeExpression(node.expression);
writeExpression(expression);
}
endLine(';');
}
@@ -2172,6 +2205,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
visitCatch(Catch node) {
writeIndentation();
// ignore: unnecessary_null_comparison
if (node.guard != null) {
writeWord('on');
writeType(node.guard);
@@ -2179,14 +2213,16 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
writeWord('catch');
writeSymbol('(');
if (node.exception != null) {
writeVariableDeclaration(node.exception);
VariableDeclaration? exception = node.exception;
if (exception != null) {
writeVariableDeclaration(exception);
} else {
writeWord('no-exception-var');
}
if (node.stackTrace != null) {
VariableDeclaration? stackTrace = node.stackTrace;
if (stackTrace != null) {
writeComma();
writeVariableDeclaration(node.stackTrace);
writeVariableDeclaration(stackTrace);
}
writeSymbol(')');
writeBody(node.body);
@@ -2225,7 +2261,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeIndentation();
writeWord('function');
if (node.function != null) {
writeFunction(node.function, name: getVariableName(node.variable));
writeFunction(node.function!, name: getVariableName(node.variable));
} else {
writeWord(getVariableName(node.variable));
endLine('...;');
@@ -2244,16 +2280,19 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeModifier(node.isGenericCovariantImpl, 'generic-covariant-impl');
writeModifier(node.isFinal, 'final');
writeModifier(node.isConst, 'const');
// ignore: unnecessary_null_comparison
if (node.type != null) {
writeAnnotatedType(node.type, annotator?.annotateVariable(this, node));
}
// ignore: unnecessary_null_comparison
if (useVarKeyword && !node.isFinal && !node.isConst && node.type == null) {
writeWord('var');
}
writeWord(getVariableName(node));
if (node.initializer != null) {
Expression? initializer = node.initializer;
if (initializer != null) {
writeSpaced('=');
writeExpression(node.initializer);
writeExpression(initializer);
}
}
@@ -2407,14 +2446,15 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
visitTypeParameterType(TypeParameterType node) {
writeTypeParameterReference(node.parameter);
writeNullability(node.declaredNullability);
if (node.promotedBound != null) {
DartType? promotedBound = node.promotedBound;
if (promotedBound != null) {
writeSpaced('&');
writeType(node.promotedBound);
writeType(promotedBound);
writeWord("/* '");
writeNullability(node.declaredNullability, inComment: true);
writeWord("' & '");
writeDartTypeNullability(node.promotedBound, inComment: true);
writeDartTypeNullability(promotedBound, inComment: true);
writeWord("' = '");
writeNullability(node.nullability, inComment: true);
writeWord("' */");
@@ -2434,10 +2474,10 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
}
writeWord(getTypeParameterName(node));
writeSpaced('extends');
writeType(node.bound);
writeType(node.bound!);
if (node.defaultType != null) {
writeSpaced('=');
writeType(node.defaultType);
writeType(node.defaultType!);
}
}
@@ -2488,6 +2528,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeIndentation();
writeConstantReference(node);
writeSpaced('=');
// ignore: unnecessary_null_comparison
String text = node.libraryReference != null
? '#${node.libraryReference.asLibrary.importUri}::${node.name}'
: '#${node.name}';
@@ -2556,9 +2597,9 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeList(node.fieldValues.entries,
(core.MapEntry<Reference, Constant> entry) {
if (entry.key.node != null) {
writeWord('${entry.key.asField.name.text}');
writeWord('${entry.key.asField.name!.text}');
} else {
writeWord('${entry.key.canonicalName.name}');
writeWord('${entry.key.canonicalName!.name}');
}
writeSymbol(':');
writeConstantReference(entry.value);
@@ -2636,7 +2677,7 @@ class Precedence implements ExpressionVisitor<int> {
static const int PRIMARY = 20;
static const int CALLEE = 21;
static const Map<String, int> binaryPrecedence = const {
static const Map<String?, int> binaryPrecedence = const {
'&&': LOGICAL_AND,
'||': LOGICAL_OR,
'??': LOGICAL_NULL_AWARE,
@@ -2708,7 +2749,7 @@ class Precedence implements ExpressionVisitor<int> {
@override
int visitLogicalExpression(LogicalExpression node) =>
binaryPrecedence[logicalExpressionOperatorToString(node.operatorEnum)];
binaryPrecedence[logicalExpressionOperatorToString(node.operatorEnum)]!;
@override
int visitConditionalExpression(ConditionalExpression node) => CONDITIONAL;
@@ -2862,5 +2903,4 @@ String procedureKindToString(ProcedureKind kind) {
case ProcedureKind.Factory:
return 'factory';
}
throw 'illegal ProcedureKind: $kind';
}
+12 -9
View File
@@ -1089,10 +1089,15 @@ YieldStatement wrapYieldStatement(Expression expression) {
}
TextSerializer<AssertStatement> assertStatementSerializer =
Wrapped<Tuple2<Expression, Expression>, AssertStatement>(
(a) => Tuple2(a.condition, a.message),
(t) => AssertStatement(t.first, message: t.second),
Tuple2Serializer(expressionSerializer, Optional(expressionSerializer)));
Wrapped<Tuple4<Expression, Expression, int, int>, AssertStatement>(
(a) => Tuple4(a.condition, a.message, a.conditionStartOffset,
a.conditionEndOffset),
(t) => AssertStatement(t.first,
message: t.second,
conditionStartOffset: t.third,
conditionEndOffset: t.fourth),
Tuple4Serializer(expressionSerializer, Optional(expressionSerializer),
const DartInt(), const DartInt()));
TextSerializer<Block> blockSerializer =
Wrapped<Tuple2<List<Statement>, Expression>, Block>(
@@ -2102,11 +2107,9 @@ TextSerializer<ExtensionMemberDescriptor> extensionMemberDescriptorSerializer =
Wrapped<Tuple4<Name, ExtensionMemberKind, int, CanonicalName>,
ExtensionMemberDescriptor>(
(w) => Tuple4(w.name, w.kind, w.flags, w.member.canonicalName),
(u) => ExtensionMemberDescriptor()
..name = u.first
..kind = u.second
..flags = u.third
..member = u.fourth.getReference(),
(u) => ExtensionMemberDescriptor(
name: u.first, kind: u.second, member: u.fourth.getReference())
..flags = u.third,
Tuple4Serializer(
nameSerializer,
extensionMemberKindSerializer,
+14 -14
View File
@@ -177,7 +177,7 @@ class ExpressionLifter extends Transformer {
// Transform an expression given an action to transform the children. For
// this purposes of the await transformer the children should generally be
// translated from right to left, in the reverse of evaluation order.
Expression transform(Expression expr, void action()) {
Expression transformTreeNode(Expression expr, void action()) {
var shouldName = seenAwait;
// 1. If there is an await in a sibling to the right, emit an assignment to
@@ -208,7 +208,7 @@ class ExpressionLifter extends Transformer {
// Unary expressions.
Expression unary(Expression expr) {
return transform(expr, () {
return transformTreeNode(expr, () {
expr.transformChildren(this);
});
}
@@ -223,7 +223,7 @@ class ExpressionLifter extends Transformer {
TreeNode visitThrow(Throw expr) => unary(expr);
TreeNode visitPropertySet(PropertySet expr) {
return transform(expr, () {
return transformTreeNode(expr, () {
expr.value = expr.value.accept<TreeNode>(this)..parent = expr;
expr.receiver = expr.receiver.accept<TreeNode>(this)..parent = expr;
});
@@ -243,32 +243,32 @@ class ExpressionLifter extends Transformer {
}
TreeNode visitMethodInvocation(MethodInvocation expr) {
return transform(expr, () {
return transformTreeNode(expr, () {
visitArguments(expr.arguments);
expr.receiver = expr.receiver.accept<TreeNode>(this)..parent = expr;
});
}
TreeNode visitSuperMethodInvocation(SuperMethodInvocation expr) {
return transform(expr, () {
return transformTreeNode(expr, () {
visitArguments(expr.arguments);
});
}
TreeNode visitStaticInvocation(StaticInvocation expr) {
return transform(expr, () {
return transformTreeNode(expr, () {
visitArguments(expr.arguments);
});
}
TreeNode visitConstructorInvocation(ConstructorInvocation expr) {
return transform(expr, () {
return transformTreeNode(expr, () {
visitArguments(expr.arguments);
});
}
TreeNode visitStringConcatenation(StringConcatenation expr) {
return transform(expr, () {
return transformTreeNode(expr, () {
var expressions = expr.expressions;
for (var i = expressions.length - 1; i >= 0; --i) {
expressions[i] = expressions[i].accept<TreeNode>(this)..parent = expr;
@@ -277,7 +277,7 @@ class ExpressionLifter extends Transformer {
}
TreeNode visitListLiteral(ListLiteral expr) {
return transform(expr, () {
return transformTreeNode(expr, () {
var expressions = expr.expressions;
for (var i = expressions.length - 1; i >= 0; --i) {
expressions[i] = expr.expressions[i].accept<TreeNode>(this)
@@ -287,7 +287,7 @@ class ExpressionLifter extends Transformer {
}
TreeNode visitMapLiteral(MapLiteral expr) {
return transform(expr, () {
return transformTreeNode(expr, () {
for (var entry in expr.entries.reversed) {
entry.value = entry.value.accept<TreeNode>(this)..parent = entry;
entry.key = entry.key.accept<TreeNode>(this)..parent = entry;
@@ -310,7 +310,7 @@ class ExpressionLifter extends Transformer {
if (rightStatements.isEmpty) {
// Easy case: right did not emit any statements.
seenAwait = shouldName;
return transform(expr, () {
return transformTreeNode(expr, () {
expr.left = expr.left.accept<TreeNode>(this)..parent = expr;
seenAwait = seenAwait || rightAwait;
});
@@ -391,7 +391,7 @@ class ExpressionLifter extends Transformer {
if (thenStatements.isEmpty && otherwiseStatements.isEmpty) {
// Easy case: neither then nor otherwise emitted any statements.
seenAwait = shouldName;
return transform(expr, () {
return transformTreeNode(expr, () {
expr.condition = expr.condition.accept<TreeNode>(this)..parent = expr;
seenAwait = seenAwait || thenAwait || otherwiseAwait;
});
@@ -518,7 +518,7 @@ class ExpressionLifter extends Transformer {
} else {
// The body in `let x = initializer in body` did not contain an await. We
// can leave a let expression.
return transform(expr, () {
return transformTreeNode(expr, () {
// The body has already been translated.
expr.body = body..parent = expr;
variable.initializer = variable.initializer.accept<TreeNode>(this)
@@ -534,7 +534,7 @@ class ExpressionLifter extends Transformer {
}
TreeNode visitBlockExpression(BlockExpression expr) {
return transform(expr, () {
return transformTreeNode(expr, () {
expr.value = expr.value.accept<TreeNode>(this)..parent = expr;
List<Statement> body = <Statement>[];
for (Statement stmt in expr.body.statements.reversed) {
@@ -296,7 +296,7 @@ abstract class ContinuationRewriterBase extends RecursiveContinuationRewriter {
}
++currentCatchDepth;
transformList(node.catches, this, node);
transformList(node.catches, node);
--currentCatchDepth;
return node;
}
@@ -4,7 +4,6 @@
library kernel.transformations.flags;
// ignore: import_of_legacy_library_into_null_safe
import '../ast.dart';
/// Flags summarizing the kinds of AST nodes contained in a given member or
+15 -16
View File
@@ -4,7 +4,6 @@
library kernel.type_algebra;
// ignore: import_of_legacy_library_into_null_safe
import 'ast.dart';
import 'core_types.dart';
import 'src/replacement_visitor.dart';
@@ -41,7 +40,7 @@ Map<TypeParameter, DartType> getUpperBoundSubstitutionMap(Class host) {
result[parameter] = const DynamicType();
}
for (TypeParameter parameter in host.typeParameters) {
result[parameter] = substitute(parameter.bound, result);
result[parameter] = substitute(parameter.bound!, result);
}
return result;
}
@@ -121,9 +120,9 @@ FreshTypeParameters getFreshTypeParameters(List<TypeParameter> typeParameters) {
TypeParameter typeParameter = typeParameters[i];
TypeParameter freshTypeParameter = freshParameters[i];
freshTypeParameter.bound = substitute(typeParameter.bound, map);
freshTypeParameter.bound = substitute(typeParameter.bound!, map);
freshTypeParameter.defaultType = typeParameter.defaultType != null
? substitute(typeParameter.defaultType, map)
? substitute(typeParameter.defaultType!, map)
: null;
freshTypeParameter.variance =
typeParameter.isLegacyCovariant ? null : typeParameter.variance;
@@ -148,7 +147,7 @@ class FreshTypeParameters {
requiredParameterCount: type.requiredParameterCount,
typedefType: type.typedefType == null
? null
: substitute(type.typedefType) as TypedefType);
: substitute(type.typedefType!) as TypedefType);
}
DartType substitute(DartType type) => substitution.substituteType(type);
@@ -250,7 +249,7 @@ abstract class Substitution {
upper[parameter] = const DynamicType();
}
for (TypeParameter parameter in class_.typeParameters) {
upper[parameter] = substitute(parameter.bound, upper);
upper[parameter] = substitute(parameter.bound!, upper);
}
return fromUpperAndLowerBounds(upper, {});
}
@@ -384,9 +383,9 @@ class _InnerTypeSubstitutor extends _TypeSubstitutor {
TypeParameter fresh = new TypeParameter(node.name);
TypeParameterType typeParameterType = substitution[node] =
new TypeParameterType.forAlphaRenaming(node, fresh);
fresh.bound = visit(node.bound);
fresh.bound = visit(node.bound!);
if (node.defaultType != null) {
fresh.defaultType = visit(node.defaultType);
fresh.defaultType = visit(node.defaultType!);
}
// If the bound was changed from substituting the bound we need to update
// implicit nullability to be based on the new bound. If the bound wasn't
@@ -561,7 +560,7 @@ abstract class _TypeSubstitutor extends DartTypeVisitor<DartType> {
DartType returnType = inner.visit(node.returnType);
TypedefType? typedefType = node.typedefType == null
? null
: inner.visit(node.typedefType) as TypedefType;
: inner.visit(node.typedefType!) as TypedefType;
if (this.useCounter == before) return node;
return new FunctionType(positionalParameters, returnType, node.nullability,
namedParameters: namedParameters,
@@ -699,9 +698,9 @@ class _OccurrenceVisitor implements DartTypeVisitor<bool> {
bool handleTypeParameter(TypeParameter node) {
assert(!variables.contains(node));
if (node.bound.accept(this)) return true;
if (node.bound!.accept(this)) return true;
if (node.defaultType == null) return false;
return node.defaultType.accept(this);
return node.defaultType!.accept(this);
}
}
@@ -755,9 +754,9 @@ class _FreeFunctionTypeVariableVisitor implements DartTypeVisitor<bool> {
bool handleTypeParameter(TypeParameter node) {
assert(variables.contains(node));
if (node.bound.accept(this)) return true;
if (node.bound!.accept(this)) return true;
if (node.defaultType == null) return false;
return node.defaultType.accept(this);
return node.defaultType!.accept(this);
}
}
@@ -811,9 +810,9 @@ class _FreeTypeVariableVisitor implements DartTypeVisitor<bool> {
bool handleTypeParameter(TypeParameter node) {
assert(variables.contains(node));
if (node.bound.accept(this)) return true;
if (node.bound!.accept(this)) return true;
if (node.defaultType == null) return false;
return node.defaultType.accept(this);
return node.defaultType!.accept(this);
}
}
@@ -1057,7 +1056,7 @@ class NullabilityAwareTypeVariableEliminator extends ReplacementVisitor {
// - The greatest closure of `S` with respect to `L` is `Function`
if (node.typeParameters.isNotEmpty) {
for (TypeParameter typeParameter in node.typeParameters) {
if (containsTypeVariable(typeParameter.bound, eliminationTargets,
if (containsTypeVariable(typeParameter.bound!, eliminationTargets,
unhandledTypeHandler: unhandledTypeHandler)) {
return getFunctionReplacement(variance);
}
+8 -10
View File
@@ -4,7 +4,6 @@
library kernel.type_environment;
// ignore: import_of_legacy_library_into_null_safe
import 'ast.dart';
import 'class_hierarchy.dart';
import 'core_types.dart';
@@ -115,8 +114,7 @@ abstract class TypeEnvironment extends Types {
DartType _resolveTypeParameterType(DartType type) {
while (type is TypeParameterType) {
TypeParameterType typeParameterType = type;
type =
typeParameterType.promotedBound ?? typeParameterType.parameter.bound;
type = typeParameterType.bound;
}
return type;
}
@@ -148,13 +146,13 @@ abstract class TypeEnvironment extends Types {
bool isSpecialCasedBinaryOperator(Procedure member,
{bool isNonNullableByDefault: false}) {
if (isNonNullableByDefault) {
Class class_ = member.enclosingClass;
Class? class_ = member.enclosingClass;
// TODO(johnniwinther): Do we need to recognize backend implementation
// methods?
if (class_ == coreTypes.intClass ||
class_ == coreTypes.numClass ||
class_ == coreTypes.doubleClass) {
String name = member.name.text;
String name = member.name!.text;
return name == '+' ||
name == '-' ||
name == '*' ||
@@ -162,9 +160,9 @@ abstract class TypeEnvironment extends Types {
name == '%';
}
} else {
Class class_ = member.enclosingClass;
Class? class_ = member.enclosingClass;
if (class_ == coreTypes.intClass || class_ == coreTypes.numClass) {
String name = member.name.text;
String name = member.name!.text;
return name == '+' ||
name == '-' ||
name == '*' ||
@@ -180,9 +178,9 @@ abstract class TypeEnvironment extends Types {
bool isSpecialCasedTernaryOperator(Procedure member,
{bool isNonNullableByDefault: false}) {
if (isNonNullableByDefault) {
Class class_ = member.enclosingClass;
Class? class_ = member.enclosingClass;
if (class_ == coreTypes.intClass || class_ == coreTypes.numClass) {
String name = member.name.text;
String name = member.name!.text;
return name == 'clamp';
}
}
@@ -751,7 +749,7 @@ class _FlatStatefulStaticTypeContext extends StatefulStaticTypeContext {
"No member currently associated with StaticTypeContext.");
return _currentMember?.enclosingClass?.getThisType(
typeEnvironment.coreTypes,
_currentMember?.enclosingLibrary.nonNullable);
_currentMember!.enclosingLibrary.nonNullable);
}
@override
+626 -1
View File
@@ -6,7 +6,6 @@ library kernel.ast.visitor;
import 'dart:collection';
// ignore: import_of_legacy_library_into_null_safe
import 'ast.dart';
abstract class ExpressionVisitor<R> {
@@ -126,6 +125,20 @@ abstract class MemberVisitor<R> {
}
}
abstract class MemberVisitor1<R, A> {
const MemberVisitor1();
R defaultMember(Member node, A arg);
R visitConstructor(Constructor node, A arg) => defaultMember(node, arg);
R visitProcedure(Procedure node, A arg) => defaultMember(node, arg);
R visitField(Field node, A arg) => defaultMember(node, arg);
R visitRedirectingFactoryConstructor(
RedirectingFactoryConstructor node, A arg) {
return defaultMember(node, arg);
}
}
abstract class InitializerVisitor<R> {
const InitializerVisitor();
@@ -141,6 +154,25 @@ abstract class InitializerVisitor<R> {
R visitAssertInitializer(AssertInitializer node) => defaultInitializer(node);
}
abstract class InitializerVisitor1<R, A> {
const InitializerVisitor1();
R defaultInitializer(Initializer node, A arg);
R visitInvalidInitializer(InvalidInitializer node, A arg) =>
defaultInitializer(node, arg);
R visitFieldInitializer(FieldInitializer node, A arg) =>
defaultInitializer(node, arg);
R visitSuperInitializer(SuperInitializer node, A arg) =>
defaultInitializer(node, arg);
R visitRedirectingInitializer(RedirectingInitializer node, A arg) =>
defaultInitializer(node, arg);
R visitLocalInitializer(LocalInitializer node, A arg) =>
defaultInitializer(node, arg);
R visitAssertInitializer(AssertInitializer node, A arg) =>
defaultInitializer(node, arg);
}
abstract class TreeVisitor<R>
implements
ExpressionVisitor<R>,
@@ -287,6 +319,195 @@ abstract class TreeVisitor<R>
R visitComponent(Component node) => defaultTreeNode(node);
}
abstract class TreeVisitor1<R, A>
implements
ExpressionVisitor1<R, A>,
StatementVisitor1<R, A>,
MemberVisitor1<R, A>,
InitializerVisitor1<R, A> {
const TreeVisitor1();
R defaultTreeNode(TreeNode node, A arg);
// Expressions
R defaultExpression(Expression node, A arg) => defaultTreeNode(node, arg);
R defaultBasicLiteral(BasicLiteral node, A arg) =>
defaultExpression(node, arg);
R visitInvalidExpression(InvalidExpression node, A arg) =>
defaultExpression(node, arg);
R visitVariableGet(VariableGet node, A arg) => defaultExpression(node, arg);
R visitVariableSet(VariableSet node, A arg) => defaultExpression(node, arg);
R visitDynamicGet(DynamicGet node, A arg) => defaultExpression(node, arg);
R visitDynamicSet(DynamicSet node, A arg) => defaultExpression(node, arg);
R visitFunctionTearOff(FunctionTearOff node, A arg) =>
defaultExpression(node, arg);
R visitInstanceGet(InstanceGet node, A arg) => defaultExpression(node, arg);
R visitInstanceSet(InstanceSet node, A arg) => defaultExpression(node, arg);
R visitInstanceTearOff(InstanceTearOff node, A arg) =>
defaultExpression(node, arg);
R visitPropertyGet(PropertyGet node, A arg) => defaultExpression(node, arg);
R visitPropertySet(PropertySet node, A arg) => defaultExpression(node, arg);
R visitSuperPropertyGet(SuperPropertyGet node, A arg) =>
defaultExpression(node, arg);
R visitSuperPropertySet(SuperPropertySet node, A arg) =>
defaultExpression(node, arg);
R visitStaticGet(StaticGet node, A arg) => defaultExpression(node, arg);
R visitStaticSet(StaticSet node, A arg) => defaultExpression(node, arg);
R visitStaticTearOff(StaticTearOff node, A arg) =>
defaultExpression(node, arg);
R visitLocalFunctionInvocation(LocalFunctionInvocation node, A arg) =>
defaultExpression(node, arg);
R visitDynamicInvocation(DynamicInvocation node, A arg) =>
defaultExpression(node, arg);
R visitFunctionInvocation(FunctionInvocation node, A arg) =>
defaultExpression(node, arg);
R visitInstanceInvocation(InstanceInvocation node, A arg) =>
defaultExpression(node, arg);
R visitEqualsNull(EqualsNull node, A arg) => defaultExpression(node, arg);
R visitEqualsCall(EqualsCall node, A arg) => defaultExpression(node, arg);
R visitMethodInvocation(MethodInvocation node, A arg) =>
defaultExpression(node, arg);
R visitSuperMethodInvocation(SuperMethodInvocation node, A arg) =>
defaultExpression(node, arg);
R visitStaticInvocation(StaticInvocation node, A arg) =>
defaultExpression(node, arg);
R visitConstructorInvocation(ConstructorInvocation node, A arg) =>
defaultExpression(node, arg);
R visitNot(Not node, A arg) => defaultExpression(node, arg);
R visitNullCheck(NullCheck node, A arg) => defaultExpression(node, arg);
R visitLogicalExpression(LogicalExpression node, A arg) =>
defaultExpression(node, arg);
R visitConditionalExpression(ConditionalExpression node, A arg) =>
defaultExpression(node, arg);
R visitStringConcatenation(StringConcatenation node, A arg) =>
defaultExpression(node, arg);
R visitListConcatenation(ListConcatenation node, A arg) =>
defaultExpression(node, arg);
R visitSetConcatenation(SetConcatenation node, A arg) =>
defaultExpression(node, arg);
R visitMapConcatenation(MapConcatenation node, A arg) =>
defaultExpression(node, arg);
R visitInstanceCreation(InstanceCreation node, A arg) =>
defaultExpression(node, arg);
R visitFileUriExpression(FileUriExpression node, A arg) =>
defaultExpression(node, arg);
R visitIsExpression(IsExpression node, A arg) => defaultExpression(node, arg);
R visitAsExpression(AsExpression node, A arg) => defaultExpression(node, arg);
R visitSymbolLiteral(SymbolLiteral node, A arg) =>
defaultExpression(node, arg);
R visitTypeLiteral(TypeLiteral node, A arg) => defaultExpression(node, arg);
R visitThisExpression(ThisExpression node, A arg) =>
defaultExpression(node, arg);
R visitRethrow(Rethrow node, A arg) => defaultExpression(node, arg);
R visitThrow(Throw node, A arg) => defaultExpression(node, arg);
R visitListLiteral(ListLiteral node, A arg) => defaultExpression(node, arg);
R visitSetLiteral(SetLiteral node, A arg) => defaultExpression(node, arg);
R visitMapLiteral(MapLiteral node, A arg) => defaultExpression(node, arg);
R visitAwaitExpression(AwaitExpression node, A arg) =>
defaultExpression(node, arg);
R visitFunctionExpression(FunctionExpression node, A arg) =>
defaultExpression(node, arg);
R visitConstantExpression(ConstantExpression node, A arg) =>
defaultExpression(node, arg);
R visitStringLiteral(StringLiteral node, A arg) =>
defaultBasicLiteral(node, arg);
R visitIntLiteral(IntLiteral node, A arg) => defaultBasicLiteral(node, arg);
R visitDoubleLiteral(DoubleLiteral node, A arg) =>
defaultBasicLiteral(node, arg);
R visitBoolLiteral(BoolLiteral node, A arg) => defaultBasicLiteral(node, arg);
R visitNullLiteral(NullLiteral node, A arg) => defaultBasicLiteral(node, arg);
R visitLet(Let node, A arg) => defaultExpression(node, arg);
R visitBlockExpression(BlockExpression node, A arg) =>
defaultExpression(node, arg);
R visitInstantiation(Instantiation node, A arg) =>
defaultExpression(node, arg);
R visitLoadLibrary(LoadLibrary node, A arg) => defaultExpression(node, arg);
R visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node, A arg) =>
defaultExpression(node, arg);
// Statements
R defaultStatement(Statement node, A arg) => defaultTreeNode(node, arg);
R visitExpressionStatement(ExpressionStatement node, A arg) =>
defaultStatement(node, arg);
R visitBlock(Block node, A arg) => defaultStatement(node, arg);
R visitAssertBlock(AssertBlock node, A arg) => defaultStatement(node, arg);
R visitEmptyStatement(EmptyStatement node, A arg) =>
defaultStatement(node, arg);
R visitAssertStatement(AssertStatement node, A arg) =>
defaultStatement(node, arg);
R visitLabeledStatement(LabeledStatement node, A arg) =>
defaultStatement(node, arg);
R visitBreakStatement(BreakStatement node, A arg) =>
defaultStatement(node, arg);
R visitWhileStatement(WhileStatement node, A arg) =>
defaultStatement(node, arg);
R visitDoStatement(DoStatement node, A arg) => defaultStatement(node, arg);
R visitForStatement(ForStatement node, A arg) => defaultStatement(node, arg);
R visitForInStatement(ForInStatement node, A arg) =>
defaultStatement(node, arg);
R visitSwitchStatement(SwitchStatement node, A arg) =>
defaultStatement(node, arg);
R visitContinueSwitchStatement(ContinueSwitchStatement node, A arg) =>
defaultStatement(node, arg);
R visitIfStatement(IfStatement node, A arg) => defaultStatement(node, arg);
R visitReturnStatement(ReturnStatement node, A arg) =>
defaultStatement(node, arg);
R visitTryCatch(TryCatch node, A arg) => defaultStatement(node, arg);
R visitTryFinally(TryFinally node, A arg) => defaultStatement(node, arg);
R visitYieldStatement(YieldStatement node, A arg) =>
defaultStatement(node, arg);
R visitVariableDeclaration(VariableDeclaration node, A arg) =>
defaultStatement(node, arg);
R visitFunctionDeclaration(FunctionDeclaration node, A arg) =>
defaultStatement(node, arg);
// Members
R defaultMember(Member node, A arg) => defaultTreeNode(node, arg);
R visitConstructor(Constructor node, A arg) => defaultMember(node, arg);
R visitProcedure(Procedure node, A arg) => defaultMember(node, arg);
R visitField(Field node, A arg) => defaultMember(node, arg);
R visitRedirectingFactoryConstructor(
RedirectingFactoryConstructor node, A arg) {
return defaultMember(node, arg);
}
// Classes
R visitClass(Class node, A arg) => defaultTreeNode(node, arg);
R visitExtension(Extension node, A arg) => defaultTreeNode(node, arg);
// Initializers
R defaultInitializer(Initializer node, A arg) => defaultTreeNode(node, arg);
R visitInvalidInitializer(InvalidInitializer node, A arg) =>
defaultInitializer(node, arg);
R visitFieldInitializer(FieldInitializer node, A arg) =>
defaultInitializer(node, arg);
R visitSuperInitializer(SuperInitializer node, A arg) =>
defaultInitializer(node, arg);
R visitRedirectingInitializer(RedirectingInitializer node, A arg) =>
defaultInitializer(node, arg);
R visitLocalInitializer(LocalInitializer node, A arg) =>
defaultInitializer(node, arg);
R visitAssertInitializer(AssertInitializer node, A arg) =>
defaultInitializer(node, arg);
// Other tree nodes
R visitLibrary(Library node, A arg) => defaultTreeNode(node, arg);
R visitLibraryDependency(LibraryDependency node, A arg) =>
defaultTreeNode(node, arg);
R visitCombinator(Combinator node, A arg) => defaultTreeNode(node, arg);
R visitLibraryPart(LibraryPart node, A arg) => defaultTreeNode(node, arg);
R visitTypedef(Typedef node, A arg) => defaultTreeNode(node, arg);
R visitTypeParameter(TypeParameter node, A arg) => defaultTreeNode(node, arg);
R visitFunctionNode(FunctionNode node, A arg) => defaultTreeNode(node, arg);
R visitArguments(Arguments node, A arg) => defaultTreeNode(node, arg);
R visitNamedExpression(NamedExpression node, A arg) =>
defaultTreeNode(node, arg);
R visitSwitchCase(SwitchCase node, A arg) => defaultTreeNode(node, arg);
R visitCatch(Catch node, A arg) => defaultTreeNode(node, arg);
R visitMapEntry(MapEntry node, A arg) => defaultTreeNode(node, arg);
R visitComponent(Component node, A arg) => defaultTreeNode(node, arg);
}
abstract class DartTypeVisitor<R> {
const DartTypeVisitor();
@@ -775,6 +996,54 @@ class RecursiveResultVisitor<R> extends Visitor<R?> with VisitorNullMixin<R> {
class Transformer extends TreeVisitor<TreeNode> {
const Transformer();
T transform<T extends TreeNode>(T node) {
T result = node.accept<TreeNode>(this) as T;
assert(
// ignore: unnecessary_null_comparison
result != null,
'Attempting to remove ${node} (${node.runtimeType}) '
'in transformer.');
return result;
}
void transformDartTypeList(List<DartType> nodes) {
for (int i = 0; i < nodes.length; ++i) {
DartType result = visitDartType(nodes[i]);
assert(
// ignore: unnecessary_null_comparison
result != null,
'Attempting to remove ${nodes[i]} (${nodes[i].runtimeType}) '
'in transformer.');
nodes[i] = result;
}
}
void transformSupertypeList(List<Supertype> nodes) {
for (int i = 0; i < nodes.length; ++i) {
Supertype result = visitSupertype(nodes[i]);
assert(
// ignore: unnecessary_null_comparison
result != null,
'Attempting to remove ${nodes[i]} (${nodes[i].runtimeType}) '
'in transformer.');
nodes[i] = result;
}
}
void transformList<T extends TreeNode>(List<T> nodes, TreeNode parent) {
for (int i = 0; i < nodes.length; ++i) {
T result = transform(nodes[i]);
assert(
// ignore: unnecessary_null_comparison
result != null,
'Attempting to remove ${nodes[i]} (${nodes[i].runtimeType}) '
'in transformer.');
// ignore: invalid_null_aware_operator
result.parent = parent;
nodes[i] = result;
}
}
/// Replaces a use of a type.
///
/// By default, recursion stops at this point.
@@ -790,6 +1059,362 @@ class Transformer extends TreeVisitor<TreeNode> {
}
}
/// Transformer that recursively rewrites each node in tree and supports removal
/// of nodes.
///
/// Visit methods should return a new node, the visited node (possibly
/// mutated), any node from the visited node's subtree, or the provided
/// removal sentinel, if non-null.
///
/// To support removal of nodes during traversal, while enforcing nullability
/// invariants, this visitor takes an argument, the removal sentinel. If a
/// node is visited in a context where it can be removed, for instance in a
/// list or as an optional child of its parent, a non-null sentinel value is
/// provided, and this value can be returned to signal to the caller that the
/// visited node should be removed. If the sentinel value is `null`, the node
/// cannot be removed from its context, in which case the node itself or a new
/// non-null node must be returned, possibly a sentinel value specific to the
/// particular visitor.
///
/// For instance
///
/// class AssertRemover extends RemovingTransformer {
/// @override
/// TreeNode visitAssertStatement(
/// AssertStatement node,
/// TreeNode? removalSentinel) {
/// return removalSentinel ?? new EmptyStatement();
/// }
///
/// @override
/// TreeNode visitIfStatement(
/// IfStatement node,
/// TreeNode? removalSentinel) {
/// node.transformOrRemoveChildren(this);
/// if (node.then is EmptyStatement) {
/// if (node.otherwise != null) {
/// return new IfStatement(
/// new Not(node.condition), node.otherwise);
/// } else {
/// return removalSentinel ?? new EmptyStatement();
/// }
/// }
/// return node;
/// }
/// }
///
/// Each subclass is responsible for ensuring that the AST remains a tree.
///
/// For example, the following transformer replaces every occurrence of
/// `!(x && y)` with `(!x || !y)`:
///
/// class NegationSinker extends RemovingTransformer {
/// @override
/// Node visitNot(Not node) {
/// var operand = node.operand.accept(this); // Remember to visit.
/// if (operand is LogicalExpression && operand.operator == '&&') {
/// return new LogicalExpression(
/// new Not(operand.left),
/// '||',
/// new Not(operand.right));
/// }
/// return node;
/// }
/// }
///
class RemovingTransformer extends TreeVisitor1<TreeNode, TreeNode?> {
const RemovingTransformer();
/// Visits [node], returning the transformation result.
///
/// The transformation cannot result in `null`.
T transform<T extends TreeNode>(T node) {
return node.accept1<TreeNode, TreeNode?>(this, cannotRemoveSentinel) as T;
}
/// Visits [node], returning the transformation result. Removal of [node] is
/// supported with `null` as the result.
///
/// This is convenience method for calling [transformOrRemove] with removal
/// sentinel for [Expression] nodes.
Expression? transformOrRemoveExpression(Expression node) {
return transformOrRemove(node, dummyExpression);
}
/// Visits [node], returning the transformation result. Removal of [node] is
/// supported with `null` as the result.
///
/// This is convenience method for calling [transformOrRemove] with removal
/// sentinel for [Statement] nodes.
Statement? transformOrRemoveStatement(Statement node) {
return transformOrRemove(node, dummyStatement);
}
/// Visits [node], returning the transformation result. Removal of [node] is
/// supported with `null` as the result.
///
/// This is convenience method for calling [transformOrRemove] with removal
/// sentinel for [VariableDeclaration] nodes.
VariableDeclaration? transformOrRemoveVariableDeclaration(
VariableDeclaration node) {
return transformOrRemove(node, dummyVariableDeclaration);
}
/// Visits [node] using [removalSentinel] as the removal sentinel.
///
/// If [removalSentinel] is the result of visiting [node], `null` is returned.
/// Otherwise the result is returned.
T? transformOrRemove<T extends TreeNode>(T node, T? removalSentinel) {
T result = node.accept1<TreeNode, TreeNode?>(this, removalSentinel) as T;
if (identical(result, removalSentinel)) {
return null;
} else {
return result;
}
}
/// Transforms or removes [DartType] nodes in [nodes].
void transformDartTypeList(List<DartType> nodes) {
int storeIndex = 0;
for (int i = 0; i < nodes.length; ++i) {
DartType result = visitDartType(nodes[i], dummyDartType);
if (!identical(result, dummyDartType)) {
nodes[storeIndex] = result;
++storeIndex;
}
}
if (storeIndex < nodes.length) {
nodes.length = storeIndex;
}
}
/// Transforms or removes [Supertype] nodes in [nodes].
void transformSupertypeList(List<Supertype> nodes) {
int storeIndex = 0;
for (int i = 0; i < nodes.length; ++i) {
Supertype result = visitSupertype(nodes[i], dummySupertype);
if (!identical(result, dummySupertype)) {
nodes[storeIndex] = result;
++storeIndex;
}
}
if (storeIndex < nodes.length) {
nodes.length = storeIndex;
}
}
/// Transforms or removes [Library] nodes in [nodes] as children of [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [Library] nodes.
void transformLibraryList(List<Library> nodes, TreeNode parent) {
transformList(nodes, parent, dummyLibrary);
}
/// Transforms or removes [LibraryDependency] nodes in [nodes] as children of
/// [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [LibraryDependency] nodes.
void transformLibraryDependencyList(
List<LibraryDependency> nodes, TreeNode parent) {
transformList(nodes, parent, dummyLibraryDependency);
}
/// Transforms or removes [Combinator] nodes in [nodes] as children of
/// [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [Combinator] nodes.
void transformCombinatorList(List<Combinator> nodes, TreeNode parent) {
transformList(nodes, parent, dummyCombinator);
}
/// Transforms or removes [LibraryPart] nodes in [nodes] as children of
/// [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [LibraryPart] nodes.
void transformLibraryPartList(List<LibraryPart> nodes, TreeNode parent) {
transformList(nodes, parent, dummyLibraryPart);
}
/// Transforms or removes [Class] nodes in [nodes] as children of [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [Class] nodes.
void transformClassList(List<Class> nodes, TreeNode parent) {
transformList(nodes, parent, dummyClass);
}
/// Transforms or removes [Extension] nodes in [nodes] as children of
/// [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [Extension] nodes.
void transformExtensionList(List<Extension> nodes, TreeNode parent) {
transformList(nodes, parent, dummyExtension);
}
/// Transforms or removes [Constructor] nodes in [nodes] as children of
/// [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [Constructor] nodes.
void transformConstructorList(List<Constructor> nodes, TreeNode parent) {
transformList(nodes, parent, dummyConstructor);
}
/// Transforms or removes [Procedure] nodes in [nodes] as children of
/// [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [Procedure] nodes.
void transformProcedureList(List<Procedure> nodes, TreeNode parent) {
transformList(nodes, parent, dummyProcedure);
}
/// Transforms or removes [Field] nodes in [nodes] as children of [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [Field] nodes.
void transformFieldList(List<Field> nodes, TreeNode parent) {
transformList(nodes, parent, dummyField);
}
/// Transforms or removes [RedirectingFactoryConstructor] nodes in [nodes] as
/// children of [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [RedirectingFactoryConstructor] nodes.
void transformRedirectingFactoryConstructorList(
List<RedirectingFactoryConstructor> nodes, TreeNode parent) {
transformList(nodes, parent, dummyRedirectingFactoryConstructor);
}
/// Transforms or removes [Typedef] nodes in [nodes] as children of [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [Typedef] nodes.
void transformTypedefList(List<Typedef> nodes, TreeNode parent) {
transformList(nodes, parent, dummyTypedef);
}
/// Transforms or removes [Initializer] nodes in [nodes] as children of
/// [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [Initializer] nodes.
void transformInitializerList(List<Initializer> nodes, TreeNode parent) {
transformList(nodes, parent, dummyInitializer);
}
/// Transforms or removes [Expression] nodes in [nodes] as children of
/// [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [Expression] nodes.
void transformExpressionList(List<Expression> nodes, TreeNode parent) {
transformList(nodes, parent, dummyExpression);
}
/// Transforms or removes [NamedExpression] nodes in [nodes] as children of
/// [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [NamedExpression] nodes.
void transformNamedExpressionList(
List<NamedExpression> nodes, TreeNode parent) {
transformList(nodes, parent, dummyNamedExpression);
}
/// Transforms or removes [MapEntry] nodes in [nodes] as children of [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [MapEntry] nodes.
void transformMapEntryList(List<MapEntry> nodes, TreeNode parent) {
transformList(nodes, parent, dummyMapEntry);
}
/// Transforms or removes [Statement] nodes in [nodes] as children of
/// [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [Statement] nodes.
void transformStatementList(List<Statement> nodes, TreeNode parent) {
transformList(nodes, parent, dummyStatement);
}
/// Transforms or removes [SwitchCase] nodes in [nodes] as children of
/// [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [SwitchCase] nodes.
void transformSwitchCaseList(List<SwitchCase> nodes, TreeNode parent) {
transformList(nodes, parent, dummySwitchCase);
}
/// Transforms or removes [Catch] nodes in [nodes] as children of [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [Catch] nodes.
void transformCatchList(List<Catch> nodes, TreeNode parent) {
transformList(nodes, parent, dummyCatch);
}
/// Transforms or removes [TypeParameter] nodes in [nodes] as children of
/// [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [TypeParameter] nodes.
void transformTypeParameterList(List<TypeParameter> nodes, TreeNode parent) {
transformList(nodes, parent, dummyTypeParameter);
}
/// Transforms or removes [VariableDeclaration] nodes in [nodes] as children
/// of [parent].
///
/// This is convenience method for calling [transformList] with removal
/// sentinel for [VariableDeclaration] nodes.
void transformVariableDeclarationList(
List<VariableDeclaration> nodes, TreeNode parent) {
transformList(nodes, parent, dummyVariableDeclaration);
}
/// Transforms or removes [T] nodes in [nodes] as children of [parent] by
/// calling [transformOrRemove] using [removalSentinel] as the removal
/// sentinel.
void transformList<T extends TreeNode>(
List<T> nodes, TreeNode parent, T removalSentinel) {
int storeIndex = 0;
for (int i = 0; i < nodes.length; ++i) {
T? result = transformOrRemove(nodes[i], removalSentinel);
if (result != null) {
nodes[storeIndex] = result;
result.parent = parent;
++storeIndex;
}
}
if (storeIndex < nodes.length) {
nodes.length = storeIndex;
}
}
/// Replaces a use of a type.
///
/// By default, recursion stops at this point.
DartType visitDartType(DartType node, DartType? removalSentinel) => node;
Constant visitConstant(Constant node, Constant? removalSentinel) => node;
Supertype visitSupertype(Supertype node, Supertype? removalSentinel) => node;
TreeNode defaultTreeNode(TreeNode node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
return node;
}
}
abstract class ExpressionVisitor1<R, T> {
const ExpressionVisitor1();
+1 -22
View File
@@ -227,7 +227,7 @@ main() {
negative1Test(
'Dangling interface type',
(TestHarness test) {
Class orphan = new Class();
Class orphan = new Class(name: 'Class');
test.addNode(
new TypeLiteral(new InterfaceType(orphan, Nullability.legacy)));
return orphan;
@@ -264,27 +264,6 @@ main() {
test.addNode(procedure);
},
);
simpleNegativeTest(
'StaticGet without target',
"StaticGet without target.",
(TestHarness test) {
test.addNode(StaticGet(null));
},
);
simpleNegativeTest(
'StaticSet without target',
"StaticSet without target.",
(TestHarness test) {
test.addNode(StaticSet(null, new NullLiteral()));
},
);
simpleNegativeTest(
'StaticInvocation without target',
"StaticInvocation without target.",
(TestHarness test) {
test.addNode(StaticInvocation(null, new Arguments.empty()));
},
);
positiveTest(
'Correct StaticInvocation',
(TestHarness test) {
@@ -2,6 +2,8 @@
// 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.12
library vm.transformations.mixin_deduplication;
import 'package:kernel/ast.dart';
@@ -13,7 +15,8 @@ void transformComponent(Component component) {
// Deduplicate mixins and re-resolve super initializers.
// (this is a shallow transformation)
component.libraries.forEach(deduplicateMixins.visitLibrary);
component.libraries
.forEach((library) => deduplicateMixins.visitLibrary(library, null));
// Do a deep transformation to update references to the removed mixin
// application classes in the interface targets and types.
@@ -83,29 +86,30 @@ class _DeduplicateMixinKey {
}
}
class DeduplicateMixinsTransformer extends Transformer {
class DeduplicateMixinsTransformer extends RemovingTransformer {
final _canonicalMixins = new Map<_DeduplicateMixinKey, Class>();
final _duplicatedMixins = new Map<Class, Class>();
@override
TreeNode visitLibrary(Library node) {
transformList(node.classes, this, node);
TreeNode visitLibrary(Library node, TreeNode? removalSentinel) {
transformClassList(node.classes, node);
return node;
}
@override
TreeNode visitClass(Class c) {
TreeNode visitClass(Class c, TreeNode? removalSentinel) {
if (_duplicatedMixins.containsKey(c)) {
return null; // Class was de-duplicated already, just remove it.
// Class was de-duplicated already, just remove it.
return removalSentinel!;
}
if (c.supertype != null) {
c.supertype = _transformSupertype(c.supertype, c, true);
c.supertype = _transformSupertype(c.supertype!, c, true);
}
if (c.mixedInType != null) {
throw 'All mixins should be transformed already.';
}
transformSupertypeList(c.implementedTypes, this);
transformSupertypeList(c.implementedTypes);
if (!c.isAnonymousMixin) {
return c;
@@ -113,6 +117,7 @@ class DeduplicateMixinsTransformer extends Transformer {
Class canonical =
_canonicalMixins.putIfAbsent(new _DeduplicateMixinKey(c), () => c);
// ignore: unnecessary_null_comparison
assert(canonical != null);
if (canonical != c) {
@@ -120,34 +125,34 @@ class DeduplicateMixinsTransformer extends Transformer {
// write a dangling reference to the deleted class.
c.reference.canonicalName = null;
_duplicatedMixins[c] = canonical;
return null; // Remove class.
// Remove class.
return removalSentinel!;
}
return c;
}
@override
Supertype visitSupertype(Supertype node) {
Supertype visitSupertype(Supertype node, Supertype? removalSentinel) {
return _transformSupertype(node, null, false);
}
Supertype _transformSupertype(
Supertype supertype, Class cls, bool isSuperclass) {
Supertype supertype, Class? cls, bool isSuperclass) {
Class oldSuper = supertype.classNode;
Class newSuper = visitClass(oldSuper);
if (newSuper == null) {
Class canonicalSuper = _duplicatedMixins[oldSuper];
assert(canonicalSuper != null);
Class newSuper = visitClass(oldSuper, dummyClass) as Class;
if (identical(newSuper, dummyClass)) {
Class canonicalSuper = _duplicatedMixins[oldSuper]!;
supertype = new Supertype(canonicalSuper, supertype.typeArguments);
if (isSuperclass) {
_correctForwardingConstructors(cls, oldSuper, canonicalSuper);
_correctForwardingConstructors(cls!, oldSuper, canonicalSuper);
}
}
return supertype;
}
@override
TreeNode defaultTreeNode(TreeNode node) =>
TreeNode defaultTreeNode(TreeNode node, TreeNode? removalSentinel) =>
throw 'Unexpected node ${node.runtimeType}: $node';
}
@@ -204,17 +209,18 @@ class ReferenceUpdater extends RecursiveVisitor {
@override
visitSuperMethodInvocation(SuperMethodInvocation node) {
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
node.interfaceTarget =
_resolveNewInterfaceTarget(node.interfaceTarget) as Procedure?;
super.visitSuperMethodInvocation(node);
}
Member _resolveNewInterfaceTarget(Member m) {
final Class c = m?.enclosingClass;
Member? _resolveNewInterfaceTarget(Member? m) {
final Class? c = m?.enclosingClass;
if (c != null && c.isAnonymousMixin) {
final Class replacement = transformer._duplicatedMixins[c];
final Class? replacement = transformer._duplicatedMixins[c];
if (replacement != null) {
// The class got removed, so we need to re-resolve the interface target.
return _findMember(replacement, m);
return _findMember(replacement, m!);
}
}
return m;
@@ -240,8 +246,8 @@ class ReferenceUpdater extends RecursiveVisitor {
Reference _updateClassReference(Reference classRef) {
final Class c = classRef.asClass;
if (c != null && c.isAnonymousMixin) {
final Class replacement = transformer._duplicatedMixins[c];
if (c.isAnonymousMixin) {
final Class? replacement = transformer._duplicatedMixins[c];
if (replacement != null) {
return replacement.reference;
}
@@ -279,7 +285,7 @@ void _correctForwardingConstructors(Class c, Class oldSuper, Class newSuper) {
for (var initializer in constructor.initializers) {
if ((initializer is SuperInitializer) &&
initializer.target.enclosingClass == oldSuper) {
Constructor replacement = null;
Constructor? replacement = null;
for (var c in newSuper.constructors) {
if (c.name == initializer.target.name) {
replacement = c;
@@ -523,8 +523,8 @@ class TreeShaker {
}
transformComponent(Component component) {
_pass1.transform(component);
_pass2.transform(component);
_pass1.transformComponent(component);
_pass2.transformComponent(component);
}
bool isClassReferencedFromNativeCode(Class c) =>
@@ -563,8 +563,8 @@ class TreeShaker {
}
_usedClasses.add(c);
visitIterable(c.supers, typeVisitor);
transformList(c.typeParameters, _pass1, c);
transformList(c.annotations, _pass1, c);
_pass1.transformTypeParameterList(c.typeParameters, c);
_pass1.transformExpressionList(c.annotations, c);
// Preserve NSM forwarders. They are overlooked by TFA / tree shaker
// as they are abstract and don't have a body.
for (Procedure p in c.procedures) {
@@ -615,13 +615,14 @@ class TreeShaker {
}
if (func != null) {
transformList(func.typeParameters, _pass1, func);
transformList(func.positionalParameters, _pass1, func);
transformList(func.namedParameters, _pass1, func);
_pass1.transformTypeParameterList(func.typeParameters, func);
_pass1.transformVariableDeclarationList(
func.positionalParameters, func);
_pass1.transformVariableDeclarationList(func.namedParameters, func);
func.returnType.accept(typeVisitor);
}
transformList(m.annotations, _pass1, m);
_pass1.transformExpressionList(m.annotations, m);
// If the member is kept alive we need to keep the extension alive.
if (m.isExtensionMember) {
@@ -641,18 +642,20 @@ class TreeShaker {
void addUsedExtension(Extension node) {
if (_usedExtensions.add(node)) {
transformList(node.typeParameters, _pass1, node);
_pass1.transformTypeParameterList(node.typeParameters, node);
node.onType?.accept(typeVisitor);
}
}
void addUsedTypedef(Typedef typedef) {
if (_usedTypedefs.add(typedef)) {
transformList(typedef.annotations, _pass1, typedef);
transformList(typedef.typeParameters, _pass1, typedef);
transformList(typedef.typeParametersOfFunctionType, _pass1, typedef);
transformList(typedef.positionalParameters, _pass1, typedef);
transformList(typedef.namedParameters, _pass1, typedef);
_pass1.transformExpressionList(typedef.annotations, typedef);
_pass1.transformTypeParameterList(typedef.typeParameters, typedef);
_pass1.transformTypeParameterList(
typedef.typeParametersOfFunctionType, typedef);
_pass1.transformVariableDeclarationList(
typedef.positionalParameters, typedef);
_pass1.transformVariableDeclarationList(typedef.namedParameters, typedef);
typedef.type?.accept(typeVisitor);
}
}
@@ -786,7 +789,7 @@ class _TreeShakerTypeVisitor extends RecursiveVisitor {
/// Visits all classes, members and bodies of reachable members.
/// Collects all used classes, members and types, and
/// transforms unreachable calls into 'throw' expressions.
class _TreeShakerPass1 extends Transformer {
class _TreeShakerPass1 extends RemovingTransformer {
final TreeShaker shaker;
final FieldMorpher fieldMorpher;
final TypeEnvironment environment;
@@ -808,8 +811,8 @@ class _TreeShakerPass1 extends Transformer {
: fieldMorpher = shaker.fieldMorpher,
environment = shaker.typeFlowAnalysis.environment;
void transform(Component component) {
component.transformChildren(this);
void transformComponent(Component component) {
component.transformOrRemoveChildren(this);
}
bool _isUnreachable(TreeNode node) {
@@ -870,61 +873,62 @@ class _TreeShakerPass1 extends Transformer {
NarrowNotNull _getNullTest(TreeNode node) =>
shaker.typeFlowAnalysis.nullTest(node);
TreeNode _visitAssertNode(TreeNode node) {
TreeNode _visitAssertNode(TreeNode node, TreeNode removalSentinel) {
if (kRemoveAsserts) {
return null;
return removalSentinel;
} else {
node.transformChildren(this);
node.transformOrRemoveChildren(this);
return node;
}
}
@override
DartType visitDartType(DartType node) {
DartType visitDartType(DartType node, DartType removalSentinel) {
node.accept(shaker.typeVisitor);
return node;
}
@override
Supertype visitSupertype(Supertype node) {
Supertype visitSupertype(Supertype node, Supertype removalSentinel) {
node.accept(shaker.typeVisitor);
return node;
}
@override
TreeNode visitTypedef(Typedef node) {
TreeNode visitTypedef(Typedef node, TreeNode removalSentinel) {
return node; // Do not go deeper.
}
@override
Extension visitExtension(Extension node) {
Extension visitExtension(Extension node, TreeNode removalSentinel) {
// The extension can be considered a weak node, we'll only retain it if
// normal code references any of it's members.
return node;
}
@override
TreeNode visitClass(Class node) {
TreeNode visitClass(Class node, TreeNode removalSentinel) {
if (shaker.isClassAllocated(node) ||
shaker.isClassReferencedFromNativeCode(node)) {
shaker.addClassUsedInType(node);
}
transformList(node.constructors, this, node);
transformList(node.procedures, this, node);
transformList(node.fields, this, node);
transformList(node.redirectingFactoryConstructors, this, node);
transformConstructorList(node.constructors, node);
transformProcedureList(node.procedures, node);
transformFieldList(node.fields, node);
transformRedirectingFactoryConstructorList(
node.redirectingFactoryConstructors, node);
return node;
}
@override
TreeNode defaultMember(Member node) {
TreeNode defaultMember(Member node, TreeNode removalSentinel) {
currentMember = node;
if (shaker.isMemberBodyReachable(node)) {
if (kPrintTrace) {
tracePrint("Visiting $node");
}
shaker.addUsedMember(node);
node.transformChildren(this);
node.transformOrRemoveChildren(this);
} else if (shaker.isMemberReferencedFromNativeCode(node)) {
// Preserve members referenced from native code to satisfy lookups, even
// if they are not reachable. An instance member could be added via
@@ -937,7 +941,7 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitField(Field node) {
TreeNode visitField(Field node, TreeNode removalSentinel) {
currentMember = node;
if (shaker.retainField(node)) {
if (kPrintTrace) {
@@ -946,7 +950,7 @@ class _TreeShakerPass1 extends Transformer {
shaker.addUsedMember(node);
if (node.initializer != null) {
if (shaker.isFieldInitializerReachable(node)) {
node.transformChildren(this);
node.transformOrRemoveChildren(this);
} else {
node.initializer = _makeUnreachableCall([])..parent = node;
}
@@ -961,8 +965,9 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitMethodInvocation(MethodInvocation node) {
node.transformChildren(this);
TreeNode visitMethodInvocation(
MethodInvocation node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(
_flattenArguments(node.arguments, receiver: node.receiver));
@@ -984,8 +989,8 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitPropertyGet(PropertyGet node) {
node.transformChildren(this);
TreeNode visitPropertyGet(PropertyGet node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver]);
} else {
@@ -999,8 +1004,8 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitPropertySet(PropertySet node) {
node.transformChildren(this);
TreeNode visitPropertySet(PropertySet node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver, node.value]);
} else {
@@ -1014,8 +1019,9 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitSuperMethodInvocation(SuperMethodInvocation node) {
node.transformChildren(this);
TreeNode visitSuperMethodInvocation(
SuperMethodInvocation node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(_flattenArguments(node.arguments));
} else {
@@ -1029,8 +1035,9 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitSuperPropertyGet(SuperPropertyGet node) {
node.transformChildren(this);
TreeNode visitSuperPropertyGet(
SuperPropertyGet node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([]);
} else {
@@ -1044,8 +1051,9 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitSuperPropertySet(SuperPropertySet node) {
node.transformChildren(this);
TreeNode visitSuperPropertySet(
SuperPropertySet node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.value]);
} else {
@@ -1059,8 +1067,9 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitStaticInvocation(StaticInvocation node) {
node.transformChildren(this);
TreeNode visitStaticInvocation(
StaticInvocation node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(_flattenArguments(node.arguments));
}
@@ -1073,8 +1082,8 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitStaticGet(StaticGet node) {
node.transformChildren(this);
TreeNode visitStaticGet(StaticGet node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([]);
} else {
@@ -1088,14 +1097,14 @@ class _TreeShakerPass1 extends Transformer {
}
@override
Constant visitConstant(Constant node) {
Constant visitConstant(Constant node, Constant removalSentinel) {
shaker.constantVisitor.analyzeConstant(node);
return node;
}
@override
TreeNode visitStaticSet(StaticSet node) {
node.transformChildren(this);
TreeNode visitStaticSet(StaticSet node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.value]);
} else {
@@ -1110,8 +1119,9 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitConstructorInvocation(ConstructorInvocation node) {
node.transformChildren(this);
TreeNode visitConstructorInvocation(
ConstructorInvocation node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(_flattenArguments(node.arguments));
} else {
@@ -1125,8 +1135,9 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitRedirectingInitializer(RedirectingInitializer node) {
node.transformChildren(this);
TreeNode visitRedirectingInitializer(
RedirectingInitializer node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableInitializer(_flattenArguments(node.arguments));
} else {
@@ -1137,8 +1148,9 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitSuperInitializer(SuperInitializer node) {
node.transformChildren(this);
TreeNode visitSuperInitializer(
SuperInitializer node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableInitializer(_flattenArguments(node.arguments));
} else {
@@ -1148,8 +1160,9 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitFieldInitializer(FieldInitializer node) {
node.transformChildren(this);
TreeNode visitFieldInitializer(
FieldInitializer node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableInitializer([node.value]);
} else {
@@ -1160,7 +1173,7 @@ class _TreeShakerPass1 extends Transformer {
return LocalInitializer(
VariableDeclaration(null, initializer: node.value));
} else {
return null;
return removalSentinel;
}
}
return node;
@@ -1168,23 +1181,25 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitAssertStatement(AssertStatement node) {
return _visitAssertNode(node);
TreeNode visitAssertStatement(
AssertStatement node, TreeNode removalSentinel) {
return _visitAssertNode(node, removalSentinel);
}
@override
TreeNode visitAssertBlock(AssertBlock node) {
return _visitAssertNode(node);
TreeNode visitAssertBlock(AssertBlock node, TreeNode removalSentinel) {
return _visitAssertNode(node, removalSentinel);
}
@override
TreeNode visitAssertInitializer(AssertInitializer node) {
return _visitAssertNode(node);
TreeNode visitAssertInitializer(
AssertInitializer node, TreeNode removalSentinel) {
return _visitAssertNode(node, removalSentinel);
}
@override
TreeNode visitAsExpression(AsExpression node) {
node.transformChildren(this);
TreeNode visitAsExpression(AsExpression node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
TypeCheck check = shaker.typeFlowAnalysis.explicitCast(node);
if (check != null && check.canAlwaysSkip) {
return StaticInvocation(
@@ -1195,8 +1210,8 @@ class _TreeShakerPass1 extends Transformer {
}
@override
TreeNode visitNullCheck(NullCheck node) {
node.transformChildren(this);
TreeNode visitNullCheck(NullCheck node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
final nullTest = _getNullTest(node);
if (nullTest.isAlwaysNotNull) {
return StaticInvocation(
@@ -1221,13 +1236,13 @@ class _TreeShakerPass1 extends Transformer {
/// This pass visits classes and members and removes unused classes and members.
/// Bodies of unreachable but used members are replaced with 'throw'
/// expressions. This pass does not dive deeper than member level.
class _TreeShakerPass2 extends Transformer {
class _TreeShakerPass2 extends RemovingTransformer {
final TreeShaker shaker;
_TreeShakerPass2(this.shaker);
void transform(Component component) {
component.transformChildren(this);
void transformComponent(Component component) {
component.transformOrRemoveChildren(this);
for (Source source in component.uriToSource.values) {
source?.constantCoverageConstructors?.removeWhere((Reference reference) {
Member node = reference.asMember;
@@ -1237,8 +1252,8 @@ class _TreeShakerPass2 extends Transformer {
}
@override
TreeNode visitLibrary(Library node) {
node.transformChildren(this);
TreeNode visitLibrary(Library node, TreeNode removalSentinel) {
node.transformOrRemoveChildren(this);
// The transformer API does not iterate over `Library.additionalExports`,
// so we manually delete the references to shaken nodes.
node.additionalExports.removeWhere((Reference reference) {
@@ -1257,19 +1272,19 @@ class _TreeShakerPass2 extends Transformer {
}
@override
Typedef visitTypedef(Typedef node) {
return shaker.isTypedefUsed(node) ? node : null;
Typedef visitTypedef(Typedef node, TreeNode removalSentinel) {
return shaker.isTypedefUsed(node) ? node : removalSentinel;
}
@override
Class visitClass(Class node) {
Class visitClass(Class node, TreeNode removalSentinel) {
if (!shaker.isClassUsed(node)) {
debugPrint('Dropped class ${node.name}');
// Ensure that kernel file writer will not be able to
// write a dangling reference to the deleted class.
node.reference.canonicalName = null;
Statistics.classesDropped++;
return null; // Remove the class.
return removalSentinel; // Remove the class.
}
if (!shaker.isClassUsedInType(node)) {
@@ -1292,7 +1307,7 @@ class _TreeShakerPass2 extends Transformer {
node.isAbstract = true;
}
node.transformChildren(this);
node.transformOrRemoveChildren(this);
return node;
}
@@ -1305,13 +1320,13 @@ class _TreeShakerPass2 extends Transformer {
node.enclosingClass.isEnum;
@override
Member defaultMember(Member node) {
Member defaultMember(Member node, TreeNode removalSentinel) {
if (!shaker.isMemberUsed(node) && !_preserveSpecialMember(node)) {
// Ensure that kernel file writer will not be able to
// write a dangling reference to the deleted member.
node.reference.canonicalName = null;
Statistics.membersDropped++;
return null;
return removalSentinel;
}
if (!shaker.isMemberBodyReachable(node)) {
@@ -1358,7 +1373,7 @@ class _TreeShakerPass2 extends Transformer {
}
@override
Extension visitExtension(Extension node) {
Extension visitExtension(Extension node, TreeNode removalSentinel) {
if (shaker.isExtensionUsed(node)) {
int writeIndex = 0;
for (int i = 0; i < node.members.length; ++i) {
@@ -1379,7 +1394,7 @@ class _TreeShakerPass2 extends Transformer {
assert(node.members.length > 0);
return node;
}
return null;
return removalSentinel;
}
void _makeUnreachableBody(FunctionNode function) {
@@ -1391,7 +1406,7 @@ class _TreeShakerPass2 extends Transformer {
}
@override
TreeNode defaultTreeNode(TreeNode node) {
TreeNode defaultTreeNode(TreeNode node, TreeNode removalSentinel) {
return node; // Do not traverse into other nodes.
}
}
@@ -2,17 +2,20 @@
// 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.12
import 'package:kernel/ast.dart';
/// Simple unreachable code elimination: removes asserts and if statements
/// with constant conditions. Does a very limited constant folding of
/// logical expressions.
Component transformComponent(Component component, bool enableAsserts) {
new SimpleUnreachableCodeElimination(enableAsserts).visitComponent(component);
new SimpleUnreachableCodeElimination(enableAsserts)
.visitComponent(component, null);
return component;
}
class SimpleUnreachableCodeElimination extends Transformer {
class SimpleUnreachableCodeElimination extends RemovingTransformer {
final bool enableAsserts;
SimpleUnreachableCodeElimination(this.enableAsserts);
@@ -37,24 +40,27 @@ class SimpleUnreachableCodeElimination extends Transformer {
Expression _createBoolLiteral(bool value, int fileOffset) =>
new BoolLiteral(value)..fileOffset = fileOffset;
Statement _makeEmptyBlockIfNull(Statement node, TreeNode parent) =>
node == null ? (Block(<Statement>[])..parent = parent) : node;
Statement _makeEmptyBlockIfEmptyStatement(Statement node, TreeNode parent) =>
node is EmptyStatement ? (Block(<Statement>[])..parent = parent) : node;
@override
TreeNode visitIfStatement(IfStatement node) {
node.transformChildren(this);
TreeNode visitIfStatement(IfStatement node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
final condition = node.condition;
if (_isBoolConstant(condition)) {
final value = _getBoolConstantValue(condition);
return value ? node.then : node.otherwise;
return value
? node.then
: (node.otherwise ?? removalSentinel ?? new EmptyStatement());
}
node.then = _makeEmptyBlockIfNull(node.then, node);
node.then = _makeEmptyBlockIfEmptyStatement(node.then, node);
return node;
}
@override
visitConditionalExpression(ConditionalExpression node) {
node.transformChildren(this);
visitConditionalExpression(
ConditionalExpression node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
final condition = node.condition;
if (_isBoolConstant(condition)) {
final value = _getBoolConstantValue(condition);
@@ -64,8 +70,8 @@ class SimpleUnreachableCodeElimination extends Transformer {
}
@override
TreeNode visitNot(Not node) {
node.transformChildren(this);
TreeNode visitNot(Not node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
final operand = node.operand;
if (_isBoolConstant(operand)) {
return _createBoolLiteral(
@@ -75,8 +81,9 @@ class SimpleUnreachableCodeElimination extends Transformer {
}
@override
TreeNode visitLogicalExpression(LogicalExpression node) {
node.transformChildren(this);
TreeNode visitLogicalExpression(
LogicalExpression node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
final left = node.left;
final right = node.right;
final operatorEnum = node.operatorEnum;
@@ -104,8 +111,8 @@ class SimpleUnreachableCodeElimination extends Transformer {
}
@override
visitStaticGet(StaticGet node) {
node.transformChildren(this);
visitStaticGet(StaticGet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
final target = node.target;
if (target is Field && target.isConst) {
throw 'StaticGet from const field $target should be evaluated by front-end: $node';
@@ -114,34 +121,38 @@ class SimpleUnreachableCodeElimination extends Transformer {
}
@override
TreeNode visitAssertStatement(AssertStatement node) {
TreeNode visitAssertStatement(
AssertStatement node, TreeNode? removalSentinel) {
if (!enableAsserts) {
return null;
return removalSentinel ?? new EmptyStatement();
}
return super.visitAssertStatement(node);
return super.visitAssertStatement(node, removalSentinel);
}
@override
TreeNode visitAssertBlock(AssertBlock node) {
TreeNode visitAssertBlock(AssertBlock node, TreeNode? removalSentinel) {
if (!enableAsserts) {
return null;
return removalSentinel ?? new EmptyStatement();
}
return super.visitAssertBlock(node);
return super.visitAssertBlock(node, removalSentinel);
}
@override
TreeNode visitAssertInitializer(AssertInitializer node) {
TreeNode visitAssertInitializer(
AssertInitializer node, TreeNode? removalSentinel) {
if (!enableAsserts) {
return null;
// Initializers only occur in the initializer list where they are always
// removable.
return removalSentinel!;
}
return super.visitAssertInitializer(node);
return super.visitAssertInitializer(node, removalSentinel);
}
@override
TreeNode visitTryFinally(TryFinally node) {
node.transformChildren(this);
TreeNode visitTryFinally(TryFinally node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
final fin = node.finalizer;
if (fin == null || (fin is Block && fin.statements.isEmpty)) {
if (fin is EmptyStatement || (fin is Block && fin.statements.isEmpty)) {
return node.body;
}
return node;
@@ -157,8 +168,8 @@ class SimpleUnreachableCodeElimination extends Transformer {
}
@override
TreeNode visitTryCatch(TryCatch node) {
node.transformChildren(this);
TreeNode visitTryCatch(TryCatch node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
// Can replace try/catch with its body if all catches are just rethow.
for (Catch catchClause in node.catches) {
if (!_isRethrow(catchClause.body)) {
@@ -174,30 +185,30 @@ class SimpleUnreachableCodeElimination extends Transformer {
// need to guard against null.
@override
TreeNode visitWhileStatement(WhileStatement node) {
node.transformChildren(this);
node.body = _makeEmptyBlockIfNull(node.body, node);
TreeNode visitWhileStatement(WhileStatement node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
node.body = _makeEmptyBlockIfEmptyStatement(node.body, node);
return node;
}
@override
TreeNode visitDoStatement(DoStatement node) {
node.transformChildren(this);
node.body = _makeEmptyBlockIfNull(node.body, node);
TreeNode visitDoStatement(DoStatement node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
node.body = _makeEmptyBlockIfEmptyStatement(node.body, node);
return node;
}
@override
TreeNode visitForStatement(ForStatement node) {
node.transformChildren(this);
node.body = _makeEmptyBlockIfNull(node.body, node);
TreeNode visitForStatement(ForStatement node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
node.body = _makeEmptyBlockIfEmptyStatement(node.body, node);
return node;
}
@override
TreeNode visitForInStatement(ForInStatement node) {
node.transformChildren(this);
node.body = _makeEmptyBlockIfNull(node.body, node);
TreeNode visitForInStatement(ForInStatement node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
node.body = _makeEmptyBlockIfEmptyStatement(node.body, node);
return node;
}
}