Skip to content

Commit

Permalink
Fix NodeUtil.isNonLocalModuleName behavior on export {a} from './foo.js'
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=246428904
  • Loading branch information
lauraharker authored and brad4d committed May 6, 2019
1 parent 1bd16a0 commit 5b414df
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 10 deletions.
6 changes: 3 additions & 3 deletions src/com/google/javascript/jscomp/MakeDeclaredNamesUnique.java
Expand Up @@ -108,17 +108,17 @@ public void visit(NodeTraversal t, Node n, Node parent) {
switch (n.getToken()) {
case NAME:
case IMPORT_STAR:
visitName(t, n, parent);
visitNameOrImportStar(t, n, parent);
break;

default:
break;
}
}

private void visitName(NodeTraversal t, Node n, Node parent) {
private void visitNameOrImportStar(NodeTraversal t, Node n, Node parent) {
// Don't rename the exported name foo in export {a as foo}; or import {foo as b};
if (NodeUtil.isNonlocalModuleExportName(n)) {
if (n.isName() && NodeUtil.isNonlocalModuleExportName(n)) {
return;
}
String newName = getReplacementName(n.getString());
Expand Down
35 changes: 28 additions & 7 deletions src/com/google/javascript/jscomp/NodeUtil.java
Expand Up @@ -2734,16 +2734,37 @@ static boolean isReferenceName(Node n) {
}

/**
* @return Whether the name in an import or export spec is not defined within the module, but is
* an exported name from this or another module. e.g. nonlocal in "export {a as nonlocal}" or
* "import {nonlocal as a} from './foo.js'"
* Returns whether the given name in an import or export spec is not defined within the module,
* but is an exported name from this or another module.
*
* <p>Examples include `nonlocal` in:
*
* <ul>
* <li>export {a as nonlocal};
* <li>import {nonlocal} from './foo.js';
* <li>import {nonlocal as a} from './foo.js';
* <li>export {nonlocal as a} from './foo.js';
* <li>export {a as nonlocal} from './foo.js';
* </ul>
*
* @param n a NAME node.
*/
static boolean isNonlocalModuleExportName(Node n) {
checkArgument(n.isName(), n);
Node parent = n.getParent();
return (parent != null
&& n.isName()
&& ((parent.isExportSpec() && n != parent.getFirstChild())
|| (parent.isImportSpec() && n != parent.getLastChild())));
if (parent.isImportSpec() && n.isFirstChildOf(parent)) {
// import {nonlocal as x} from './foo.js'
return true;
} else if (parent.isExportSpec()) {
if (n.isFirstChildOf(parent)) {
// export {nonlocal as b} from './foo.js';
return isExportFrom(parent.getGrandparent());
} else {
// export {local as nonlocal};
return true;
}
}
return false;
}

/** Whether the child node is the FINALLY block of a try. */
Expand Down
16 changes: 16 additions & 0 deletions test/com/google/javascript/jscomp/NodeUtilTest.java
Expand Up @@ -1274,6 +1274,22 @@ public void testIsNonlocalModuleExportNameOnExports2() {
assertThat(NodeUtil.isNonlocalModuleExportName(name)).isFalse();
}

@Test
public void testIsNonlocalModuleExportNameOnExportFrom() {
Node root = parse("export {bar as baz} from './foo.js';");
Node moduleBody = root.getFirstChild();
Node exportNode = moduleBody.getFirstChild();
Node exportSpecs = exportNode.getFirstChild();
Node exportSpec = exportSpecs.getFirstChild();

Node bar = exportSpec.getFirstChild();
Node baz = exportSpec.getSecondChild();

// Neither identifier is defined locally.
assertThat(NodeUtil.isNonlocalModuleExportName(bar)).isTrue();
assertThat(NodeUtil.isNonlocalModuleExportName(baz)).isTrue();
}

@Test
public void testIsNonlocalModuleExportNameOnImports1() {
Node root = parse("import {exportName as localName} from './foo.js';");
Expand Down

0 comments on commit 5b414df

Please sign in to comment.