Prototyping DCE tool for JS
This commit is contained in:
@@ -32,9 +32,13 @@ public class JsAstMapper {
|
||||
private final JsProgram program;
|
||||
private final ScopeContext scopeContext;
|
||||
|
||||
public JsAstMapper(@NotNull JsScope scope) {
|
||||
@NotNull
|
||||
private final String fileName;
|
||||
|
||||
public JsAstMapper(@NotNull JsScope scope, @NotNull String fileName) {
|
||||
scopeContext = new ScopeContext(scope);
|
||||
program = scope.getProgram();
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
private static JsParserException createParserException(String msg, Node offender) {
|
||||
@@ -43,6 +47,10 @@ public class JsAstMapper {
|
||||
}
|
||||
|
||||
private JsNode map(Node node) throws JsParserException {
|
||||
return withLocation(mapWithoutLocation(node), node);
|
||||
}
|
||||
|
||||
private JsNode mapWithoutLocation(Node node) throws JsParserException {
|
||||
switch (node.getType()) {
|
||||
case TokenStream.SCRIPT: {
|
||||
JsBlock block = new JsBlock();
|
||||
@@ -1115,4 +1123,18 @@ public class JsAstMapper {
|
||||
int type = jsNode.getType();
|
||||
return type == TokenStream.NUMBER || type == TokenStream.NUMBER;
|
||||
}
|
||||
|
||||
private <T extends JsNode> T withLocation(T astNode, Node node) {
|
||||
int lineNumber = node.getLineno();
|
||||
if (lineNumber >= 0) {
|
||||
JsLocation location = new JsLocation(fileName, lineNumber, 0);
|
||||
if (astNode instanceof SourceInfoAwareJsNode) {
|
||||
astNode.setSource(location);
|
||||
}
|
||||
else if (astNode instanceof JsExpressionStatement) {
|
||||
((JsExpressionStatement) astNode).getExpression().setSource(location);
|
||||
}
|
||||
}
|
||||
return astNode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,17 +29,19 @@ import java.util.*
|
||||
|
||||
private val FAKE_SOURCE_INFO = SourceInfoImpl(null, 0, 0, 0, 0)
|
||||
|
||||
fun parse(code: String, reporter: ErrorReporter, scope: JsScope): List<JsStatement> {
|
||||
fun parse(code: String, reporter: ErrorReporter, scope: JsScope, fileName: String): List<JsStatement> {
|
||||
val insideFunction = scope is JsFunctionScope
|
||||
val node = parse(code, 0, reporter, insideFunction, Parser::parse)
|
||||
return node.toJsAst(scope, JsAstMapper::mapStatements)
|
||||
return node.toJsAst(scope, fileName) {
|
||||
mapStatements(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun parseFunction(code: String, offset: Int, reporter: ErrorReporter, scope: JsScope): JsFunction =
|
||||
fun parseFunction(code: String, fileName: String, offset: Int, reporter: ErrorReporter, scope: JsScope): JsFunction =
|
||||
parse(code, offset, reporter, insideFunction = false) {
|
||||
addObserver(FunctionParsingObserver())
|
||||
primaryExpr(it)
|
||||
}.toJsAst(scope, JsAstMapper::mapFunction)
|
||||
}.toJsAst(scope, fileName, JsAstMapper::mapFunction)
|
||||
|
||||
private class FunctionParsingObserver : Observer {
|
||||
var functionsStarted = 0
|
||||
@@ -80,8 +82,8 @@ private fun parse(
|
||||
}
|
||||
|
||||
inline
|
||||
private fun <T> Node.toJsAst(scope: JsScope, mapAction: JsAstMapper.(Node)->T): T =
|
||||
JsAstMapper(scope).mapAction(this)
|
||||
private fun <T> Node.toJsAst(scope: JsScope, fileName: String, mapAction: JsAstMapper.(Node)->T): T =
|
||||
JsAstMapper(scope, fileName).mapAction(this)
|
||||
|
||||
private fun StringReader(string: String, offset: Int): Reader {
|
||||
val reader = StringReader(string)
|
||||
|
||||
Reference in New Issue
Block a user