| 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);
|
| }
|
|
|