使用 google 闭包编译器解析 javascript 源代码
Using google closure compiler to parse javascript source
我想使用 google 闭包编译器解析给定的 ES6 源文件,以便构建程序的自定义 'object-oriented' 表示。此表示将包括 源文件中所有 classes 的详细信息以及这些 classes 中包含的方法和变量。我已经为我使用 Antlr - once you have a suitable grammar 的 Java 程序完成了这项任务,您可以为任何所需的语法规则(class 声明、方法声明等)注册进入和退出侦听器,这使得实施相当简单。如果能够使用 google 闭包编译器解析 Java 脚本代码以提取有关源代码的类似信息,我将不胜感激。
到目前为止,我有以下代码可以解析给定的 javascript 源文件:
Compiler compiler = new Compiler();
CompilerOptions options = new CompilerOptions();
options.setIdeMode(true);
compiler.initOptions(options);
Node root = new JsAst(SourceFile.fromCode(file.name(), file.content())).getAstRoot(compiler);
NodeTraversal.traverseEs6(compiler, root, new JavaScriptParsePass());
JavaScriptParsePass class 简单地输出处理的每个节点的类型和限定名称,如下所示:
public class JavaScriptParsePass extends AbstractPostOrderCallback implements CompilerPass {
@Override
public void process(Node externs, Node root) {
}
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
System.out.println(n.getType() + ": " + n.getQualifiedName());
}
}
运行这个程序就输入:
class Model { constructor(properties) { this.properties = properties; }
产生输出:
38: Model
124: null
38: null
38: properties
83: null
42: this
40: null
33: this.properties
38: properties
86: null
130: null
125: null
105: null
160: null
159: null
158: null
132: null`
我希望能对此输出进行解释,因为排序和空值对我来说没有任何意义,以及有关如何解决原始问题的任何一般指导。
您得到的是空值,因为 n.getQualifiedName()
仅适用于名称节点。这将包括变量名称、函数名称、class 名称和属性。对于大多数 AST 节点类型,它不会打印出有意义的数据。
以下代码打印出给定 JavaScript 程序中的所有方法和 classes,并概述了使用 Google 分析 JavaScript 代码的基本方法Closure-Compiler 的 Java API,更多细节见 this post 我写的
首先,我们需要扩展 AbstractShallowCallback class,它提供了一种遍历解析树中节点的方法。我们为访问方法提供了一个实现,如果它是我们感兴趣的节点,它将输出节点的值。
public class JavaScriptAnalyzer extends AbstractShallowCallback {
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
if (n.isClass()) {
System.out.println(n.getFirstChild().getString());
}
if (n.isMemberFunctionDef() || n.isGetterDef() || n.isSetterDef()) {
System.out.println(n.getString());
}
if (n.isFunction()) {
System.out.println(n.getFirstChild().getString());
}
// there is more work required to detect all types of methods that
// has been left out for brevity...
}
}
接下来我们初始化编译器和 运行 我们在给定的 Java 脚本源文件上创建的 Java 脚本分析器。
public void parse(String jsFileContent, String jsName) throws Exception {
Compiler compiler = new Compiler();
CompilerOptions options = new CompilerOptions();
options.setIdeMode(true);
compiler.initOptions(options);
Node root = new JsAst(SourceFile.fromCode(jsName, jsFileContent)).getAstRoot(compiler);
JavaScriptAnalyzer jsListener = new JavaScriptAnalyzer();
NodeTraversal.traverseEs6(compiler, root, jsListener);
}
运行 上面的代码在下面的源文件中:
class Polygon {
constructor(height, width) {}
logWidth() {}
set width(value) {}
get height(value) {}
}
按预期生成以下输出:
constructor
logWidth
width
height
Polygon
我想使用 google 闭包编译器解析给定的 ES6 源文件,以便构建程序的自定义 'object-oriented' 表示。此表示将包括 源文件中所有 classes 的详细信息以及这些 classes 中包含的方法和变量。我已经为我使用 Antlr - once you have a suitable grammar 的 Java 程序完成了这项任务,您可以为任何所需的语法规则(class 声明、方法声明等)注册进入和退出侦听器,这使得实施相当简单。如果能够使用 google 闭包编译器解析 Java 脚本代码以提取有关源代码的类似信息,我将不胜感激。
到目前为止,我有以下代码可以解析给定的 javascript 源文件:
Compiler compiler = new Compiler();
CompilerOptions options = new CompilerOptions();
options.setIdeMode(true);
compiler.initOptions(options);
Node root = new JsAst(SourceFile.fromCode(file.name(), file.content())).getAstRoot(compiler);
NodeTraversal.traverseEs6(compiler, root, new JavaScriptParsePass());
JavaScriptParsePass class 简单地输出处理的每个节点的类型和限定名称,如下所示:
public class JavaScriptParsePass extends AbstractPostOrderCallback implements CompilerPass {
@Override
public void process(Node externs, Node root) {
}
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
System.out.println(n.getType() + ": " + n.getQualifiedName());
}
}
运行这个程序就输入:
class Model { constructor(properties) { this.properties = properties; }
产生输出:
38: Model
124: null
38: null
38: properties
83: null
42: this
40: null
33: this.properties
38: properties
86: null
130: null
125: null
105: null
160: null
159: null
158: null
132: null`
我希望能对此输出进行解释,因为排序和空值对我来说没有任何意义,以及有关如何解决原始问题的任何一般指导。
您得到的是空值,因为 n.getQualifiedName()
仅适用于名称节点。这将包括变量名称、函数名称、class 名称和属性。对于大多数 AST 节点类型,它不会打印出有意义的数据。
以下代码打印出给定 JavaScript 程序中的所有方法和 classes,并概述了使用 Google 分析 JavaScript 代码的基本方法Closure-Compiler 的 Java API,更多细节见 this post 我写的
首先,我们需要扩展 AbstractShallowCallback class,它提供了一种遍历解析树中节点的方法。我们为访问方法提供了一个实现,如果它是我们感兴趣的节点,它将输出节点的值。
public class JavaScriptAnalyzer extends AbstractShallowCallback {
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
if (n.isClass()) {
System.out.println(n.getFirstChild().getString());
}
if (n.isMemberFunctionDef() || n.isGetterDef() || n.isSetterDef()) {
System.out.println(n.getString());
}
if (n.isFunction()) {
System.out.println(n.getFirstChild().getString());
}
// there is more work required to detect all types of methods that
// has been left out for brevity...
}
}
接下来我们初始化编译器和 运行 我们在给定的 Java 脚本源文件上创建的 Java 脚本分析器。
public void parse(String jsFileContent, String jsName) throws Exception {
Compiler compiler = new Compiler();
CompilerOptions options = new CompilerOptions();
options.setIdeMode(true);
compiler.initOptions(options);
Node root = new JsAst(SourceFile.fromCode(jsName, jsFileContent)).getAstRoot(compiler);
JavaScriptAnalyzer jsListener = new JavaScriptAnalyzer();
NodeTraversal.traverseEs6(compiler, root, jsListener);
}
运行 上面的代码在下面的源文件中:
class Polygon {
constructor(height, width) {}
logWidth() {}
set width(value) {}
get height(value) {}
}
按预期生成以下输出:
constructor
logWidth
width
height
Polygon