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

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

Issue 557633002: 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: report missing declarations 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 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 c7f3c12daccb071f705a6a6a9c896653b3045a37..fd9821451507d5103cbff4c9908e4d8b722f3808 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
@@ -37,6 +37,7 @@ public class ChromePass extends AbstractPostOrderCallback implements CompilerPas
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_MAKE_PUBLIC = "cr.makePublic";
private static final String CR_DEFINE_COMMON_EXPLANATION = "It should be called like this:"
+ " cr.define('name.space', function() '{ ... return {Export: Internal}; }');";
@@ -67,6 +68,14 @@ public class ChromePass extends AbstractPostOrderCallback implements CompilerPas
"Invalid cr.PropertyKind passed to cr.defineProperty(): expected ATTR,"
+ " BOOL_ATTR or JS, found \"{0}\".");
+ static final DiagnosticType CR_MAKE_PUBLIC_HAS_NO_JSDOC =
+ DiagnosticType.error("JSC_CR_MAKE_PUBLIC_HAS_NO_JSDOC",
+ "Private method exported by cr.makePublic() has no JSDoc.");
+
+ static final DiagnosticType CR_MAKE_PUBLIC_MISSED_DECLARATION =
+ DiagnosticType.error("CR_MAKE_PUBLIC_MISSED_DECLARATION",
+ "Method \"{1}_\" exported by cr.makePublic() on \"{0}\" has no declaration.");
+
public ChromePass(AbstractCompiler compiler) {
this.compiler = compiler;
// The global variable "cr" is declared in ui/webui/resources/js/cr.js.
@@ -92,6 +101,10 @@ public class ChromePass extends AbstractPostOrderCallback implements CompilerPas
callee.matchesQualifiedName(CR_DEFINE_PROPERTY)) {
visitPropertyDefinition(node, parent);
compiler.reportCodeChange();
+ } else if (callee.matchesQualifiedName(CR_MAKE_PUBLIC)) {
+ if (visitMakePublic(node, parent)) {
+ compiler.reportCodeChange();
+ }
}
}
}
@@ -140,6 +153,62 @@ public class ChromePass extends AbstractPostOrderCallback implements CompilerPas
target.setJSDocInfo(builder.build(target));
}
+ private boolean visitMakePublic(Node call, Node exprResult) {
+ boolean changesMade = false;
+ Node scope = exprResult.getParent();
+ String className = call.getChildAtIndex(1).getQualifiedName();
+ String prototype = className + ".prototype";
+ Node publicAPI = call.getChildAtIndex(2);
+
+ assert publicAPI != null && publicAPI.isArrayLit();
+
+ Set<String> publicAPIStrings = new HashSet<>();
+ for (Node methodName: publicAPI.children()) {
+ assert methodName.isString();
+ publicAPIStrings.add(methodName.getString());
+ }
+
+ for (Node child: scope.children()) {
+ if (isAssignmentToPrototype(child, prototype)) {
+ Node objectLit = child.getFirstChild().getChildAtIndex(1);
+ for (Node stringKey : objectLit.children()) {
+ String field = stringKey.getString();
+ if (field.endsWith("_")) {
+ String publicName = field.substring(0, field.length() - 1);
+ if (publicAPIStrings.contains(publicName)) {
+ Node methodDeclaration = NodeUtil.newQualifiedNameNode(
+ compiler.getCodingConvention(), className + "." + publicName);
+ if (stringKey.getJSDocInfo() != null) {
+ methodDeclaration.setJSDocInfo(stringKey.getJSDocInfo());
+ scope.addChildBefore(
+ IR.exprResult(methodDeclaration).srcrefTree(exprResult),
+ exprResult);
+ changesMade = true;
+ } else {
+ compiler.report(JSError.make(stringKey,
+ CR_MAKE_PUBLIC_HAS_NO_JSDOC));
+ }
+ publicAPIStrings.remove(publicName);
+ }
+ }
+ }
+ }
+ }
+
+ for (String missedDeclaration : publicAPIStrings) {
+ compiler.report(JSError.make(exprResult, CR_MAKE_PUBLIC_MISSED_DECLARATION, className,
+ missedDeclaration));
+ }
+
+ return changesMade;
+ }
+
+ private boolean isAssignmentToPrototype(Node node, String prototype) {
+ Node assignNode;
+ return node.isExprResult() && (assignNode = node.getFirstChild()).isAssign() &&
+ assignNode.getFirstChild().getQualifiedName().equals(prototype);
+ }
+
private void visitExportPath(Node crExportPathNode, Node parent) {
if (crExportPathNode.getChildCount() != 2) {
compiler.report(JSError.make(crExportPathNode,
@@ -342,5 +411,4 @@ public class ChromePass extends AbstractPostOrderCallback implements CompilerPas
this.namespaceName + "." + externalName).srcrefTree(internalName);
}
}
-
}

Powered by Google App Engine
This is Rietveld 408576698