Chromium Code Reviews| 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..b438ae4fe8ef340f7022560f06bc2db3f519e301 100644 |
| --- a/pkg/compiler/lib/src/ssa/kernel_impact.dart |
| +++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart |
| @@ -72,6 +72,13 @@ 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) { |
| @@ -85,9 +92,7 @@ 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)); |
| + checkFunctionTypes(procedure.function); |
| procedure.function.body.accept(this); |
| } else { |
| compiler.reporter.internalError( |
| @@ -98,6 +103,8 @@ class KernelImpactBuilder extends ir.Visitor { |
| return impactBuilder; |
| } |
| + void visitNode(ir.Node node) => node?.accept(this); |
|
Harry Terkelsen
2016/09/22 19:20:15
if you have this, you should use it consistently t
Johnni Winther
2016/09/23 09:01:50
I thought I had ;) - Done.
|
| + |
| void visitNodes(Iterable<ir.Node> nodes) { |
| nodes.forEach((ir.Node node) => node.accept(this)); |
| } |
| @@ -238,8 +245,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 |
| @@ -276,23 +288,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); |
| } |