Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Unified Diff: third_party/closure_compiler/runner/src/com/google/javascript/jscomp/ChromePass.java

Issue 453783006: Handle cr.exportPath() in compiler pass, declare every object only once (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@C_define_property
Patch Set: rebase Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/closure_compiler/runner/src/com/google/javascript/jscomp/ChromePass.java
diff --git a/third_party/closure_compiler/runner/src/com/google/javascript/jscomp/ChromePass.java b/third_party/closure_compiler/runner/src/com/google/javascript/jscomp/ChromePass.java
index 9e2ef3f62fded3616a48061a3e28eca8ac45c9ef..436fabae734380ebfca2e21feb0400023cc9afd2 100644
--- a/third_party/closure_compiler/runner/src/com/google/javascript/jscomp/ChromePass.java
+++ b/third_party/closure_compiler/runner/src/com/google/javascript/jscomp/ChromePass.java
@@ -12,9 +12,12 @@ import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.Token;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Compiler pass for Chrome-specific needs. It handles the following Chrome JS features:
@@ -28,10 +31,11 @@ import java.util.Map;
public class ChromePass extends AbstractPostOrderCallback implements CompilerPass {
final AbstractCompiler compiler;
- private static final String CR_DEFINE = "cr.define";
+ private Set<String> createdObjects;
+ private static final String CR_DEFINE = "cr.define";
+ private static final String CR_EXPORT_PATH = "cr.exportPath";
private static final String OBJECT_DEFINE_PROPERTY = "Object.defineProperty";
-
private static final String CR_DEFINE_PROPERTY = "cr.defineProperty";
private static final String CR_DEFINE_COMMON_EXPLANATION = "It should be called like this:"
@@ -41,6 +45,10 @@ public class ChromePass extends AbstractPostOrderCallback implements CompilerPas
DiagnosticType.error("JSC_CR_DEFINE_WRONG_NUMBER_OF_ARGUMENTS",
"cr.define() should have exactly 2 arguments. " + CR_DEFINE_COMMON_EXPLANATION);
+ static final DiagnosticType CR_EXPORT_PATH_WRONG_NUMBER_OF_ARGUMENTS =
+ DiagnosticType.error("JSC_CR_EXPORT_PATH_WRONG_NUMBER_OF_ARGUMENTS",
+ "cr.exportPath() should have exactly 1 argument: namespace name.");
+
static final DiagnosticType CR_DEFINE_INVALID_FIRST_ARGUMENT =
DiagnosticType.error("JSC_CR_DEFINE_INVALID_FIRST_ARGUMENT",
"Invalid first argument for cr.define(). " + CR_DEFINE_COMMON_EXPLANATION);
@@ -61,6 +69,8 @@ public class ChromePass extends AbstractPostOrderCallback implements CompilerPas
public ChromePass(AbstractCompiler compiler) {
this.compiler = compiler;
+ // The global variable "cr" is declared in ui/webui/resources/js/cr.js.
+ this.createdObjects = new HashSet<>(Arrays.asList("cr"));
}
@Override
@@ -75,6 +85,9 @@ public class ChromePass extends AbstractPostOrderCallback implements CompilerPas
if (callee.matchesQualifiedName(CR_DEFINE)) {
visitNamespaceDefinition(node, parent);
compiler.reportCodeChange();
+ } else if (callee.matchesQualifiedName(CR_EXPORT_PATH)) {
+ visitExportPath(node, parent);
+ compiler.reportCodeChange();
} else if (callee.matchesQualifiedName(OBJECT_DEFINE_PROPERTY) ||
callee.matchesQualifiedName(CR_DEFINE_PROPERTY)) {
visitPropertyDefinition(node, parent);
@@ -127,6 +140,24 @@ public class ChromePass extends AbstractPostOrderCallback implements CompilerPas
target.setJSDocInfo(builder.build(target));
}
+ private void visitExportPath(Node crExportPathNode, Node parent) {
+ if (crExportPathNode.getChildCount() != 2) {
+ compiler.report(JSError.make(crExportPathNode,
+ CR_EXPORT_PATH_WRONG_NUMBER_OF_ARGUMENTS));
+ return;
+ }
+
+ createAndInsertObjectsForQualifiedName(parent,
+ crExportPathNode.getChildAtIndex(1).getString());
+ }
+
+ private void createAndInsertObjectsForQualifiedName(Node scriptChild, String namespace) {
+ List<Node> objectsForQualifiedName = createObjectsForQualifiedName(namespace);
+ for (Node n : objectsForQualifiedName) {
+ scriptChild.getParent().addChildBefore(n, scriptChild);
+ }
+ }
+
private void visitNamespaceDefinition(Node crDefineCallNode, Node parent) {
if (crDefineCallNode.getChildCount() != 3) {
compiler.report(JSError.make(crDefineCallNode, CR_DEFINE_WRONG_NUMBER_OF_ARGUMENTS));
@@ -144,10 +175,7 @@ public class ChromePass extends AbstractPostOrderCallback implements CompilerPas
// identifiers.
String namespace = namespaceArg.getString();
- List<Node> objectsForQualifiedName = createObjectsForQualifiedName(namespace);
- for (Node n : objectsForQualifiedName) {
- parent.getParent().addChildBefore(n, parent);
- }
+ createAndInsertObjectsForQualifiedName(parent, namespace);
if (!function.isFunction()) {
compiler.report(JSError.make(namespaceArg, CR_DEFINE_INVALID_SECOND_ARGUMENT));
@@ -198,20 +226,26 @@ public class ChromePass extends AbstractPostOrderCallback implements CompilerPas
List<Node> objects = new ArrayList<>();
String[] parts = namespace.split("\\.");
- objects.add(createJsNode("var " + parts[0] + " = " + parts[0] + " || {};"));
+ createObjectIfNew(objects, parts[0], true);
if (parts.length >= 2) {
StringBuilder currPrefix = new StringBuilder().append(parts[0]);
for (int i = 1; i < parts.length; ++i) {
currPrefix.append(".").append(parts[i]);
- String code = currPrefix + " = " + currPrefix + " || {};";
- objects.add(createJsNode(code));
+ createObjectIfNew(objects, currPrefix.toString(), false);
}
}
return objects;
}
+ private void createObjectIfNew(List<Node> objects, String name, boolean needVar) {
+ if (!createdObjects.contains(name)) {
+ objects.add(createJsNode((needVar ? "var " : "") + name + " = " + name + " || {};"));
+ createdObjects.add(name);
+ }
+ }
+
private Node createJsNode(String code) {
// The parent node after parseSyntheticCode() is SCRIPT node, we need to get rid of it.
return compiler.parseSyntheticCode(code).removeFirstChild();

Powered by Google App Engine
This is Rietveld 408576698