From d2e98cb7fa67c1ae47f53b617a06d1f4872a111b Mon Sep 17 00:00:00 2001 From: blickly Date: Tue, 25 Apr 2017 13:54:14 -0700 Subject: [PATCH] Allow goog.module.get inside of goog.module files. Previously, only the specific pattern of: let x = goog.forwardDeclare(); function f() { x = goog.module.get(); } was supported, but goog.module.get can be generally useful without creating the alias. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=154216580 --- .../jscomp/ClosureRewriteModule.java | 32 +++++++++---------- .../jscomp/ClosureRewriteModuleTest.java | 22 +++++++++++++ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/com/google/javascript/jscomp/ClosureRewriteModule.java b/src/com/google/javascript/jscomp/ClosureRewriteModule.java index 1884b677f60..180248fe981 100644 --- a/src/com/google/javascript/jscomp/ClosureRewriteModule.java +++ b/src/com/google/javascript/jscomp/ClosureRewriteModule.java @@ -816,8 +816,9 @@ private void recordGoogModuleGet(NodeTraversal t, Node call) { } String aliasName = null; - boolean isFillingAnAlias = - call.getParent().isAssign() && call.getParent().getFirstChild().isName(); + Node maybeAssign = call.getParent(); + boolean isFillingAnAlias = maybeAssign.isAssign() && maybeAssign.getFirstChild().isName() + && maybeAssign.getParent().isExprResult(); if (isFillingAnAlias && currentScript.isModule) { aliasName = call.getParent().getFirstChild().getString(); @@ -839,6 +840,12 @@ private void recordGoogModuleGet(NodeTraversal t, Node call) { t.report(call, INVALID_GET_ALIAS); return; } + + // Each goog.module.get() calling filling an alias will have the alias importing logic + // handed at the goog.forwardDeclare call, and the corresponding goog.module.get can simply + // be removed. + compiler.reportChangeToEnclosingScope(maybeAssign); + maybeAssign.getParent().detach(); } } @@ -1110,20 +1117,13 @@ private void updateGoogModuleGetCall(Node call) { String legacyNamespace = legacyNamespaceNode.getString(); compiler.reportChangeToEnclosingScope(call); - if (currentScript.isModule) { - // In a module each goog.module.get() will have a paired goog.forwardDeclare() and the module - // alias importing will be handled there so that the alias is available in the entire module - // scope. - NodeUtil.getEnclosingStatement(call).detach(); - } else { - // In a non-module script goog.module.get() is used inside of a goog.scope() and it's - // imported alias need only be made available within that scope. - // Replace "goog.module.get('pkg.Foo');" with "module$exports$pkg$Foo;". - String exportedNamespace = rewriteState.getExportedNamespaceOrScript(legacyNamespace); - Node exportedNamespaceName = NodeUtil.newQName(compiler, exportedNamespace).srcrefTree(call); - exportedNamespaceName.putProp(Node.ORIGINALNAME_PROP, legacyNamespace); - call.replaceWith(exportedNamespaceName); - } + // Remaining calls to goog.module.get() are not alias updates, + // and should be replaced by a reference to the proper name. + // Replace "goog.module.get('pkg.Foo')" with either "pkg.Foo" or "module$exports$pkg$Foo". + String exportedNamespace = rewriteState.getExportedNamespaceOrScript(legacyNamespace); + Node exportedNamespaceName = NodeUtil.newQName(compiler, exportedNamespace).srcrefTree(call); + exportedNamespaceName.putProp(Node.ORIGINALNAME_PROP, legacyNamespace); + call.replaceWith(exportedNamespaceName); } private void recordExportsPropertyAssignment(NodeTraversal t, Node getpropNode) { diff --git a/test/com/google/javascript/jscomp/ClosureRewriteModuleTest.java b/test/com/google/javascript/jscomp/ClosureRewriteModuleTest.java index 6b80692858a..3ff19b5e528 100644 --- a/test/com/google/javascript/jscomp/ClosureRewriteModuleTest.java +++ b/test/com/google/javascript/jscomp/ClosureRewriteModuleTest.java @@ -932,6 +932,28 @@ public void testGoogModuleGet2() { "}")}); } + public void testGoogModuleGet3() { + testEs6( + new String[] { + LINE_JOINER.join( + "goog.module('a.b.c');", + "exports = class {};"), + LINE_JOINER.join( + "goog.module('x.y.z');", + "", + "function f() {", + " return new (goog.module.get('a.b.c'))();", + "}")}, + + new String[] { + "/** @const */ var module$exports$a$b$c = class {};", + LINE_JOINER.join( + "/** @const */ var module$exports$x$y$z = {};", + "function module$contents$x$y$z_f() {", + " return new module$exports$a$b$c();", + "}")}); + } + public void testAliasedGoogModuleGet1() { test( new String[] {