Skip to content

Instantly share code, notes, and snippets.

@leeight
Last active December 27, 2015 07:19
Show Gist options
  • Save leeight/7288556 to your computer and use it in GitHub Desktop.
Save leeight/7288556 to your computer and use it in GitHub Desktop.
Using closure-compiler to parse js file and extract the desired docs.
package com.baidu.lego.server.utils;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.google.gson.JsonPrimitive;
import com.google.javascript.jscomp.Compiler;
import com.google.javascript.jscomp.CompilerOptions;
import com.google.javascript.jscomp.CompilerPass;
import com.google.javascript.jscomp.JsAst;
import com.google.javascript.jscomp.NodeTraversal;
import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
import com.google.javascript.jscomp.SourceFile;
import com.google.javascript.rhino.JSDocInfo;
import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.Token;
class FlagDefinitions {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
private String name;
private String description;
private String type;
private JsonPrimitive defaultValue;
public JsonPrimitive getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(JsonPrimitive defaultValue) {
this.defaultValue = defaultValue;
}
}
class CheckFlagsPass extends AbstractPostOrderCallback implements CompilerPass {
private List<FlagDefinitions> defs;
public List<FlagDefinitions> getDefs() {
return defs;
}
public CheckFlagsPass() {
defs = new ArrayList<FlagDefinitions>();
}
@Override
public void process(Node externs, Node root) {
}
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
if (n.getType() == Token.NAME && n.getString().startsWith("FLAGS_")) {
JSDocInfo doc = parent.getJSDocInfo();
if (doc != null) {
Node value = n.getLastChild();
JsonPrimitive defaultValue = null;
if (value.getType() == Token.NUMBER) {
defaultValue = new JsonPrimitive(value.getDouble());
} else if (value.getType() == Token.STRING) {
defaultValue = new JsonPrimitive(value.getString());
} else if (value.getType() == Token.TRUE) {
defaultValue = new JsonPrimitive(true);
} else if (value.getType() == Token.FALSE) {
defaultValue = new JsonPrimitive(false);
} else {
// Invalid @define type.
return;
}
FlagDefinitions def = new FlagDefinitions();
def.setName(n.getString());
def.setDescription(doc.getBlockDescription());
def.setType(doc.getMarkers().iterator().next().getType()
.getItem().getString());
def.setDefaultValue(defaultValue);
defs.add(def);
}
}
}
}
public class DynamicFlagsTest {
@Test
public void testGetJsDocInfo() {
Compiler compiler = new Compiler();
CompilerOptions options = new CompilerOptions();
options.ideMode = true;
compiler.initOptions(options);
String fileName = "/Volumes/HDD/Users/leeight/local/app/ecom/lego/git/lego/lego-widgets/src/ad/flags.js";
Node root = new JsAst(SourceFile.fromFile(fileName))
.getAstRoot(compiler);
CheckFlagsPass pass = new CheckFlagsPass();
NodeTraversal.traverse(compiler, root, pass);
System.out.println(JsonUtils.toPrettyPrintJson(pass.getDefs()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment