diff --git a/src/com/google/javascript/jscomp/Es6NormalizeShorthandProperties.java b/src/com/google/javascript/jscomp/Es6NormalizeShorthandProperties.java new file mode 100644 index 00000000000..2f191ec9074 --- /dev/null +++ b/src/com/google/javascript/jscomp/Es6NormalizeShorthandProperties.java @@ -0,0 +1,55 @@ +/* + * Copyright 2017 The Closure Compiler Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.javascript.jscomp; + +import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback; +import com.google.javascript.rhino.IR; +import com.google.javascript.rhino.Node; + +/** + * Normalizes shorthand object properties. This should be one of the first things done when + * transpiling from ES6 down to ES5, as it allows all the following checks and transpilations to not + * care about shorthand and destructured assignments. + */ +public final class Es6NormalizeShorthandProperties extends AbstractPostOrderCallback + implements HotSwapCompilerPass { + private final AbstractCompiler compiler; + + public Es6NormalizeShorthandProperties(AbstractCompiler compiler) { + this.compiler = compiler; + } + + @Override + public void process(Node externs, Node root) { + TranspilationPasses.processTranspile(compiler, externs, this); + TranspilationPasses.processTranspile(compiler, root, this); + } + + @Override + public void hotSwapScript(Node scriptRoot, Node originalRoot) { + TranspilationPasses.hotSwapTranspile(compiler, scriptRoot, this); + } + + @Override + public void visit(NodeTraversal t, Node n, Node parent) { + // Transform keys that look like {foo} into {foo: foo} by adding a NAME node + // with the same string as the only child of any child-less STRING_KEY node. + if (n.isStringKey() && !n.hasChildren()) { + n.addChildToFront(IR.name(n.getString()).useSourceInfoFrom(n)); + compiler.reportChangeToEnclosingScope(n); + } + } +} diff --git a/src/com/google/javascript/jscomp/Es6RewriteBlockScopedDeclaration.java b/src/com/google/javascript/jscomp/Es6RewriteBlockScopedDeclaration.java index 39382b0a314..11fdd802a71 100644 --- a/src/com/google/javascript/jscomp/Es6RewriteBlockScopedDeclaration.java +++ b/src/com/google/javascript/jscomp/Es6RewriteBlockScopedDeclaration.java @@ -41,10 +41,13 @@ import java.util.Set; /** - * Rewrite "let"s and "const"s as "var"s. - * Rename block-scoped declarations and their references when necessary. + * Rewrite "let"s and "const"s as "var"s. Rename block-scoped declarations and their references when + * necessary. * - * TODO(moz): Try to use MakeDeclaredNamesUnique + *
Note that this must run after Es6RewriteDestructuring, since it does not process destructuring + * let/const declarations at all. + * + *
TODO(moz): Try to use MakeDeclaredNamesUnique
*
* @author moz@google.com (Michael Zhou)
*/
diff --git a/src/com/google/javascript/jscomp/LateEs6ToEs3Converter.java b/src/com/google/javascript/jscomp/LateEs6ToEs3Converter.java
index 33ce57cf6db..65bff8aa7d1 100644
--- a/src/com/google/javascript/jscomp/LateEs6ToEs3Converter.java
+++ b/src/com/google/javascript/jscomp/LateEs6ToEs3Converter.java
@@ -118,9 +118,6 @@ public void visit(NodeTraversal t, Node n, Node parent) {
case FOR_OF:
visitForOf(t, n, parent);
break;
- case STRING_KEY:
- visitStringKey(n);
- break;
case TAGGED_TEMPLATELIT:
Es6TemplateLiterals.visitTaggedTemplateLiteral(t, n, addTypes);
break;
@@ -148,19 +145,6 @@ private void visitMemberFunctionDefInObjectLit(Node n, Node parent) {
compiler.reportChangeToEnclosingScope(stringKey);
}
- /**
- * Converts extended object literal {a} to {a:a}.
- */
- // TODO(blickly): Separate this so it can be part of the normalization early transpilation passes.
- private void visitStringKey(Node n) {
- if (!n.hasChildren()) {
- Node name = withType(IR.name(n.getString()), n.getTypeI());
- name.useSourceInfoIfMissingFrom(n);
- n.addChildToBack(name);
- compiler.reportChangeToEnclosingScope(name);
- }
- }
-
private void visitForOf(NodeTraversal t, Node node, Node parent) {
Node variable = node.removeFirstChild();
Node iterable = node.removeFirstChild();
@@ -367,4 +351,3 @@ private Node withUnknownType(Node n) {
return withType(n, unknownType);
}
}
-
diff --git a/src/com/google/javascript/jscomp/NodeUtil.java b/src/com/google/javascript/jscomp/NodeUtil.java
index ff960a72148..e6cc9ab0790 100644
--- a/src/com/google/javascript/jscomp/NodeUtil.java
+++ b/src/com/google/javascript/jscomp/NodeUtil.java
@@ -2704,11 +2704,19 @@ static boolean isSwitchCase(Node n) {
}
/**
- * @return Whether the name is a reference to a variable, function or
- * function parameter (not a label or a empty function expression name).
+ * @return Whether the node is a reference to a variable, function or
+ * function parameter (not a label or a empty function expression name).
+ * This includes both NAME nodes and shorthand property STRING_KEYs.
*/
static boolean isReferenceName(Node n) {
- return n.isName() && !n.getString().isEmpty();
+ return (n.isName() && !n.getString().isEmpty()) || isShorthandProperty(n);
+ }
+
+ /**
+ * @return Whether the node is a shorthand property.
+ */
+ static boolean isShorthandProperty(Node n) {
+ return n.isStringKey() && !n.hasChildren();
}
/**
diff --git a/src/com/google/javascript/jscomp/TranspilationPasses.java b/src/com/google/javascript/jscomp/TranspilationPasses.java
index 4c0bc5c8a69..c4c670e86a4 100644
--- a/src/com/google/javascript/jscomp/TranspilationPasses.java
+++ b/src/com/google/javascript/jscomp/TranspilationPasses.java
@@ -51,6 +51,7 @@ public static void addEs2016Passes(List