mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
js: refactor and simplify AstWriter, properly fix case with variable in catch block
This commit is contained in:
parent
e4452152b7
commit
ccfe19994b
|
@ -15,10 +15,9 @@
|
|||
*/
|
||||
package org.teavm.backend.javascript.rendering;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -97,9 +96,9 @@ public class AstWriter {
|
|||
protected boolean rootScope = true;
|
||||
private Set<String> aliases = new HashSet<>();
|
||||
private Function<String, NameEmitter> globalNameWriter;
|
||||
public final Map<String, Scope> currentScopes = new HashMap<>();
|
||||
protected final Set<Scope> topLevelScopes = new HashSet<>();
|
||||
private Set<String> nonTopLevels = new HashSet<>();
|
||||
private boolean inFunction;
|
||||
private int scopeLevel;
|
||||
|
||||
public AstWriter(SourceWriter writer, Function<String, NameEmitter> globalNameWriter) {
|
||||
this.writer = writer;
|
||||
|
@ -115,13 +114,13 @@ public class AstWriter {
|
|||
return;
|
||||
}
|
||||
if (aliases.add(name)) {
|
||||
nameMap.put(name, p -> writer.append(name));
|
||||
nameMap.put(name, (w, p) -> w.append(name));
|
||||
return;
|
||||
}
|
||||
for (int i = 0;; ++i) {
|
||||
String alias = name + "_" + i;
|
||||
if (aliases.add(alias)) {
|
||||
nameMap.put(name, p -> writer.append(alias));
|
||||
nameMap.put(name, (w, p) -> w.append(alias));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +201,7 @@ public class AstWriter {
|
|||
break;
|
||||
case Token.THIS:
|
||||
if (nameMap.containsKey("this")) {
|
||||
nameMap.get("this").emit(precedence);
|
||||
nameMap.get("this").emit(writer, precedence);
|
||||
} else {
|
||||
writer.append("this");
|
||||
}
|
||||
|
@ -324,7 +323,7 @@ public class AstWriter {
|
|||
}
|
||||
|
||||
private void print(Scope node) {
|
||||
var scope = enterScope(node);
|
||||
var scope = enterScope(node, false);
|
||||
writer.append('{').softNewLine().indent();
|
||||
for (Node child = node.getFirstChild(); child != null; child = child.getNext()) {
|
||||
if (!print((AstNode) child)) {
|
||||
|
@ -332,7 +331,7 @@ public class AstWriter {
|
|||
}
|
||||
}
|
||||
writer.outdent().append('}');
|
||||
leaveScope(scope, node);
|
||||
leaveScope(scope);
|
||||
}
|
||||
|
||||
private void print(LabeledStatement node) {
|
||||
|
@ -374,17 +373,17 @@ public class AstWriter {
|
|||
}
|
||||
|
||||
private void print(DoLoop node) {
|
||||
var scope = enterScope(node);
|
||||
var scope = enterScope(node, false);
|
||||
writer.append("do ").ws();
|
||||
print(node.getBody());
|
||||
writer.append("while").ws().append('(');
|
||||
print(node.getCondition());
|
||||
writer.append(");");
|
||||
leaveScope(scope, node);
|
||||
leaveScope(scope);
|
||||
}
|
||||
|
||||
private void print(ForInLoop node) {
|
||||
var scope = enterScope(node);
|
||||
var scope = enterScope(node, false);
|
||||
writer.append("for");
|
||||
if (node.isForEach()) {
|
||||
writer.append(" each");
|
||||
|
@ -395,11 +394,11 @@ public class AstWriter {
|
|||
print(node.getIteratedObject());
|
||||
writer.append(')').ws();
|
||||
print(node.getBody());
|
||||
leaveScope(scope, node);
|
||||
leaveScope(scope);
|
||||
}
|
||||
|
||||
private void print(ForLoop node) {
|
||||
var scope = enterScope(node);
|
||||
var scope = enterScope(node, false);
|
||||
writer.append("for").ws().append('(');
|
||||
print(node.getInitializer());
|
||||
writer.append(';');
|
||||
|
@ -408,16 +407,16 @@ public class AstWriter {
|
|||
print(node.getIncrement());
|
||||
writer.append(')').ws();
|
||||
print(node.getBody());
|
||||
leaveScope(scope, node);
|
||||
leaveScope(scope);
|
||||
}
|
||||
|
||||
private void print(WhileLoop node) {
|
||||
var scope = enterScope(node);
|
||||
var scope = enterScope(node, false);
|
||||
writer.append("while").ws().append('(');
|
||||
print(node.getCondition());
|
||||
writer.append(')').ws();
|
||||
print(node.getBody());
|
||||
leaveScope(scope, node);
|
||||
leaveScope(scope);
|
||||
}
|
||||
|
||||
private void print(IfStatement node) {
|
||||
|
@ -458,8 +457,10 @@ public class AstWriter {
|
|||
private void print(TryStatement node) {
|
||||
writer.append("try ");
|
||||
print(node.getTryBlock());
|
||||
for (CatchClause cc : node.getCatchClauses()) {
|
||||
for (var cc : node.getCatchClauses()) {
|
||||
writer.ws().append("catch").ws().append('(');
|
||||
var scope = enterScope(false);
|
||||
includeInScope(scope, cc.getVarName().getIdentifier());
|
||||
print(cc.getVarName());
|
||||
if (cc.getCatchCondition() != null) {
|
||||
writer.append(" if ");
|
||||
|
@ -467,6 +468,7 @@ public class AstWriter {
|
|||
}
|
||||
writer.append(')');
|
||||
print(cc.getBody());
|
||||
leaveScope(scope);
|
||||
}
|
||||
if (node.getFinallyBlock() != null) {
|
||||
writer.ws().append("finally ");
|
||||
|
@ -475,10 +477,9 @@ public class AstWriter {
|
|||
}
|
||||
|
||||
private boolean print(VariableDeclaration node) {
|
||||
if (isTopLevel() && node.getVariables().get(0).getTarget() instanceof Name) {
|
||||
if (isTopLevelOutput() && node.getVariables().get(0).getTarget() instanceof Name) {
|
||||
var name = (Name) node.getVariables().get(0).getTarget();
|
||||
var definingScope = scopeOfId(name.getIdentifier());
|
||||
if (definingScope == null || topLevelScopes.contains(definingScope)) {
|
||||
if (isTopLevelIdentifier(name.getIdentifier())) {
|
||||
printTopLevel(node);
|
||||
return true;
|
||||
}
|
||||
|
@ -647,7 +648,7 @@ public class AstWriter {
|
|||
}
|
||||
|
||||
private void print(ArrayComprehension node) {
|
||||
var scope = enterScope(node);
|
||||
var scope = enterScope(node, false);
|
||||
writer.append("[");
|
||||
for (ArrayComprehensionLoop loop : node.getLoops()) {
|
||||
writer.append("for").ws().append("(");
|
||||
|
@ -663,11 +664,11 @@ public class AstWriter {
|
|||
}
|
||||
print(node.getResult());
|
||||
writer.append(']');
|
||||
leaveScope(scope, node);
|
||||
leaveScope(scope);
|
||||
}
|
||||
|
||||
private void print(GeneratorExpression node) {
|
||||
var scope = enterScope(node);
|
||||
var scope = enterScope(node, false);
|
||||
writer.append("(");
|
||||
for (GeneratorExpressionLoop loop : node.getLoops()) {
|
||||
writer.append("for").ws().append("(");
|
||||
|
@ -683,7 +684,7 @@ public class AstWriter {
|
|||
}
|
||||
print(node.getResult());
|
||||
writer.append(')');
|
||||
leaveScope(scope, node);
|
||||
leaveScope(scope);
|
||||
}
|
||||
|
||||
private void print(NumberLiteral node) {
|
||||
|
@ -697,17 +698,16 @@ public class AstWriter {
|
|||
}
|
||||
|
||||
public void print(Name node, int precedence) {
|
||||
var definingScope = scopeOfId(node.getIdentifier());
|
||||
if (rootScope && definingScope == null) {
|
||||
if (rootScope && isTopLevelIdentifier(node.getIdentifier())) {
|
||||
var alias = nameMap.get(node.getIdentifier());
|
||||
if (alias == null) {
|
||||
if (globalNameWriter != null) {
|
||||
alias = globalNameWriter.apply(node.getIdentifier());
|
||||
} else {
|
||||
alias = prec -> writer.append(node.getIdentifier());
|
||||
alias = (w, prec) -> w.append(node.getIdentifier());
|
||||
}
|
||||
}
|
||||
alias.emit(precedence);
|
||||
alias.emit(writer, precedence);
|
||||
} else {
|
||||
writer.append(node.getIdentifier());
|
||||
}
|
||||
|
@ -753,18 +753,16 @@ public class AstWriter {
|
|||
|
||||
protected boolean print(FunctionNode node) {
|
||||
var isArrow = node.getFunctionType() == FunctionNode.ARROW_FUNCTION;
|
||||
if (isTopLevel() && !isArrow && node.getFunctionName() != null) {
|
||||
var definingScope = scopeOfId(node.getFunctionName().getIdentifier());
|
||||
if (definingScope == null || topLevelScopes.contains(definingScope)) {
|
||||
printTopLevel(node);
|
||||
return true;
|
||||
}
|
||||
if (isTopLevelOutput() && !isArrow && node.getFunctionName() != null
|
||||
&& isTopLevelIdentifier(node.getFunctionName().getIdentifier())) {
|
||||
printTopLevel(node);
|
||||
return true;
|
||||
}
|
||||
var wasInFunction = inFunction;
|
||||
inFunction = true;
|
||||
var scope = enterScope(node);
|
||||
var scope = enterScope(node, true);
|
||||
if (!isArrow) {
|
||||
currentScopes.put("arguments", node);
|
||||
includeInScope(scope, "arguments");
|
||||
}
|
||||
if (!node.isMethod() && !isArrow) {
|
||||
writer.append("function");
|
||||
|
@ -797,7 +795,7 @@ public class AstWriter {
|
|||
print(node.getBody());
|
||||
}
|
||||
|
||||
leaveScope(scope, node);
|
||||
leaveScope(scope);
|
||||
inFunction = wasInFunction;
|
||||
return false;
|
||||
}
|
||||
|
@ -805,25 +803,25 @@ public class AstWriter {
|
|||
private void printTopLevel(FunctionNode node) {
|
||||
var wasInFunction = inFunction;
|
||||
inFunction = true;
|
||||
var scope = enterScope(node);
|
||||
currentScopes.put("arguments", node);
|
||||
var scope = enterScope(node, true);
|
||||
includeInScope(scope, "arguments");
|
||||
writer.startFunctionDeclaration().appendFunction(node.getFunctionName().getIdentifier());
|
||||
writer.append('(');
|
||||
printList(node.getParams());
|
||||
writer.append(')').ws();
|
||||
print(node.getBody());
|
||||
writer.endDeclaration();
|
||||
leaveScope(scope, node);
|
||||
leaveScope(scope);
|
||||
inFunction = wasInFunction;
|
||||
}
|
||||
|
||||
private void print(LetNode node) {
|
||||
var scope = enterScope(node);
|
||||
var scope = enterScope(node, false);
|
||||
writer.append("let").ws().append('(');
|
||||
printList(node.getVariables().getVariables());
|
||||
writer.append(')');
|
||||
print(node.getBody());
|
||||
leaveScope(scope, node);
|
||||
leaveScope(scope);
|
||||
}
|
||||
|
||||
private void print(ParenthesizedExpression node, int precedence) {
|
||||
|
@ -1021,47 +1019,45 @@ public class AstWriter {
|
|||
}
|
||||
}
|
||||
|
||||
private Map<String, Scope> enterScope(Scope scope) {
|
||||
if (scope.getSymbolTable() == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
var map = new LinkedHashMap<String, Scope>();
|
||||
for (var name : scope.getSymbolTable().keySet()) {
|
||||
map.put(name, currentScopes.get(name));
|
||||
currentScopes.put(name, scope);
|
||||
}
|
||||
onEnterScope(scope);
|
||||
return map;
|
||||
}
|
||||
|
||||
protected void onEnterScope(Scope scope) {
|
||||
if (isTopLevel() && !inFunction()) {
|
||||
topLevelScopes.add(scope);
|
||||
}
|
||||
}
|
||||
|
||||
private void leaveScope(Map<String, Scope> backup, Scope scope) {
|
||||
for (var entry : backup.entrySet()) {
|
||||
if (entry.getValue() == null) {
|
||||
currentScopes.remove(entry.getKey());
|
||||
} else {
|
||||
currentScopes.put(entry.getKey(), entry.getValue());
|
||||
private Set<String> enterScope(Scope scope, boolean nesting) {
|
||||
var set = enterScope(nesting);
|
||||
if (scope.getSymbolTable() != null) {
|
||||
for (var name : scope.getSymbolTable().keySet()) {
|
||||
includeInScope(set, name);
|
||||
}
|
||||
}
|
||||
onLeaveScope(scope);
|
||||
return set;
|
||||
}
|
||||
|
||||
protected void onLeaveScope(Scope scope) {
|
||||
if (isTopLevel() && !inFunction()) {
|
||||
topLevelScopes.remove(scope);
|
||||
public Set<String> enterScope(boolean nesting) {
|
||||
if (scopeLevel > 0 || nesting) {
|
||||
++scopeLevel;
|
||||
}
|
||||
return new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
public final void includeInScope(Set<String> scope, String name) {
|
||||
if (nonTopLevels.add(name)) {
|
||||
scope.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
protected Scope scopeOfId(String id) {
|
||||
return currentScopes.get(id);
|
||||
public void leaveScope(Set<String> backup) {
|
||||
nonTopLevels.removeAll(backup);
|
||||
if (scopeLevel > 0) {
|
||||
--scopeLevel;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isTopLevel() {
|
||||
protected boolean isTopLevelIdentifier(String id) {
|
||||
return !nonTopLevels.contains(id);
|
||||
}
|
||||
|
||||
protected boolean isInTopLevelScope() {
|
||||
return scopeLevel == 0;
|
||||
}
|
||||
|
||||
protected boolean isTopLevelOutput() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,20 +16,13 @@
|
|||
package org.teavm.backend.javascript.rendering;
|
||||
|
||||
import java.util.function.Function;
|
||||
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||
|
||||
public class DefaultGlobalNameWriter implements Function<String, NameEmitter> {
|
||||
private SourceWriter writer;
|
||||
|
||||
public DefaultGlobalNameWriter(SourceWriter writer) {
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NameEmitter apply(String s) {
|
||||
if (s.startsWith("$rt_") || s.startsWith("Long_") || s.equals("Long")) {
|
||||
return prec -> writer.appendFunction(s);
|
||||
return (w, intprec) -> w.appendFunction(s);
|
||||
}
|
||||
return prec -> writer.appendGlobal(s);
|
||||
return (w, prec) -> w.appendGlobal(s);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package org.teavm.backend.javascript.rendering;
|
||||
|
||||
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||
|
||||
public interface NameEmitter {
|
||||
void emit(int precedence);
|
||||
void emit(SourceWriter writer, int precedence);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,9 @@ import java.io.InputStreamReader;
|
|||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.mozilla.javascript.CompilerEnvirons;
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.ast.AstRoot;
|
||||
|
@ -42,6 +44,7 @@ public class RuntimeRenderer {
|
|||
private final ClassReaderSource classSource;
|
||||
private final SourceWriter writer;
|
||||
private final ClassInitializerInfo classInitializerInfo;
|
||||
private final Set<String> topLevelNames = new HashSet<>();
|
||||
|
||||
public RuntimeRenderer(ClassReaderSource classSource, SourceWriter writer,
|
||||
ClassInitializerInfo classInitializerInfo) {
|
||||
|
@ -83,12 +86,15 @@ public class RuntimeRenderer {
|
|||
ast.visit(new StringConstantElimination());
|
||||
new TemplatingAstTransformer(classSource).visit(ast);
|
||||
removablePartsFinder.visit(ast);
|
||||
topLevelNames.addAll(ast.getSymbolTable().keySet());
|
||||
return ast;
|
||||
}
|
||||
|
||||
private void renderRuntimePart(AstRoot ast) {
|
||||
var astWriter = new TemplatingAstWriter(writer, null, null, classInitializerInfo);
|
||||
astWriter.hoist(ast);
|
||||
var astWriter = new TemplatingAstWriter(writer, classInitializerInfo, true);
|
||||
for (var name : topLevelNames) {
|
||||
astWriter.declareNameEmitter(name, (w, prec) -> w.appendFunction(name));
|
||||
}
|
||||
astWriter.print(ast);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.function.IntFunction;
|
|||
import org.mozilla.javascript.ast.AstNode;
|
||||
import org.mozilla.javascript.ast.FunctionNode;
|
||||
import org.mozilla.javascript.ast.Name;
|
||||
import org.teavm.backend.javascript.rendering.NameEmitter;
|
||||
import org.teavm.backend.javascript.spi.GeneratorContext;
|
||||
import org.teavm.model.ClassReaderSource;
|
||||
|
||||
|
@ -65,27 +66,26 @@ public class JavaScriptTemplate {
|
|||
|
||||
public SourceFragment build() {
|
||||
var intParameters = parameters;
|
||||
var nameParameters = new HashMap<String, SourceFragment>();
|
||||
var nameParameters = new HashMap<String, NameEmitter>();
|
||||
for (var i = 0; i < node.getParams().size(); ++i) {
|
||||
var param = node.getParams().get(i);
|
||||
if (param instanceof Name) {
|
||||
nameParameters.put(((Name) param).getIdentifier(), intParameters.apply(i + 1));
|
||||
var sourceFragment = intParameters.apply(i + 1);
|
||||
nameParameters.put(((Name) param).getIdentifier(), sourceFragment::write);
|
||||
}
|
||||
}
|
||||
var thisFragment = parameters.apply(0);
|
||||
var body = node.getBody();
|
||||
return (writer, precedence) -> {
|
||||
var astWriter = new TemplatingAstWriter(writer, nameParameters, node, null);
|
||||
var astWriter = new TemplatingAstWriter(writer, null, false);
|
||||
for (var entry : nameParameters.entrySet()) {
|
||||
astWriter.declareNameEmitter(entry.getKey(), entry.getValue());
|
||||
}
|
||||
for (var entry : fragments.entrySet()) {
|
||||
astWriter.setFragment(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (node.getSymbolTable() != null) {
|
||||
for (var name : node.getSymbolTable().keySet()) {
|
||||
astWriter.currentScopes.put(name, node);
|
||||
}
|
||||
}
|
||||
if (thisFragment != null) {
|
||||
astWriter.declareNameEmitter("this", thisPrecedence -> thisFragment.write(writer, thisPrecedence));
|
||||
astWriter.declareNameEmitter("this", thisFragment::write);
|
||||
}
|
||||
for (var child = body.getFirstChild(); child != null; child = child.getNext()) {
|
||||
astWriter.print((AstNode) child);
|
||||
|
|
|
@ -19,10 +19,8 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import org.mozilla.javascript.ast.ElementGet;
|
||||
import org.mozilla.javascript.ast.FunctionCall;
|
||||
import org.mozilla.javascript.ast.FunctionNode;
|
||||
import org.mozilla.javascript.ast.Name;
|
||||
import org.mozilla.javascript.ast.PropertyGet;
|
||||
import org.mozilla.javascript.ast.Scope;
|
||||
import org.mozilla.javascript.ast.StringLiteral;
|
||||
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||
import org.teavm.backend.javascript.rendering.AstWriter;
|
||||
|
@ -33,25 +31,14 @@ import org.teavm.model.MethodReference;
|
|||
import org.teavm.model.analysis.ClassInitializerInfo;
|
||||
|
||||
public class TemplatingAstWriter extends AstWriter {
|
||||
private Map<String, SourceFragment> names;
|
||||
private Scope scope;
|
||||
private Map<String, SourceFragment> fragments = new HashMap<>();
|
||||
private ClassInitializerInfo classInitializerInfo;
|
||||
private boolean topLevelOutput;
|
||||
|
||||
public TemplatingAstWriter(SourceWriter writer, Map<String, SourceFragment> names, Scope scope,
|
||||
ClassInitializerInfo classInitializerInfo) {
|
||||
super(writer, new DefaultGlobalNameWriter(writer));
|
||||
public TemplatingAstWriter(SourceWriter writer, ClassInitializerInfo classInitializerInfo, boolean topLevelOutput) {
|
||||
super(writer, new DefaultGlobalNameWriter());
|
||||
this.classInitializerInfo = classInitializerInfo;
|
||||
this.names = names;
|
||||
this.scope = scope;
|
||||
if (names != null) {
|
||||
for (var name : names.keySet()) {
|
||||
currentScopes.put(name, scope);
|
||||
}
|
||||
}
|
||||
if (scope instanceof FunctionNode) {
|
||||
currentScopes.put("arguments", scope);
|
||||
}
|
||||
this.topLevelOutput = topLevelOutput;
|
||||
}
|
||||
|
||||
public void setFragment(String name, SourceFragment fragment) {
|
||||
|
@ -62,7 +49,7 @@ public class TemplatingAstWriter extends AstWriter {
|
|||
protected boolean intrinsic(FunctionCall node, int precedence) {
|
||||
if (node.getTarget() instanceof Name) {
|
||||
var name = (Name) node.getTarget();
|
||||
if (scopeOfId(name.getIdentifier()) == null) {
|
||||
if (isTopLevelIdentifier(name.getIdentifier())) {
|
||||
return tryIntrinsicName(node, name.getIdentifier());
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +151,7 @@ public class TemplatingAstWriter extends AstWriter {
|
|||
var call = (FunctionCall) node.getElement();
|
||||
if (call.getTarget() instanceof Name) {
|
||||
var name = (Name) call.getTarget();
|
||||
if (scopeOfId(name.getIdentifier()) == null) {
|
||||
if (isTopLevelIdentifier(name.getIdentifier())) {
|
||||
switch (name.getIdentifier()) {
|
||||
case "teavm_javaVirtualMethod":
|
||||
if (writeJavaVirtualMethod(node, call)) {
|
||||
|
@ -187,8 +174,7 @@ public class TemplatingAstWriter extends AstWriter {
|
|||
public void print(PropertyGet node) {
|
||||
if (node.getTarget() instanceof Name) {
|
||||
var name = (Name) node.getTarget();
|
||||
var scope = scopeOfId(name.getIdentifier());
|
||||
if (scope == null && name.getIdentifier().equals("teavm_globals")) {
|
||||
if (isTopLevelIdentifier(name.getIdentifier()) && name.getIdentifier().equals("teavm_globals")) {
|
||||
var oldRootScope = rootScope;
|
||||
rootScope = false;
|
||||
writer.appendGlobal(node.getProperty().getIdentifier());
|
||||
|
@ -227,26 +213,7 @@ public class TemplatingAstWriter extends AstWriter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void print(Name node, int precedence) {
|
||||
var definingScope = scopeOfId(node.getIdentifier());
|
||||
if (rootScope) {
|
||||
if (names != null && definingScope == scope) {
|
||||
var fragment = names.get(node.getIdentifier());
|
||||
if (fragment != null) {
|
||||
fragment.write(writer, precedence);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (definingScope == null || topLevelScopes.contains(definingScope)) {
|
||||
writer.appendFunction(node.getIdentifier());
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.print(node, precedence);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isTopLevel() {
|
||||
return names == null;
|
||||
public boolean isTopLevelOutput() {
|
||||
return topLevelOutput;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public class AstWriterTest {
|
|||
builder.setMinified(true);
|
||||
sourceWriter = builder.build(sb);
|
||||
writer = new AstWriter(sourceWriter, null);
|
||||
writerWithGlobals = new AstWriter(sourceWriter, name -> prec -> sourceWriter.append("globals.").append(name));
|
||||
writerWithGlobals = new AstWriter(sourceWriter, name -> (w, prec) -> w.append("globals.").append(name));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -44,21 +44,21 @@ class JSBodyAstEmitter implements JSBodyEmitter {
|
|||
|
||||
@Override
|
||||
public void emit(InjectorContext context) {
|
||||
var astWriter = new AstWriter(context.getWriter(), new DefaultGlobalNameWriter(context.getWriter()));
|
||||
var astWriter = new AstWriter(context.getWriter(), new DefaultGlobalNameWriter());
|
||||
int paramIndex = 0;
|
||||
if (!isStatic) {
|
||||
int index = paramIndex++;
|
||||
astWriter.declareNameEmitter("this", prec -> context.writeExpr(context.getArgument(index),
|
||||
astWriter.declareNameEmitter("this", (w, prec) -> context.writeExpr(context.getArgument(index),
|
||||
convert(prec)));
|
||||
}
|
||||
for (int i = 0; i < parameterNames.length; ++i) {
|
||||
int index = paramIndex++;
|
||||
astWriter.declareNameEmitter(parameterNames[i],
|
||||
prec -> context.writeExpr(context.getArgument(index), convert(prec)));
|
||||
(w, prec) -> context.writeExpr(context.getArgument(index), convert(prec)));
|
||||
}
|
||||
for (var importInfo : imports) {
|
||||
astWriter.declareNameEmitter(importInfo.alias,
|
||||
prec -> context.getWriter().appendFunction(context.importModule(importInfo.fromModule)));
|
||||
(w, prec) -> context.getWriter().appendFunction(context.importModule(importInfo.fromModule)));
|
||||
}
|
||||
astWriter.hoist(rootAst);
|
||||
astWriter.print(ast, convert(context.getPrecedence()));
|
||||
|
@ -148,19 +148,19 @@ class JSBodyAstEmitter implements JSBodyEmitter {
|
|||
|
||||
@Override
|
||||
public void emit(GeneratorContext context, SourceWriter writer, MethodReference methodRef) {
|
||||
var astWriter = new AstWriter(writer, new DefaultGlobalNameWriter(writer));
|
||||
var astWriter = new AstWriter(writer, new DefaultGlobalNameWriter());
|
||||
int paramIndex = 1;
|
||||
if (!isStatic) {
|
||||
int index = paramIndex++;
|
||||
astWriter.declareNameEmitter("this", prec -> writer.append(context.getParameterName(index)));
|
||||
astWriter.declareNameEmitter("this", (w, prec) -> w.append(context.getParameterName(index)));
|
||||
}
|
||||
for (var parameterName : parameterNames) {
|
||||
int index = paramIndex++;
|
||||
astWriter.declareNameEmitter(parameterName, prec -> writer.append(context.getParameterName(index)));
|
||||
astWriter.declareNameEmitter(parameterName, (w, prec) -> w.append(context.getParameterName(index)));
|
||||
}
|
||||
for (var importInfo : imports) {
|
||||
astWriter.declareNameEmitter(importInfo.alias,
|
||||
prec -> writer.appendFunction(context.importModule(importInfo.fromModule)));
|
||||
(w, prec) -> w.appendFunction(context.importModule(importInfo.fromModule)));
|
||||
}
|
||||
astWriter.hoist(rootAst);
|
||||
if (ast instanceof Block) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user