mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Implementing JavaScript-to-Java calls in JSBody
This commit is contained in:
parent
7012e9b4d9
commit
ffbd68cf69
|
@ -71,6 +71,9 @@ import org.mozilla.javascript.ast.VariableDeclaration;
|
|||
import org.mozilla.javascript.ast.VariableInitializer;
|
||||
import org.mozilla.javascript.ast.WhileLoop;
|
||||
import org.teavm.codegen.SourceWriter;
|
||||
import org.teavm.diagnostics.Diagnostics;
|
||||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -94,11 +97,13 @@ public class AstWriter {
|
|||
private static final int PRECEDENCE_COND = 16;
|
||||
private static final int PRECEDENCE_ASSIGN = 17;
|
||||
private static final int PRECEDENCE_COMMA = 18;
|
||||
private Diagnostics diagnostics;
|
||||
private SourceWriter writer;
|
||||
private Map<String, NameEmitter> nameMap = new HashMap<>();
|
||||
private Set<String> aliases = new HashSet<>();
|
||||
|
||||
public AstWriter(SourceWriter writer) {
|
||||
public AstWriter(Diagnostics diagnostics, SourceWriter writer) {
|
||||
this.diagnostics = diagnostics;
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
|
@ -501,6 +506,14 @@ public class AstWriter {
|
|||
}
|
||||
|
||||
private void print(FunctionCall node, int precedence) throws IOException {
|
||||
if (node.getTarget() instanceof PropertyGet) {
|
||||
PropertyGet propertyGet = (PropertyGet) node.getTarget();
|
||||
MethodReference methodRef = getJavaMethodSelector(propertyGet.getTarget());
|
||||
if (methodRef != null && propertyGet.getProperty().getIdentifier().equals("invoke")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (precedence < PRECEDENCE_FUNCTION) {
|
||||
writer.append('(');
|
||||
}
|
||||
|
@ -524,6 +537,57 @@ public class AstWriter {
|
|||
}
|
||||
}
|
||||
|
||||
private MethodReference getJavaMethodSelector(AstNode node) {
|
||||
if (!(node instanceof FunctionCall)) {
|
||||
return null;
|
||||
}
|
||||
FunctionCall call = (FunctionCall) node;
|
||||
if (!isJavaMethodRepository(call.getTarget())) {
|
||||
return null;
|
||||
}
|
||||
if (call.getArguments().size() != 1) {
|
||||
diagnostics.warning(new CallLocation(null), "JavaMethods.get method should take exactly one argument");
|
||||
return null;
|
||||
}
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
if (!extractMethodName(call.getArguments().get(0), nameBuilder)) {
|
||||
diagnostics.warning(new CallLocation(null), "JavaMethods.get method should take string constant");
|
||||
return null;
|
||||
}
|
||||
return MethodReference.parse(nameBuilder.toString());
|
||||
}
|
||||
|
||||
private boolean isJavaMethodRepository(AstNode node) {
|
||||
if (!(node instanceof PropertyGet)) {
|
||||
return false;
|
||||
}
|
||||
PropertyGet propertyGet = (PropertyGet) node;
|
||||
|
||||
if (propertyGet.getLeft() instanceof Name) {
|
||||
return false;
|
||||
}
|
||||
if (!((Name) propertyGet.getTarget()).getIdentifier().equals("JavaMethods")) {
|
||||
return false;
|
||||
}
|
||||
if (!propertyGet.getProperty().getIdentifier().equals("get")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean extractMethodName(AstNode node, StringBuilder sb) {
|
||||
if (node.getType() == Token.ADD) {
|
||||
InfixExpression infix = (InfixExpression) node;
|
||||
return extractMethodName(infix.getLeft(), sb) && extractMethodName(infix.getRight(), sb);
|
||||
} else if (node.getType() == Token.STRING) {
|
||||
sb.append(((StringLiteral) node).getValue());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void print(ConditionalExpression node, int precedence) throws IOException {
|
||||
if (precedence < PRECEDENCE_COND) {
|
||||
writer.append('(');
|
||||
|
|
|
@ -39,7 +39,7 @@ class JSBodyAstEmitter implements JSBodyEmitter {
|
|||
|
||||
@Override
|
||||
public void emit(InjectorContext context) throws IOException {
|
||||
AstWriter astWriter = new AstWriter(context.getWriter());
|
||||
AstWriter astWriter = new AstWriter(null, context.getWriter());
|
||||
int paramIndex = 0;
|
||||
if (!isStatic) {
|
||||
int index = paramIndex++;
|
||||
|
@ -55,7 +55,7 @@ class JSBodyAstEmitter implements JSBodyEmitter {
|
|||
|
||||
@Override
|
||||
public void emit(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
|
||||
AstWriter astWriter = new AstWriter(writer);
|
||||
AstWriter astWriter = new AstWriter(context.getDiagnostics(), writer);
|
||||
int paramIndex = 1;
|
||||
if (!isStatic) {
|
||||
int index = paramIndex++;
|
||||
|
|
|
@ -39,7 +39,7 @@ public class AstWriterTest {
|
|||
SourceWriterBuilder builder = new SourceWriterBuilder(null);
|
||||
builder.setMinified(true);
|
||||
sourceWriter = builder.build(sb);
|
||||
writer = new AstWriter(sourceWriter);
|
||||
writer = new AstWriter(null, sourceWriter);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue
Block a user