| 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 0c31e97fdc8d3a949bf34e17fb13da6eb5b8f7a2..63bac549e1ecc06484d69e198fa3a1985ec7fbc9 100644
|
| --- a/pkg/compiler/lib/src/ssa/kernel_impact.dart
|
| +++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart
|
| @@ -26,37 +26,39 @@ import '../common/resolution.dart';
|
| /// Computes the [ResolutionImpact] for [resolvedAst] through kernel.
|
| ResolutionImpact build(Compiler compiler, ResolvedAst resolvedAst) {
|
| AstElement element = resolvedAst.element;
|
| - JavaScriptBackend backend = compiler.backend;
|
| - Kernel kernel = backend.kernelTask.kernel;
|
| - KernelImpactBuilder builder =
|
| - new KernelImpactBuilder(resolvedAst, compiler, kernel);
|
| - if (element.isFunction ||
|
| - element.isGetter ||
|
| - element.isSetter ||
|
| - element.isFactoryConstructor) {
|
| - ir.Procedure function = kernel.functions[element];
|
| - if (function == null) {
|
| - throw "FOUND NULL FUNCTION: $element";
|
| - } else {
|
| - return builder.buildProcedure(function);
|
| - }
|
| - } else if (element.isGenerativeConstructor) {
|
| - ir.Constructor constructor = kernel.functions[element];
|
| - if (constructor == null) {
|
| - throw "FOUND NULL CONSTRUCTOR: $element";
|
| - } else {
|
| - return builder.buildConstructor(constructor);
|
| - }
|
| - } else if (element.isField) {
|
| - ir.Field field = kernel.fields[element];
|
| - if (field == null) {
|
| - throw "FOUND NULL FIELD: $element";
|
| + return compiler.reporter.withCurrentElement(element.implementation, () {
|
| + JavaScriptBackend backend = compiler.backend;
|
| + Kernel kernel = backend.kernelTask.kernel;
|
| + KernelImpactBuilder builder =
|
| + new KernelImpactBuilder(resolvedAst, compiler, kernel);
|
| + if (element.isFunction ||
|
| + element.isGetter ||
|
| + element.isSetter ||
|
| + element.isFactoryConstructor) {
|
| + ir.Procedure function = kernel.functions[element];
|
| + if (function == null) {
|
| + throw "FOUND NULL FUNCTION: $element";
|
| + } else {
|
| + return builder.buildProcedure(function);
|
| + }
|
| + } else if (element.isGenerativeConstructor) {
|
| + ir.Constructor constructor = kernel.functions[element];
|
| + if (constructor == null) {
|
| + throw "FOUND NULL CONSTRUCTOR: $element";
|
| + } else {
|
| + return builder.buildConstructor(constructor);
|
| + }
|
| + } else if (element.isField) {
|
| + ir.Field field = kernel.fields[element];
|
| + if (field == null) {
|
| + throw "FOUND NULL FIELD: $element";
|
| + } else {
|
| + return builder.buildField(field);
|
| + }
|
| } else {
|
| - return builder.buildField(field);
|
| + throw new UnsupportedError("Unsupported element: $element");
|
| }
|
| - } else {
|
| - throw new UnsupportedError("Unsupported element: $element");
|
| - }
|
| + });
|
| }
|
|
|
| class KernelImpactBuilder extends ir.Visitor {
|
| @@ -105,7 +107,7 @@ class KernelImpactBuilder extends ir.Visitor {
|
| checkType(field.type);
|
| if (field.initializer != null) {
|
| visitNode(field.initializer);
|
| - if (!field.isConst) {
|
| + if (!field.isInstanceMember && !field.isConst) {
|
| impactBuilder.registerFeature(Feature.LAZY_FIELD);
|
| }
|
| } else {
|
| @@ -291,7 +293,7 @@ class KernelImpactBuilder extends ir.Visitor {
|
| // to B. Currently, we only do this soundly if we register A<int> and
|
| // A<String> as instantiated. We should instead register that A.T is
|
| // instantiated as int and String.
|
| - handleNew(node, node.target);
|
| + handleNew(node, node.target, isConst: node.isConst);
|
| } else {
|
| _visitArguments(node.arguments);
|
| impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
|
| @@ -317,6 +319,64 @@ class KernelImpactBuilder extends ir.Visitor {
|
| impactBuilder.registerStaticUse(new StaticUse.staticSet(element));
|
| }
|
|
|
| + void handleSuperInvocation(ir.Node target, ir.Node arguments) {
|
| + Element element = astAdapter.getElement(target).declaration;
|
| + _visitArguments(arguments);
|
| + impactBuilder.registerStaticUse(new StaticUse.superInvoke(
|
| + element, astAdapter.getCallStructure(arguments)));
|
| + }
|
| +
|
| + @override
|
| + void visitDirectMethodInvocation(ir.DirectMethodInvocation node) {
|
| + handleSuperInvocation(node.target, node.arguments);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperMethodInvocation(ir.SuperMethodInvocation node) {
|
| + // TODO(johnniwinther): Should we support this or always use the
|
| + // [MixinFullResolution] transformer?
|
| + handleSuperInvocation(node.interfaceTarget, node.arguments);
|
| + }
|
| +
|
| + void handleSuperGet(ir.Member target) {
|
| + Element element = astAdapter.getElement(target).declaration;
|
| + if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) {
|
| + impactBuilder.registerStaticUse(new StaticUse.superTearOff(element));
|
| + } else {
|
| + impactBuilder.registerStaticUse(new StaticUse.superGet(element));
|
| + }
|
| + }
|
| +
|
| + @override
|
| + void visitDirectGet(ir.StaticGet node) {
|
| + handleSuperGet(node.target);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperPropertyGet(ir.SuperPropertyGet node) {
|
| + handleSuperGet(node.interfaceTarget);
|
| + }
|
| +
|
| + void handleSuperSet(ir.Node target, ir.Node value) {
|
| + visitNode(value);
|
| + Element element = astAdapter.getElement(target).declaration;
|
| + if (target is ir.Field) {
|
| + impactBuilder.registerStaticUse(new StaticUse.superFieldSet(element));
|
| + } else {
|
| + impactBuilder.registerStaticUse(new StaticUse.superSetterSet(element));
|
| + }
|
| + }
|
| +
|
| + @override
|
| + void visitDirectPropertySet(ir.DirectPropertySet node) {
|
| + handleSuperSet(node.target, node.value);
|
| + }
|
| +
|
| + @override
|
| + void visitSuperPropertySet(ir.SuperPropertySet node) {
|
| + handleSuperSet(node.interfaceTarget, node.value);
|
| + }
|
| +
|
| @override
|
| void visitMethodInvocation(ir.MethodInvocation invocation) {
|
| var receiver = invocation.receiver;
|
| @@ -392,12 +452,14 @@ class KernelImpactBuilder extends ir.Visitor {
|
| void visitIsExpression(ir.IsExpression node) {
|
| impactBuilder.registerTypeUse(
|
| new TypeUse.isCheck(astAdapter.getDartType(node.type)));
|
| + visitNode(node.operand);
|
| }
|
|
|
| @override
|
| void visitAsExpression(ir.AsExpression node) {
|
| impactBuilder
|
| .registerTypeUse(new TypeUse.asCast(astAdapter.getDartType(node.type)));
|
| + visitNode(node.operand);
|
| }
|
|
|
| @override
|
| @@ -448,6 +510,27 @@ class KernelImpactBuilder extends ir.Visitor {
|
| visitNode(node.finalizer);
|
| }
|
|
|
| + @override
|
| + void visitTypeLiteral(ir.TypeLiteral node) {
|
| + impactBuilder.registerTypeUse(
|
| + new TypeUse.typeLiteral(astAdapter.getDartType(node.type)));
|
| + }
|
| +
|
| + @override
|
| + void visitFieldInitializer(ir.FieldInitializer node) {
|
| + impactBuilder.registerStaticUse(
|
| + new StaticUse.fieldInit(astAdapter.getElement(node.field)));
|
| + visitNode(node.value);
|
| + }
|
| +
|
| + @override
|
| + void visitRedirectingInitializer(ir.RedirectingInitializer node) {
|
| + _visitArguments(node.arguments);
|
| + Element target = astAdapter.getElement(node.target).declaration;
|
| + impactBuilder.registerStaticUse(new StaticUse.superConstructorInvoke(
|
| + target, astAdapter.getCallStructure(node.arguments)));
|
| + }
|
| +
|
| // TODO(johnniwinther): Make this throw and visit child nodes explicitly
|
| // instead to ensure that we don't visit unwanted parts of the ir.
|
| @override
|
|
|