Skip to content

Commit

Permalink
Always mark constant exports as constant.
Browse files Browse the repository at this point in the history
Needed for type checking.

"exports Class {}" was marked as const correctly, but "export const Class = class {}" was not.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=202360495
  • Loading branch information
johnplaisted authored and brad4d committed Jun 28, 2018
1 parent 63ad7f9 commit 59d1e32
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 63 deletions.
20 changes: 4 additions & 16 deletions src/com/google/javascript/jscomp/Es6RewriteModules.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ public final class Es6RewriteModules extends AbstractPostOrderCallback

private final Set<Node> importedGoogNames;

private Set<String> classes;
private Set<String> typedefs;

private final ModuleMetadata moduleMetadata;
Expand Down Expand Up @@ -178,7 +177,6 @@ public void clearState() {
this.exportsByLocalName = LinkedHashMultimap.create();
this.importMap = new HashMap<>();
this.importedGoogNames.clear();
this.classes = new HashSet<>();
this.typedefs = new HashSet<>();
}

Expand Down Expand Up @@ -453,14 +451,6 @@ private void visitExportDeclaration(NodeTraversal t, Node export, Node parent) {
Node nameNode = declaration.getFirstChild();
String name = nameNode.getString();
exportsByLocalName.put(name, new NameNodePair(name, nameNode));

// If the declaration declares a new type, create annotations for
// the type checker.
// TODO(moz): Currently we only record ES6 classes and typedefs,
// need to handle other kinds of type declarations too.
if (declaration.isClass()) {
classes.add(name);
}
}

parent.replaceChild(export, declaration.detach());
Expand Down Expand Up @@ -551,12 +541,10 @@ private Node createExportsObject(NodeTraversal t, Node script) {
// actually type checkable.
// exports.foo = foo;
Node assign = IR.assign(getProp, NodeUtil.newQName(compiler, withSuffix));
if (classes.contains(exportedName)) {
JSDocInfoBuilder builder = new JSDocInfoBuilder(true);
builder.recordConstancy();
JSDocInfo info = builder.build();
assign.setJSDocInfo(info);
}
JSDocInfoBuilder builder = new JSDocInfoBuilder(true);
builder.recordConstancy();
JSDocInfo info = builder.build();
assign.setJSDocInfo(info);
script.addChildToBack(
IR.exprResult(assign).useSourceInfoIfMissingFromForTree(nodeForSourceInfo));
}
Expand Down
8 changes: 4 additions & 4 deletions test/com/google/javascript/jscomp/CollapsePropertiesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2191,8 +2191,8 @@ public void testModuleExportsBasicEsm() {
"var $jscompDefaultExport$$module$mod1=123;",
"var bar$$module$mod1 = 'bar';",
"/** @const */ var module$mod1={};",
"var module$mod1$default = $jscompDefaultExport$$module$mod1;",
"var module$mod1$bar = bar$$module$mod1")));
"/** @const */ var module$mod1$default = $jscompDefaultExport$$module$mod1;",
"/** @const */ var module$mod1$bar = bar$$module$mod1")));
expected.add(
SourceFile.fromCode("entry.js", "alert(module$mod1$default); alert(module$mod1$bar);"));

Expand Down Expand Up @@ -2223,7 +2223,7 @@ public void testMutableModuleExportsBasicEsm() {
"/** @const */ var module$mod1= {",
" /** @return {?} */ get bar() { return bar$$module$mod1; },",
"};",
"var module$mod1$default = $jscompDefaultExport$$module$mod1;")));
"/** @const */ var module$mod1$default = $jscompDefaultExport$$module$mod1;")));
expected.add(
SourceFile.fromCode("entry.js", "alert(module$mod1$default); alert(module$mod1.bar);"));

Expand Down Expand Up @@ -2279,7 +2279,7 @@ public void testModuleExportsObjectEsm() {
"foo$$module$mod1.bar.baz = 123;",
"var $jscompDefaultExport$$module$mod1 = foo$$module$mod1;",
"/** @const */ var module$mod1={};",
"var module$mod1$default = $jscompDefaultExport$$module$mod1;")));
"/** @const */ var module$mod1$default = $jscompDefaultExport$$module$mod1;")));
expected.add(SourceFile.fromCode("entry.js", "alert(module$mod1$default.bar.baz);"));

test(inputs, expected);
Expand Down
10 changes: 5 additions & 5 deletions test/com/google/javascript/jscomp/CommandLineRunnerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1776,10 +1776,10 @@ public void testProcessCJSWithES6Export() {
"var Foo$$module$foo=function(){};",
"Foo$$module$foo.prototype.bar=function(){console.log(\"bar\")};",
"var module$foo={};",
"module$foo.default=Foo$$module$foo;"),
"/** @const */ module$foo.default=Foo$$module$foo;"),
LINE_JOINER.join(
"var FooBar = module$foo.default,",
" baz = new module$foo.default();",
"var FooBar = Foo$$module$foo,",
" baz = new Foo$$module$foo();",
"console.log(baz.bar());")
});
}
Expand Down Expand Up @@ -1851,10 +1851,10 @@ public void testES6ImportOfFileWithImportsButNoExports() {
new String[] {
LINE_JOINER.join(
"var $jscompDefaultExport$$module$message = 'message', module$message = {};",
"module$message.default = $jscompDefaultExport$$module$message;"),
"/** @const */ module$message.default = $jscompDefaultExport$$module$message;"),
LINE_JOINER.join(
"function foo$$module$foo(){",
" alert(module$message.default);",
" alert($jscompDefaultExport$$module$message);",
"}",
"foo$$module$foo();",
"/** @const */ var module$foo = {};"),
Expand Down
83 changes: 46 additions & 37 deletions test/com/google/javascript/jscomp/Es6RewriteModulesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,62 +114,62 @@ public void testExport() {
lines(
"var a$$module$testcode = 1, b$$module$testcode = 2;",
"/** @const */ var module$testcode = {};",
"module$testcode.a = a$$module$testcode;",
"module$testcode.b = b$$module$testcode;"));
"/** @const */ module$testcode.a = a$$module$testcode;",
"/** @const */ module$testcode.b = b$$module$testcode;"));

testModules(
"export var a;\nexport var b;",
lines(
"var a$$module$testcode; var b$$module$testcode;",
"/** @const */ var module$testcode = {};",
"module$testcode.a = a$$module$testcode;",
"module$testcode.b = b$$module$testcode;"));
"/** @const */ module$testcode.a = a$$module$testcode;",
"/** @const */ module$testcode.b = b$$module$testcode;"));

testModules(
"export function f() {};",
lines(
"function f$$module$testcode() {}",
"/** @const */ var module$testcode = {};",
"module$testcode.f = f$$module$testcode;"));
"/** @const */ module$testcode.f = f$$module$testcode;"));

testModules(
"export function f() {};\nfunction g() { f(); }",
lines(
"function f$$module$testcode() {}",
"function g$$module$testcode() { f$$module$testcode(); }",
"/** @const */ var module$testcode = {};",
"module$testcode.f = f$$module$testcode;"));
"/** @const */ module$testcode.f = f$$module$testcode;"));

testModules(
lines("export function MyClass() {};", "MyClass.prototype.foo = function() {};"),
lines(
"function MyClass$$module$testcode() {}",
"MyClass$$module$testcode.prototype.foo = function() {};",
"/** @const */ var module$testcode = {};",
"module$testcode.MyClass = MyClass$$module$testcode;"));
"/** @const */ module$testcode.MyClass = MyClass$$module$testcode;"));

testModules(
"var f = 1;\nvar b = 2;\nexport {f as foo, b as bar};",
lines(
"var f$$module$testcode = 1;",
"var b$$module$testcode = 2;",
"/** @const */ var module$testcode = {};",
"module$testcode.foo = f$$module$testcode;",
"module$testcode.bar = b$$module$testcode;"));
"/** @const */ module$testcode.foo = f$$module$testcode;",
"/** @const */ module$testcode.bar = b$$module$testcode;"));

testModules(
"var f = 1;\nexport {f as default};",
lines(
"var f$$module$testcode = 1;",
"/** @const */ var module$testcode = {};",
"module$testcode.default = f$$module$testcode;"));
"/** @const */ module$testcode.default = f$$module$testcode;"));

testModules(
"var f = 1;\nexport {f as class};",
lines(
"var f$$module$testcode = 1;",
"/** @const */ var module$testcode = {};",
"module$testcode.class = f$$module$testcode;"));
"/** @const */ module$testcode.class = f$$module$testcode;"));
}

public void testModulesInExterns() {
Expand Down Expand Up @@ -339,7 +339,16 @@ public void testMutableExport() {
" /** @return {?} */ get ARRAY() { return ARRAY$$module$testcode; },",
" /** @return {?} */ get OBJ() { return OBJ$$module$testcode; },",
"};",
"module$testcode.UNCHANGED = UNCHANGED$$module$testcode"));
"/** @const */ module$testcode.UNCHANGED = UNCHANGED$$module$testcode"));
}

public void testConstClassExportIsConstant() {
testModules(
"export const Class = class {}",
lines(
"const Class$$module$testcode = class {}",
"/** @const */ var module$testcode = {};",
"/** @const */ module$testcode.Class = Class$$module$testcode;"));
}

public void testTopLevelMutationIsNotMutable() {
Expand All @@ -352,8 +361,8 @@ public void testTopLevelMutationIsNotMutable() {
"a$$module$testcode++;",
"b$$module$testcode++",
"/** @const */ var module$testcode = {};",
"module$testcode.a = a$$module$testcode;",
"module$testcode.b = b$$module$testcode;"));
"/** @const */ module$testcode.a = a$$module$testcode;",
"/** @const */ module$testcode.b = b$$module$testcode;"));

testModules(
lines("var a = 1, b = 2; export {a as A, b as B};",
Expand All @@ -368,8 +377,8 @@ public void testTopLevelMutationIsNotMutable() {
" b$$module$testcode++",
"}",
"/** @const */ var module$testcode = {};",
"module$testcode.A = a$$module$testcode;",
"module$testcode.B = b$$module$testcode;"));
"/** @const */ module$testcode.A = a$$module$testcode;",
"/** @const */ module$testcode.B = b$$module$testcode;"));

testModules(
lines("export function f() {};",
Expand All @@ -382,7 +391,7 @@ public void testTopLevelMutationIsNotMutable() {
" f$$module$testcode = function() {};",
"}",
"/** @const */ var module$testcode = {};",
"module$testcode.f = f$$module$testcode;"));
"/** @const */ module$testcode.f = f$$module$testcode;"));

testModules(
lines("export default function f() {};",
Expand All @@ -392,7 +401,7 @@ public void testTopLevelMutationIsNotMutable() {
"try { f$$module$testcode = function() {}; }",
"catch (e) { f$$module$testcode = function() {}; }",
"/** @const */ var module$testcode = {};",
"module$testcode.default = f$$module$testcode;"));
"/** @const */ module$testcode.default = f$$module$testcode;"));

testModules(
lines("export class C {};",
Expand All @@ -418,7 +427,7 @@ public void testTopLevelMutationIsNotMutable() {
" C$$module$testcode = class {};",
"}",
"/** @const */ var module$testcode = {};",
"module$testcode.default = C$$module$testcode;"));
"/** @const */ module$testcode.default = C$$module$testcode;"));
}

public void testExportWithJsDoc() {
Expand All @@ -428,31 +437,31 @@ public void testExportWithJsDoc() {
"/** @constructor */",
"function F$$module$testcode() { return ''; }",
"/** @const */ var module$testcode = {};",
"module$testcode.F = F$$module$testcode;"));
"/** @const */ module$testcode.F = F$$module$testcode;"));

testModules(
"/** @return {string} */\nexport function f() { return '';}",
lines(
"/** @return {string} */",
"function f$$module$testcode() { return ''; }",
"/** @const */ var module$testcode = {};",
"module$testcode.f = f$$module$testcode;"));
"/** @const */ module$testcode.f = f$$module$testcode;"));

testModules(
"/** @return {string} */\nexport var f = function() { return '';}",
lines(
"/** @return {string} */",
"var f$$module$testcode = function() { return ''; }",
"/** @const */ var module$testcode = {};",
"module$testcode.f = f$$module$testcode;"));
"/** @const */ module$testcode.f = f$$module$testcode;"));

testModules(
"/** @type {number} */\nexport var x = 3",
lines(
"/** @type {number} */",
"var x$$module$testcode = 3;",
"/** @const */ var module$testcode = {};",
"module$testcode.x = x$$module$testcode;"));
"/** @const */ module$testcode.x = x$$module$testcode;"));
}

public void testImportAndExport() {
Expand Down Expand Up @@ -515,31 +524,31 @@ public void testExportDefault() {
lines(
"var $jscompDefaultExport$$module$testcode = 'someString';",
"/** @const */ var module$testcode = {};",
"module$testcode.default = $jscompDefaultExport$$module$testcode;"));
"/** @const */ module$testcode.default = $jscompDefaultExport$$module$testcode;"));

testModules(
"var x = 5;\nexport default x;",
lines(
"var x$$module$testcode = 5;",
"var $jscompDefaultExport$$module$testcode = x$$module$testcode;",
"/** @const */ var module$testcode = {};",
"module$testcode.default = $jscompDefaultExport$$module$testcode;"));
"/** @const */ module$testcode.default = $jscompDefaultExport$$module$testcode;"));

testModules(
"export default function f(){};\n var x = f();",
lines(
"function f$$module$testcode() {}",
"var x$$module$testcode = f$$module$testcode();",
"/** @const */ var module$testcode = {};",
"module$testcode.default = f$$module$testcode;"));
"/** @const */ module$testcode.default = f$$module$testcode;"));

testModules(
"export default class Foo {};\n var x = new Foo;",
lines(
"class Foo$$module$testcode {}",
"var x$$module$testcode = new Foo$$module$testcode;",
"/** @const */ var module$testcode = {};",
"module$testcode.default = Foo$$module$testcode;"));
"/** @const */ module$testcode.default = Foo$$module$testcode;"));
}

public void testExportDefault_anonymous() {
Expand All @@ -548,14 +557,14 @@ public void testExportDefault_anonymous() {
lines(
"var $jscompDefaultExport$$module$testcode = class {};",
"/** @const */ var module$testcode = {};",
"module$testcode.default = $jscompDefaultExport$$module$testcode;"));
"/** @const */ module$testcode.default = $jscompDefaultExport$$module$testcode;"));

testModules(
"export default function() {}",
lines(
"var $jscompDefaultExport$$module$testcode = function() {}",
"/** @const */ var module$testcode = {};",
"module$testcode.default = $jscompDefaultExport$$module$testcode;"));
"/** @const */ module$testcode.default = $jscompDefaultExport$$module$testcode;"));
}

public void testExportDestructureDeclaration() {
Expand All @@ -564,25 +573,25 @@ public void testExportDestructureDeclaration() {
lines(
"let {a:a$$module$testcode, c:b$$module$testcode} = obj;",
"/** @const */ var module$testcode = {};",
"module$testcode.a = a$$module$testcode;",
"module$testcode.b = b$$module$testcode;"));
"/** @const */ module$testcode.a = a$$module$testcode;",
"/** @const */ module$testcode.b = b$$module$testcode;"));

testModules(
"export let [a, b] = obj;",
lines(
"let [a$$module$testcode, b$$module$testcode] = obj;",
"/** @const */ var module$testcode = {};",
"module$testcode.a = a$$module$testcode;",
"module$testcode.b = b$$module$testcode;"));
"/** @const */ module$testcode.a = a$$module$testcode;",
"/** @const */ module$testcode.b = b$$module$testcode;"));

testModules(
"export let {a, b:[c,d]} = obj;",
lines(
"let {a:a$$module$testcode, b:[c$$module$testcode, d$$module$testcode]} = obj;",
"/** @const */ var module$testcode = {};",
"module$testcode.a = a$$module$testcode;",
"module$testcode.c = c$$module$testcode;",
"module$testcode.d = d$$module$testcode;"));
"/** @const */ module$testcode.a = a$$module$testcode;",
"/** @const */ module$testcode.c = c$$module$testcode;",
"/** @const */ module$testcode.d = d$$module$testcode;"));
}

public void testExtendImportedClass() {
Expand Down Expand Up @@ -710,7 +719,7 @@ public void testNoInnerChange() {
" return Foo;",
"}();",
"/** @const */ var module$testcode = {};",
"module$testcode.Foo = Foo$$module$testcode;"));
"/** @const */ module$testcode.Foo = Foo$$module$testcode;"));
}

public void testRenameImportedReference() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ public void testDeclareNamespace() {
SourceFile expectedEs6 =
SourceFile.fromCode(
"es6.js",
"var x$$module$es6;/** @const */ var module$es6={};module$es6.x=x$$module$es6;");
lines(
"var x$$module$es6;/** @const */ var module$es6={};",
"/** @const */ module$es6.x=x$$module$es6;"));

test(
srcs(
Expand Down

0 comments on commit 59d1e32

Please sign in to comment.