Index: pkg/compiler/lib/src/ssa/kernel_impact.dart |
diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart |
index f03bd1f61372d7b4ae273ad2d6e43e6eb6ff3e92..a2f9279ab3d46d48e7c489d3b5ad8d090dca1f52 100644 |
--- a/pkg/compiler/lib/src/ssa/kernel_impact.dart |
+++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart |
@@ -72,10 +72,17 @@ class KernelImpactBuilder extends ir.Visitor { |
return type; |
} |
+ /// Add a checked-mode type use of return type and parameters of [node]. |
+ void checkFunctionTypes(ir.FunctionNode node) { |
+ checkType(node.returnType); |
+ node.positionalParameters.forEach((v) => checkType(v.type)); |
+ node.namedParameters.forEach((v) => checkType(v.type)); |
+ } |
+ |
ResolutionImpact buildField(ir.Field field) { |
checkType(field.type); |
if (field.initializer != null) { |
- field.initializer.accept(this); |
+ visitNode(field.initializer); |
} else { |
impactBuilder.registerFeature(Feature.FIELD_WITHOUT_INITIALIZER); |
} |
@@ -85,10 +92,8 @@ class KernelImpactBuilder extends ir.Visitor { |
ResolutionImpact buildProcedure(ir.Procedure procedure) { |
if (procedure.kind == ir.ProcedureKind.Method || |
procedure.kind == ir.ProcedureKind.Operator) { |
- checkType(procedure.function.returnType); |
- procedure.function.positionalParameters.forEach((v) => checkType(v.type)); |
- procedure.function.namedParameters.forEach((v) => checkType(v.type)); |
- procedure.function.body.accept(this); |
+ checkFunctionTypes(procedure.function); |
+ visitNode(procedure.function.body); |
} else { |
compiler.reporter.internalError( |
resolvedAst.element, |
@@ -98,8 +103,10 @@ class KernelImpactBuilder extends ir.Visitor { |
return impactBuilder; |
} |
+ void visitNode(ir.Node node) => node?.accept(this); |
+ |
void visitNodes(Iterable<ir.Node> nodes) { |
- nodes.forEach((ir.Node node) => node.accept(this)); |
+ nodes.forEach(visitNode); |
} |
@override |
@@ -107,19 +114,19 @@ class KernelImpactBuilder extends ir.Visitor { |
@override |
void visitExpressionStatement(ir.ExpressionStatement exprStatement) { |
- exprStatement.expression.accept(this); |
+ visitNode(exprStatement.expression); |
} |
@override |
void visitReturnStatement(ir.ReturnStatement returnStatement) { |
- returnStatement.expression?.accept(this); |
+ visitNode(returnStatement.expression); |
} |
@override |
void visitIfStatement(ir.IfStatement ifStatement) { |
- ifStatement.condition.accept(this); |
- ifStatement.then.accept(this); |
- ifStatement.otherwise?.accept(this); |
+ visitNode(ifStatement.condition); |
+ visitNode(ifStatement.then); |
+ visitNode(ifStatement.otherwise); |
} |
@override |
@@ -179,17 +186,13 @@ class KernelImpactBuilder extends ir.Visitor { |
} |
void visitMapEntry(ir.MapEntry entry) { |
- entry.key.accept(this); |
- entry.value.accept(this); |
+ visitNode(entry.key); |
+ visitNode(entry.value); |
} |
void _visitArguments(ir.Arguments arguments) { |
- for (ir.Expression argument in arguments.positional) { |
- argument.accept(this); |
- } |
- for (ir.NamedExpression argument in arguments.named) { |
- argument.value.accept(this); |
- } |
+ arguments.positional.forEach(visitNode); |
+ arguments.named.forEach(visitNode); |
} |
@override |
@@ -238,8 +241,13 @@ class KernelImpactBuilder extends ir.Visitor { |
@override |
void visitStaticGet(ir.StaticGet node) { |
- Element target = astAdapter.getElement(node.target).declaration; |
- impactBuilder.registerStaticUse(new StaticUse.staticGet(target)); |
+ ir.Member target = node.target; |
+ Element element = astAdapter.getElement(target).declaration; |
+ if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) { |
+ impactBuilder.registerStaticUse(new StaticUse.staticTearOff(element)); |
+ } else { |
+ impactBuilder.registerStaticUse(new StaticUse.staticGet(element)); |
+ } |
} |
@override |
@@ -250,7 +258,7 @@ class KernelImpactBuilder extends ir.Visitor { |
receiver.variable.parent is ir.FunctionDeclaration) { |
// Invocation of a local function. No need for dynamic use. |
} else { |
- invocation.receiver.accept(this); |
+ visitNode(invocation.receiver); |
impactBuilder.registerDynamicUse( |
new DynamicUse(astAdapter.getSelector(invocation), null)); |
} |
@@ -259,15 +267,15 @@ class KernelImpactBuilder extends ir.Visitor { |
@override |
void visitPropertyGet(ir.PropertyGet node) { |
- node.receiver.accept(this); |
+ visitNode(node.receiver); |
impactBuilder.registerDynamicUse(new DynamicUse( |
new Selector.getter(astAdapter.getName(node.name)), null)); |
} |
@override |
void visitPropertySet(ir.PropertySet node) { |
- node.receiver.accept(this); |
- node.value.accept(this); |
+ visitNode(node.receiver); |
+ visitNode(node.value); |
impactBuilder.registerDynamicUse(new DynamicUse( |
new Selector.setter(astAdapter.getName(node.name)), null)); |
} |
@@ -276,23 +284,45 @@ class KernelImpactBuilder extends ir.Visitor { |
void visitAssertStatement(ir.AssertStatement node) { |
impactBuilder.registerFeature( |
node.message != null ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT); |
- node.visitChildren(this); |
+ visitNode(node.condition); |
+ visitNode(node.message); |
} |
@override |
void visitStringConcatenation(ir.StringConcatenation node) { |
impactBuilder.registerFeature(Feature.STRING_INTERPOLATION); |
impactBuilder.registerFeature(Feature.STRING_JUXTAPOSITION); |
- node.visitChildren(this); |
+ visitNodes(node.expressions); |
} |
@override |
void visitFunctionDeclaration(ir.FunctionDeclaration node) { |
impactBuilder |
.registerStaticUse(new StaticUse.closure(astAdapter.getElement(node))); |
- node.visitChildren(this); |
+ checkFunctionTypes(node.function); |
+ visitNode(node.function.body); |
+ } |
+ |
+ @override |
+ void visitFunctionExpression(ir.FunctionExpression node) { |
+ impactBuilder |
+ .registerStaticUse(new StaticUse.closure(astAdapter.getElement(node))); |
+ checkFunctionTypes(node.function); |
+ visitNode(node.function.body); |
+ } |
+ |
+ @override |
+ void visitVariableDeclaration(ir.VariableDeclaration node) { |
+ checkType(node.type); |
+ if (node.initializer != null) { |
+ visitNode(node.initializer); |
+ } else { |
+ impactBuilder.registerFeature(Feature.LOCAL_WITHOUT_INITIALIZER); |
+ } |
} |
+ // TODO(johnniwinther): Make this throw and visit child nodes explicitly |
+ // instead to ensure that we don't visit unwanted parts of the ir. |
@override |
void defaultNode(ir.Node node) => node.visitChildren(this); |
} |