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

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

Issue 577843003: Revert of Add public API generation with cr.makePublic() and handle it in compiler pass (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@H_options_errors_3
Patch Set: Created 6 years, 3 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package com.google.javascript.jscomp; 5 package com.google.javascript.jscomp;
6 6
7 import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback; 7 import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
8 import com.google.javascript.rhino.IR; 8 import com.google.javascript.rhino.IR;
9 import com.google.javascript.rhino.JSDocInfoBuilder; 9 import com.google.javascript.rhino.JSDocInfoBuilder;
10 import com.google.javascript.rhino.JSTypeExpression; 10 import com.google.javascript.rhino.JSTypeExpression;
(...skipping 19 matching lines...) Expand all
30 */ 30 */
31 public class ChromePass extends AbstractPostOrderCallback implements CompilerPas s { 31 public class ChromePass extends AbstractPostOrderCallback implements CompilerPas s {
32 final AbstractCompiler compiler; 32 final AbstractCompiler compiler;
33 33
34 private Set<String> createdObjects; 34 private Set<String> createdObjects;
35 35
36 private static final String CR_DEFINE = "cr.define"; 36 private static final String CR_DEFINE = "cr.define";
37 private static final String CR_EXPORT_PATH = "cr.exportPath"; 37 private static final String CR_EXPORT_PATH = "cr.exportPath";
38 private static final String OBJECT_DEFINE_PROPERTY = "Object.defineProperty" ; 38 private static final String OBJECT_DEFINE_PROPERTY = "Object.defineProperty" ;
39 private static final String CR_DEFINE_PROPERTY = "cr.defineProperty"; 39 private static final String CR_DEFINE_PROPERTY = "cr.defineProperty";
40 private static final String CR_MAKE_PUBLIC = "cr.makePublic";
41 40
42 private static final String CR_DEFINE_COMMON_EXPLANATION = "It should be cal led like this:" 41 private static final String CR_DEFINE_COMMON_EXPLANATION = "It should be cal led like this:"
43 + " cr.define('name.space', function() '{ ... return {Export: Intern al}; }');"; 42 + " cr.define('name.space', function() '{ ... return {Export: Intern al}; }');";
44 43
45 static final DiagnosticType CR_DEFINE_WRONG_NUMBER_OF_ARGUMENTS = 44 static final DiagnosticType CR_DEFINE_WRONG_NUMBER_OF_ARGUMENTS =
46 DiagnosticType.error("JSC_CR_DEFINE_WRONG_NUMBER_OF_ARGUMENTS", 45 DiagnosticType.error("JSC_CR_DEFINE_WRONG_NUMBER_OF_ARGUMENTS",
47 "cr.define() should have exactly 2 arguments. " + CR_DEFINE_ COMMON_EXPLANATION); 46 "cr.define() should have exactly 2 arguments. " + CR_DEFINE_ COMMON_EXPLANATION);
48 47
49 static final DiagnosticType CR_EXPORT_PATH_WRONG_NUMBER_OF_ARGUMENTS = 48 static final DiagnosticType CR_EXPORT_PATH_WRONG_NUMBER_OF_ARGUMENTS =
50 DiagnosticType.error("JSC_CR_EXPORT_PATH_WRONG_NUMBER_OF_ARGUMENTS", 49 DiagnosticType.error("JSC_CR_EXPORT_PATH_WRONG_NUMBER_OF_ARGUMENTS",
(...skipping 10 matching lines...) Expand all
61 static final DiagnosticType CR_DEFINE_INVALID_RETURN_IN_FUNCTION = 60 static final DiagnosticType CR_DEFINE_INVALID_RETURN_IN_FUNCTION =
62 DiagnosticType.error("JSC_CR_DEFINE_INVALID_RETURN_IN_SECOND_ARGUMEN T", 61 DiagnosticType.error("JSC_CR_DEFINE_INVALID_RETURN_IN_SECOND_ARGUMEN T",
63 "Function passed as second argument of cr.define() should re turn the" 62 "Function passed as second argument of cr.define() should re turn the"
64 + " dictionary in its last statement. " + CR_DEFINE_COMMON_E XPLANATION); 63 + " dictionary in its last statement. " + CR_DEFINE_COMMON_E XPLANATION);
65 64
66 static final DiagnosticType CR_DEFINE_PROPERTY_INVALID_PROPERTY_KIND = 65 static final DiagnosticType CR_DEFINE_PROPERTY_INVALID_PROPERTY_KIND =
67 DiagnosticType.error("JSC_CR_DEFINE_PROPERTY_INVALID_PROPERTY_KIND", 66 DiagnosticType.error("JSC_CR_DEFINE_PROPERTY_INVALID_PROPERTY_KIND",
68 "Invalid cr.PropertyKind passed to cr.defineProperty(): expe cted ATTR," 67 "Invalid cr.PropertyKind passed to cr.defineProperty(): expe cted ATTR,"
69 + " BOOL_ATTR or JS, found \"{0}\"."); 68 + " BOOL_ATTR or JS, found \"{0}\".");
70 69
71 static final DiagnosticType CR_MAKE_PUBLIC_HAS_NO_JSDOC =
72 DiagnosticType.error("JSC_CR_MAKE_PUBLIC_HAS_NO_JSDOC",
73 "Private method exported by cr.makePublic() has no JSDoc.");
74
75 static final DiagnosticType CR_MAKE_PUBLIC_MISSED_DECLARATION =
76 DiagnosticType.error("JSC_CR_MAKE_PUBLIC_MISSED_DECLARATION",
77 "Method \"{1}_\" exported by cr.makePublic() on \"{0}\" has no declaration.");
78
79 static final DiagnosticType CR_MAKE_PUBLIC_INVALID_SECOND_ARGUMENT =
80 DiagnosticType.error("JSC_CR_MAKE_PUBLIC_INVALID_SECOND_ARGUMENT",
81 "Invalid second argument passed to cr.makePublic(): should b e array of " +
82 "strings.");
83
84 public ChromePass(AbstractCompiler compiler) { 70 public ChromePass(AbstractCompiler compiler) {
85 this.compiler = compiler; 71 this.compiler = compiler;
86 // The global variable "cr" is declared in ui/webui/resources/js/cr.js. 72 // The global variable "cr" is declared in ui/webui/resources/js/cr.js.
87 this.createdObjects = new HashSet<>(Arrays.asList("cr")); 73 this.createdObjects = new HashSet<>(Arrays.asList("cr"));
88 } 74 }
89 75
90 @Override 76 @Override
91 public void process(Node externs, Node root) { 77 public void process(Node externs, Node root) {
92 NodeTraversal.traverse(compiler, root, this); 78 NodeTraversal.traverse(compiler, root, this);
93 } 79 }
94 80
95 @Override 81 @Override
96 public void visit(NodeTraversal t, Node node, Node parent) { 82 public void visit(NodeTraversal t, Node node, Node parent) {
97 if (node.isCall()) { 83 if (node.isCall()) {
98 Node callee = node.getFirstChild(); 84 Node callee = node.getFirstChild();
99 if (callee.matchesQualifiedName(CR_DEFINE)) { 85 if (callee.matchesQualifiedName(CR_DEFINE)) {
100 visitNamespaceDefinition(node, parent); 86 visitNamespaceDefinition(node, parent);
101 compiler.reportCodeChange(); 87 compiler.reportCodeChange();
102 } else if (callee.matchesQualifiedName(CR_EXPORT_PATH)) { 88 } else if (callee.matchesQualifiedName(CR_EXPORT_PATH)) {
103 visitExportPath(node, parent); 89 visitExportPath(node, parent);
104 compiler.reportCodeChange(); 90 compiler.reportCodeChange();
105 } else if (callee.matchesQualifiedName(OBJECT_DEFINE_PROPERTY) || 91 } else if (callee.matchesQualifiedName(OBJECT_DEFINE_PROPERTY) ||
106 callee.matchesQualifiedName(CR_DEFINE_PROPERTY)) { 92 callee.matchesQualifiedName(CR_DEFINE_PROPERTY)) {
107 visitPropertyDefinition(node, parent); 93 visitPropertyDefinition(node, parent);
108 compiler.reportCodeChange(); 94 compiler.reportCodeChange();
109 } else if (callee.matchesQualifiedName(CR_MAKE_PUBLIC)) {
110 if (visitMakePublic(node, parent)) {
111 compiler.reportCodeChange();
112 }
113 } 95 }
114 } 96 }
115 } 97 }
116 98
117 private void visitPropertyDefinition(Node call, Node parent) { 99 private void visitPropertyDefinition(Node call, Node parent) {
118 Node callee = call.getFirstChild(); 100 Node callee = call.getFirstChild();
119 String target = call.getChildAtIndex(1).getQualifiedName(); 101 String target = call.getChildAtIndex(1).getQualifiedName();
120 if (callee.matchesQualifiedName(CR_DEFINE_PROPERTY) && !target.endsWith( ".prototype")) { 102 if (callee.matchesQualifiedName(CR_DEFINE_PROPERTY) && !target.endsWith( ".prototype")) {
121 target += ".prototype"; 103 target += ".prototype";
122 } 104 }
(...skipping 28 matching lines...) Expand all
151 propertyKind.getQualifiedName())); 133 propertyKind.getQualifiedName()));
152 return null; 134 return null;
153 } 135 }
154 136
155 private void setJsDocWithType(Node target, Node type) { 137 private void setJsDocWithType(Node target, Node type) {
156 JSDocInfoBuilder builder = new JSDocInfoBuilder(false); 138 JSDocInfoBuilder builder = new JSDocInfoBuilder(false);
157 builder.recordType(new JSTypeExpression(type, "")); 139 builder.recordType(new JSTypeExpression(type, ""));
158 target.setJSDocInfo(builder.build(target)); 140 target.setJSDocInfo(builder.build(target));
159 } 141 }
160 142
161 private boolean visitMakePublic(Node call, Node exprResult) {
162 boolean changesMade = false;
163 Node scope = exprResult.getParent();
164 String className = call.getChildAtIndex(1).getQualifiedName();
165 String prototype = className + ".prototype";
166 Node methods = call.getChildAtIndex(2);
167
168 if (methods == null || !methods.isArrayLit()) {
169 compiler.report(JSError.make(exprResult, CR_MAKE_PUBLIC_INVALID_SECO ND_ARGUMENT));
170 return changesMade;
171 }
172
173 Set<String> methodNames = new HashSet<>();
174 for (Node methodName: methods.children()) {
175 if (!methodName.isString()) {
176 compiler.report(JSError.make(methodName, CR_MAKE_PUBLIC_INVALID_ SECOND_ARGUMENT));
177 return changesMade;
178 }
179 methodNames.add(methodName.getString());
180 }
181
182 for (Node child: scope.children()) {
183 if (isAssignmentToPrototype(child, prototype)) {
184 Node objectLit = child.getFirstChild().getChildAtIndex(1);
185 for (Node stringKey : objectLit.children()) {
186 String field = stringKey.getString();
187 changesMade |= maybeAddPublicDeclaration(field, methodNames, className,
188 stringKey, scope, e xprResult);
189 }
190 } else if (isAssignmentToPrototypeMethod(child, prototype)) {
191 Node assignNode = child.getFirstChild();
192 String qualifiedName = assignNode.getFirstChild().getQualifiedNa me();
193 String field = qualifiedName.substring(qualifiedName.lastIndexOf ('.') + 1);
194 changesMade |= maybeAddPublicDeclaration(field, methodNames, cla ssName,
195 assignNode, scope, expr Result);
196 } else if (isDummyPrototypeMethodDeclaration(child, prototype)) {
197 String qualifiedName = child.getFirstChild().getQualifiedName();
198 String field = qualifiedName.substring(qualifiedName.lastIndexOf ('.') + 1);
199 changesMade |= maybeAddPublicDeclaration(field, methodNames, cla ssName,
200 child.getFirstChild(), scope, exprResult);
201 }
202 }
203
204 for (String missedDeclaration : methodNames) {
205 compiler.report(JSError.make(exprResult, CR_MAKE_PUBLIC_MISSED_DECLA RATION, className,
206 missedDeclaration));
207 }
208
209 return changesMade;
210 }
211
212 private boolean isAssignmentToPrototype(Node node, String prototype) {
213 Node assignNode;
214 return node.isExprResult() && (assignNode = node.getFirstChild()).isAssi gn() &&
215 assignNode.getFirstChild().getQualifiedName().equals(prototype);
216 }
217
218 private boolean isAssignmentToPrototypeMethod(Node node, String prototype) {
219 Node assignNode;
220 return node.isExprResult() && (assignNode = node.getFirstChild()).isAssi gn() &&
221 assignNode.getFirstChild().getQualifiedName().startsWith(prototy pe + ".");
222 }
223
224 private boolean isDummyPrototypeMethodDeclaration(Node node, String prototyp e) {
225 Node getPropNode;
226 return node.isExprResult() && (getPropNode = node.getFirstChild()).isGet Prop() &&
227 getPropNode.getQualifiedName().startsWith(prototype + ".");
228 }
229
230 private boolean maybeAddPublicDeclaration(String field, Set<String> publicAP IStrings,
231 String className, Node jsDocSourceNode, Node scope, Node exprResult) {
232 boolean changesMade = false;
233 if (field.endsWith("_")) {
234 String publicName = field.substring(0, field.length() - 1);
235 if (publicAPIStrings.contains(publicName)) {
236 Node methodDeclaration = NodeUtil.newQualifiedNameNode(
237 compiler.getCodingConvention(), className + "." + public Name);
238 if (jsDocSourceNode.getJSDocInfo() != null) {
239 methodDeclaration.setJSDocInfo(jsDocSourceNode.getJSDocInfo( ));
240 scope.addChildBefore(
241 IR.exprResult(methodDeclaration).srcrefTree(exprResu lt),
242 exprResult);
243 changesMade = true;
244 } else {
245 compiler.report(JSError.make(jsDocSourceNode, CR_MAKE_PUBLIC _HAS_NO_JSDOC));
246 }
247 publicAPIStrings.remove(publicName);
248 }
249 }
250 return changesMade;
251 }
252
253 private void visitExportPath(Node crExportPathNode, Node parent) { 143 private void visitExportPath(Node crExportPathNode, Node parent) {
254 if (crExportPathNode.getChildCount() != 2) { 144 if (crExportPathNode.getChildCount() != 2) {
255 compiler.report(JSError.make(crExportPathNode, 145 compiler.report(JSError.make(crExportPathNode,
256 CR_EXPORT_PATH_WRONG_NUMBER_OF_ARGUMENTS)); 146 CR_EXPORT_PATH_WRONG_NUMBER_OF_ARGUMENTS));
257 return; 147 return;
258 } 148 }
259 149
260 createAndInsertObjectsForQualifiedName(parent, 150 createAndInsertObjectsForQualifiedName(parent,
261 crExportPathNode.getChildAtIndex(1).getString()); 151 crExportPathNode.getChildAtIndex(1).getString());
262 } 152 }
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 } 335 }
446 } 336 }
447 } 337 }
448 338
449 private Node buildQualifiedName(Node internalName) { 339 private Node buildQualifiedName(Node internalName) {
450 String externalName = this.exports.get(internalName.getString()); 340 String externalName = this.exports.get(internalName.getString());
451 return NodeUtil.newQualifiedNameNode(compiler.getCodingConvention(), 341 return NodeUtil.newQualifiedNameNode(compiler.getCodingConvention(),
452 this.namespaceName + "." + externalName).srcrefTree(internal Name); 342 this.namespaceName + "." + externalName).srcrefTree(internal Name);
453 } 343 }
454 } 344 }
345
455 } 346 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698