| Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| index ee7a8706b7f9d12dc3bc417cbaf4f3db11bc4c0a..9f2295a505e1d35c12ff6b89e245382cc755d504 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| @@ -706,7 +706,21 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| // ## Sends ##
|
| @override
|
| void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) {
|
| - giveup(node, 'deferred access is not implemented');
|
| + buildCheckDeferredIsLoaded(prefix, node,
|
| + sourceInformationBuilder.buildCall(node, node.selector));
|
| + }
|
| +
|
| + ir.Primitive buildCheckDeferredIsLoaded(PrefixElement prefix, Spannable node,
|
| + SourceInformation sourceInformation) {
|
| + if (prefix == null) return null;
|
| + JavaScriptBackend backend = compiler.backend;
|
| + return irBuilder.buildStaticFunctionInvocation(
|
| + backend.helpers.checkDeferredIsLoaded,
|
| + CallStructure.TWO_ARGS, <ir.Primitive>[
|
| + irBuilder.buildStringConstant(
|
| + compiler.deferredLoadTask.getImportDeferName(node, prefix)),
|
| + irBuilder.buildStringConstant('${prefix.deferredImport.uri}'),
|
| + ], sourceInformation: sourceInformation);
|
| }
|
|
|
| ir.Primitive visitNamedArgument(ast.NamedArgument node) {
|
| @@ -2581,6 +2595,11 @@ class GlobalProgramInformation {
|
|
|
| ClassElement get nullClass => _compiler.coreClasses.nullClass;
|
|
|
| + Element get loadLibraryFunction => _compiler.loadLibraryFunction;
|
| + String getImportDeferName(PrefixElement prefix) {
|
| + return _compiler.deferredLoadTask.getImportDeferName(null, prefix);
|
| + }
|
| +
|
| DartType unaliasType(DartType type) => type.unaliased;
|
|
|
| TypeMask getTypeMaskForForeign(NativeBehavior behavior) {
|
| @@ -3344,13 +3363,39 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
|
| ast.NodeList argumentsNode,
|
| CallStructure callStructure,
|
| _) {
|
| +
|
| + ast.Send send = node.send;
|
| + // If an allocation refers to a type using a deferred import prefix (e.g.
|
| + // `new lib.A()`), we must ensure that the deferred import has already been
|
| + // loaded.
|
| + var prefix = compiler.deferredLoadTask.deferredPrefixElement(
|
| + send, elements);
|
| + if (prefix != null) {
|
| + buildCheckDeferredIsLoaded(prefix, send,
|
| + sourceInformationBuilder.buildCall(send, send.selector));
|
| + }
|
| +
|
| List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
|
| // Use default values from the effective target, not the immediate target.
|
| ConstructorElement target = constructor.effectiveTarget;
|
| - callStructure =
|
| - normalizeStaticArguments(callStructure, target, arguments);
|
| +
|
| + // We also emit deferred import checks when using redirecting factories that
|
| + // refer to deferred prefixes.
|
| + if (constructor.isRedirectingFactory && !constructor.isCyclicRedirection) {
|
| + ConstructorElement current = constructor;
|
| + while (current.isRedirectingFactory) {
|
| + var prefix = current.redirectionDeferredPrefix;
|
| + if (prefix != null) {
|
| + buildCheckDeferredIsLoaded(prefix, send,
|
| + sourceInformationBuilder.buildCall(send, send.selector));
|
| + }
|
| + current = current.immediateRedirectionTarget;
|
| + }
|
| + }
|
| +
|
| + callStructure = normalizeStaticArguments(callStructure, target, arguments);
|
| TypeMask allocationSiteType;
|
| - ast.Node send = node.send;
|
| +
|
| if (Elements.isFixedListConstructorCall(constructor, send, compiler) ||
|
| Elements.isGrowableListConstructorCall(constructor, send, compiler) ||
|
| Elements.isFilledListConstructorCall(constructor, send, compiler) ||
|
|
|