Chromium Code Reviews| Index: pkg/compiler/lib/src/kernel/kernel_visitor.dart |
| diff --git a/pkg/compiler/lib/src/kernel/kernel_visitor.dart b/pkg/compiler/lib/src/kernel/kernel_visitor.dart |
| index 8ba98d0bea7888a493cd276aa5633eabf2f41ff5..109a81c7e7c3ed98a3cd340e218838d8074e59e2 100644 |
| --- a/pkg/compiler/lib/src/kernel/kernel_visitor.dart |
| +++ b/pkg/compiler/lib/src/kernel/kernel_visitor.dart |
| @@ -47,6 +47,7 @@ import '../elements/elements.dart' |
| GetterElement, |
| InitializingFormalElement, |
| JumpTarget, |
| + LibraryElement, |
| LocalElement, |
| LocalFunctionElement, |
| LocalVariableElement, |
| @@ -202,6 +203,12 @@ class KernelVisitor extends Object |
| final Map<CascadeReceiver, ir.VariableGet> cascadeReceivers = |
| <CascadeReceiver, ir.VariableGet>{}; |
| + // This maps underlying Library elements to the corresponding DeferredImport |
| + // object, via the prefix name (aka "bar" in |
| + // "import foo.dart deferred as bar"). |
|
sra1
2017/02/14 21:55:28
Is the 'underlying' library element the current li
Emily Fortuna
2017/02/15 01:02:31
updated the comment -- imported library.
|
| + final Map<LibraryElement, Map<String, ir.DeferredImport>> deferredImports = |
| + <LibraryElement, Map<String, ir.DeferredImport>>{}; |
| + |
| ir.Node associateElement(ir.Node node, Element element) { |
| kernel.nodeToElement[node] = element; |
| return node; |
| @@ -214,6 +221,10 @@ class KernelVisitor extends Object |
| bool isVoidContext = false; |
| + /// If non-null, reference to a deferred library that a subsequent getter is |
| + /// using. |
| + ir.DeferredImport _deferredLibrary; |
| + |
| KernelVisitor(this.currentElement, this.elements, this.kernel); |
| KernelVisitor get sendVisitor => this; |
| @@ -363,7 +374,15 @@ class KernelVisitor extends Object |
| } |
| @override |
| - void previsitDeferredAccess(Send node, PrefixElement prefix, _) {} |
| + void previsitDeferredAccess(Send node, PrefixElement prefix, _) { |
| + // This is visited before any element access, and if it is deferred, |
| + // prefix.isDeferred = true. |
| + if (prefix != null && prefix.isDeferred) { |
| + _deferredLibrary = getDeferredImport(prefix); |
| + } else { |
| + _deferredLibrary = null; |
| + } |
| + } |
| @override |
| internalError(Spannable spannable, String message) { |
| @@ -1994,7 +2013,14 @@ class KernelVisitor extends Object |
| } |
| ir.Expression buildStaticGet(Element element) { |
| - return buildStaticAccessor(element).buildSimpleRead(); |
| + var expression = buildStaticAccessor(element).buildSimpleRead(); |
| + if (_deferredLibrary != null) { |
| + ir.Let let = new ir.Let( |
| + makeOrReuseVariable(new ir.CheckLibraryIsLoaded(_deferredLibrary)), |
| + expression); |
| + return let; |
| + } |
| + return expression; |
| } |
| @override |
| @@ -2229,24 +2255,44 @@ class KernelVisitor extends Object |
| return buildIrFunction(ir.ProcedureKind.Getter, getter, body); |
| } |
| + ir.DeferredImport getDeferredImport(PrefixElement prefix) { |
| + ir.DeferredImport deferredImport; |
| + var importedLibraryElement = prefix.deferredImport.importedLibrary; |
| + if (deferredImports.containsKey(importedLibraryElement)) { |
| + var prefixToDeferredImport = deferredImports[importedLibraryElement]; |
|
sra1
2017/02/14 21:55:28
Nowadays I find ??= more convenient
var map = def
Emily Fortuna
2017/02/15 01:02:31
Done.
|
| + deferredImport = |
| + prefixToDeferredImport.putIfAbsent(prefix.name, () { |
| + return new ir.DeferredImport(kernel.libraries[importedLibraryElement], |
| + prefix.name); |
| + }); |
| + } else { |
| + deferredImport = new ir.DeferredImport( |
| + kernel.libraries[importedLibraryElement], prefix.name); |
| + deferredImports[importedLibraryElement] = {prefix.name: deferredImport}; |
|
sra1
2017/02/14 21:55:28
Type parameters on literal.
Emily Fortuna
2017/02/15 01:02:31
Done.
|
| + } |
| + return deferredImport; |
| + } |
| + |
| @override |
| ir.Expression handleStaticGetterGet(Send node, FunctionElement getter, _) { |
| if (getter.isDeferredLoaderGetter) { |
| - // TODO(ahe): Support deferred load. |
| - return new ir.InvalidExpression(); |
| + return new ir.LoadLibrary(getDeferredImport(getter.enclosingElement)); |
| } |
| - return buildStaticGet(getter); |
| + var expression = buildStaticGet(getter); |
| + return expression; |
| } |
| @override |
| ir.Expression handleStaticGetterInvoke(Send node, FunctionElement getter, |
| NodeList arguments, CallStructure callStructure, _) { |
| + var expression; |
| if (getter.isDeferredLoaderGetter) { |
| - // TODO(ahe): Support deferred load. |
| - return new ir.InvalidExpression(); |
| + expression = new ir.LoadLibrary(getDeferredImport( |
| + getter.enclosingElement)); |
| + } else { |
| + expression = buildStaticGet(getter); |
| } |
| - return associateNode( |
| - buildCall(buildStaticGet(getter), callStructure, arguments), node); |
| + return associateNode(buildCall(expression, callStructure, arguments), node); |
| } |
| @override |