diff --git a/src/com/google/javascript/jscomp/Es6RewriteModules.java b/src/com/google/javascript/jscomp/Es6RewriteModules.java index 19e01f57c85..f6e7ee799f5 100644 --- a/src/com/google/javascript/jscomp/Es6RewriteModules.java +++ b/src/com/google/javascript/jscomp/Es6RewriteModules.java @@ -330,39 +330,54 @@ private void visitExport(NodeTraversal t, Node export, Node parent) { } parent.removeChild(export); } else { - // export var Foo; - // export function Foo() {} - // etc. - Node declaration = export.getFirstChild(); - Node first = declaration.getFirstChild(); - for (Node maybeName = first; maybeName != null; maybeName = maybeName.getNext()) { - if (!maybeName.isName()) { - break; - } - // Break out on "B" in "class A extends B" - if (declaration.isClass() && maybeName != first) { - break; - } - String name = maybeName.getString(); - exportsByLocalName.put(name, new NameNodePair(name, maybeName)); - - // 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); - } - if (declaration.getJSDocInfo() != null && declaration.getJSDocInfo().hasTypedefType()) { - typedefs.add(name); - } - } - parent.replaceChild(export, declaration.detach()); + visitExportDeclaration(t, export, parent); } t.reportCodeChange(); } } + private void visitExportNameDeclaration(Node declaration) { + // export var Foo; + // export let {a, b:[c,d]} = {}; + List lhsNodes = NodeUtil.findLhsNodesInNode(declaration); + + for (Node lhs : lhsNodes) { + checkState(lhs.isName()); + String name = lhs.getString(); + exportsByLocalName.put(name, new NameNodePair(name, lhs)); + + if (declaration.getJSDocInfo() != null && declaration.getJSDocInfo().hasTypedefType()) { + typedefs.add(name); + } + } + } + + private void visitExportDeclaration(NodeTraversal t, Node export, Node parent) { + // export var Foo; + // export function Foo() {} + // etc. + Node declaration = export.getFirstChild(); + + if (NodeUtil.isNameDeclaration(declaration)) { + visitExportNameDeclaration(declaration); + } else { + checkState(declaration.isFunction() || declaration.isClass()); + String name = declaration.getFirstChild().getString(); + exportsByLocalName.put(name, new NameNodePair(name, declaration)); + + // 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()); + t.reportCodeChange(); + } + private void inlineModuleToGlobalScope(Node moduleNode) { checkState(moduleNode.isModuleBody()); Node scriptNode = moduleNode.getParent(); diff --git a/test/com/google/javascript/jscomp/Es6RewriteModulesTest.java b/test/com/google/javascript/jscomp/Es6RewriteModulesTest.java index 630d6970381..2de2b0abc2c 100644 --- a/test/com/google/javascript/jscomp/Es6RewriteModulesTest.java +++ b/test/com/google/javascript/jscomp/Es6RewriteModulesTest.java @@ -516,6 +516,33 @@ public void testExportDefault_anonymous() { "module$testcode.default = $jscompDefaultExport$$module$testcode;")); } + public void testExportDestructureDeclaration() { + testModules( + "export let {a, c:b} = obj;", + 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;")); + + 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;")); + + 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;")); + } + public void testExtendImportedClass() { testModules( lines(