mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-23 00:24:11 -08:00
First version of Java callbacks, without dependency checker hook and
parameter conversion.
This commit is contained in:
parent
ffbd68cf69
commit
bae388a778
|
@ -96,24 +96,46 @@ public class MethodDescriptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MethodDescriptor parse(String text) {
|
public static MethodDescriptor parse(String text) {
|
||||||
int parenIndex = text.indexOf('(');
|
MethodDescriptor desc = parseIfPossible(text);
|
||||||
if (parenIndex < 0) {
|
if (desc == null) {
|
||||||
throw new IllegalArgumentException("Wrong method descriptor: " + text);
|
throw new IllegalArgumentException("Wrong method descriptor: " + text);
|
||||||
}
|
}
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodDescriptor parseIfPossible(String text) {
|
||||||
|
int parenIndex = text.indexOf('(');
|
||||||
|
if (parenIndex < 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return new MethodDescriptor(text.substring(0, parenIndex),
|
return new MethodDescriptor(text.substring(0, parenIndex),
|
||||||
parseSignature(text.substring(parenIndex)));
|
parseSignature(text.substring(parenIndex)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ValueType[] parseSignature(String text) {
|
public static ValueType[] parseSignature(String text) {
|
||||||
|
ValueType[] signature = parseSignatureIfPossible(text);
|
||||||
|
if (signature == null) {
|
||||||
|
throw new IllegalArgumentException("Illegal method signature: " + text);
|
||||||
|
}
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValueType[] parseSignatureIfPossible(String text) {
|
||||||
if (text.charAt(0) != '(') {
|
if (text.charAt(0) != '(') {
|
||||||
throw new IllegalArgumentException("Wrong method descriptor: " + text);
|
return null;
|
||||||
}
|
}
|
||||||
int index = text.indexOf(')', 1);
|
int index = text.indexOf(')', 1);
|
||||||
if (index == -1) {
|
if (index < 0) {
|
||||||
throw new IllegalArgumentException("Wrong method descriptor: " + text);
|
return null;
|
||||||
|
}
|
||||||
|
ValueType[] params = ValueType.parseManyIfPossible(text.substring(1, index));
|
||||||
|
if (params == null) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
ValueType[] params = ValueType.parseMany(text.substring(1, index));
|
|
||||||
ValueType result = ValueType.parse(text.substring(index + 1));
|
ValueType result = ValueType.parse(text.substring(index + 1));
|
||||||
|
if (result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
ValueType[] signature = new ValueType[params.length + 1];
|
ValueType[] signature = new ValueType[params.length + 1];
|
||||||
System.arraycopy(params, 0, signature, 0, params.length);
|
System.arraycopy(params, 0, signature, 0, params.length);
|
||||||
signature[params.length] = result;
|
signature[params.length] = result;
|
||||||
|
|
|
@ -140,9 +140,21 @@ public class MethodReference {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MethodReference parse(String string) {
|
public static MethodReference parse(String string) {
|
||||||
|
MethodReference reference = parseIfPossible(string);
|
||||||
|
if (reference == null) {
|
||||||
|
throw new IllegalArgumentException("Illegal method reference: " + string);
|
||||||
|
}
|
||||||
|
return reference;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodReference parseIfPossible(String string) {
|
||||||
int index = string.lastIndexOf('.');
|
int index = string.lastIndexOf('.');
|
||||||
|
if (index < 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
String className = string.substring(0, index);
|
String className = string.substring(0, index);
|
||||||
return new MethodReference(className, MethodDescriptor.parse(string.substring(index + 1)));
|
MethodDescriptor desc = MethodDescriptor.parseIfPossible(string.substring(index + 1));
|
||||||
|
return desc != null ? new MethodReference(className, desc) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String signatureToString() {
|
public String signatureToString() {
|
||||||
|
|
|
@ -212,11 +212,23 @@ public abstract class ValueType {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ValueType[] parseMany(String text) {
|
public static ValueType[] parseMany(String text) {
|
||||||
|
ValueType[] types = parseManyIfPossible(text);
|
||||||
|
if (types == null) {
|
||||||
|
throw new IllegalArgumentException("Illegal method type signature: " + text);
|
||||||
|
}
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValueType[] parseManyIfPossible(String text) {
|
||||||
List<ValueType> types = new ArrayList<>();
|
List<ValueType> types = new ArrayList<>();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while (index < text.length()) {
|
while (index < text.length()) {
|
||||||
int nextIndex = cut(text, index);
|
int nextIndex = cut(text, index);
|
||||||
types.add(parse(text.substring(index, nextIndex)));
|
ValueType type = parse(text.substring(index, nextIndex));
|
||||||
|
if (type == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
types.add(type);
|
||||||
index = nextIndex;
|
index = nextIndex;
|
||||||
}
|
}
|
||||||
return types.toArray(new ValueType[types.size()]);
|
return types.toArray(new ValueType[types.size()]);
|
||||||
|
@ -224,18 +236,30 @@ public abstract class ValueType {
|
||||||
|
|
||||||
private static int cut(String text, int index) {
|
private static int cut(String text, int index) {
|
||||||
while (text.charAt(index) == '[') {
|
while (text.charAt(index) == '[') {
|
||||||
++index;
|
if (++index >= text.length()) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (text.charAt(index) != 'L') {
|
if (text.charAt(index) != 'L') {
|
||||||
return index + 1;
|
return index + 1;
|
||||||
}
|
}
|
||||||
while (text.charAt(index) != ';') {
|
while (text.charAt(index) != ';') {
|
||||||
++index;
|
if (++index >= text.length()) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return index + 1;
|
return index + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ValueType parse(String string) {
|
public static ValueType parse(String string) {
|
||||||
|
ValueType type = parseIfPossible(string);
|
||||||
|
if (type == null) {
|
||||||
|
throw new IllegalArgumentException("Illegal type signature: " + string);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValueType parseIfPossible(String string) {
|
||||||
int arrayDegree = 0;
|
int arrayDegree = 0;
|
||||||
int left = 0;
|
int left = 0;
|
||||||
while (string.charAt(left) == '[') {
|
while (string.charAt(left) == '[') {
|
||||||
|
@ -243,7 +267,13 @@ public abstract class ValueType {
|
||||||
++left;
|
++left;
|
||||||
}
|
}
|
||||||
string = string.substring(left);
|
string = string.substring(left);
|
||||||
|
if (string.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
ValueType type = parseImpl(string);
|
ValueType type = parseImpl(string);
|
||||||
|
if (type == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
while (arrayDegree-- > 0) {
|
while (arrayDegree-- > 0) {
|
||||||
type = arrayOf(type);
|
type = arrayOf(type);
|
||||||
}
|
}
|
||||||
|
@ -295,7 +325,7 @@ public abstract class ValueType {
|
||||||
}
|
}
|
||||||
return object(string.substring(1, string.length() - 1).replace('/', '.'));
|
return object(string.substring(1, string.length() - 1).replace('/', '.'));
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException();
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,6 @@ import org.mozilla.javascript.ast.VariableDeclaration;
|
||||||
import org.mozilla.javascript.ast.VariableInitializer;
|
import org.mozilla.javascript.ast.VariableInitializer;
|
||||||
import org.mozilla.javascript.ast.WhileLoop;
|
import org.mozilla.javascript.ast.WhileLoop;
|
||||||
import org.teavm.codegen.SourceWriter;
|
import org.teavm.codegen.SourceWriter;
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
|
||||||
import org.teavm.model.CallLocation;
|
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,13 +95,11 @@ public class AstWriter {
|
||||||
private static final int PRECEDENCE_COND = 16;
|
private static final int PRECEDENCE_COND = 16;
|
||||||
private static final int PRECEDENCE_ASSIGN = 17;
|
private static final int PRECEDENCE_ASSIGN = 17;
|
||||||
private static final int PRECEDENCE_COMMA = 18;
|
private static final int PRECEDENCE_COMMA = 18;
|
||||||
private Diagnostics diagnostics;
|
|
||||||
private SourceWriter writer;
|
private SourceWriter writer;
|
||||||
private Map<String, NameEmitter> nameMap = new HashMap<>();
|
private Map<String, NameEmitter> nameMap = new HashMap<>();
|
||||||
private Set<String> aliases = new HashSet<>();
|
private Set<String> aliases = new HashSet<>();
|
||||||
|
|
||||||
public AstWriter(Diagnostics diagnostics, SourceWriter writer) {
|
public AstWriter(SourceWriter writer) {
|
||||||
this.diagnostics = diagnostics;
|
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,12 +502,8 @@ public class AstWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void print(FunctionCall node, int precedence) throws IOException {
|
private void print(FunctionCall node, int precedence) throws IOException {
|
||||||
if (node.getTarget() instanceof PropertyGet) {
|
if (tryJavaInvocation(node)) {
|
||||||
PropertyGet propertyGet = (PropertyGet) node.getTarget();
|
return;
|
||||||
MethodReference methodRef = getJavaMethodSelector(propertyGet.getTarget());
|
|
||||||
if (methodRef != null && propertyGet.getProperty().getIdentifier().equals("invoke")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (precedence < PRECEDENCE_FUNCTION) {
|
if (precedence < PRECEDENCE_FUNCTION) {
|
||||||
|
@ -537,55 +529,59 @@ public class AstWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MethodReference getJavaMethodSelector(AstNode node) {
|
private boolean tryJavaInvocation(FunctionCall node) throws IOException {
|
||||||
if (!(node instanceof FunctionCall)) {
|
if (!(node.getTarget() instanceof PropertyGet)) {
|
||||||
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 false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
PropertyGet propertyGet = (PropertyGet) node.getTarget();
|
||||||
}
|
String callMethod = getJavaMethod(propertyGet.getTarget());
|
||||||
|
if (callMethod == null || !propertyGet.getProperty().getIdentifier().equals("invoke")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean extractMethodName(AstNode node, StringBuilder sb) {
|
boolean isStatic;
|
||||||
if (node.getType() == Token.ADD) {
|
if (callMethod.startsWith("S")) {
|
||||||
InfixExpression infix = (InfixExpression) node;
|
isStatic = true;
|
||||||
return extractMethodName(infix.getLeft(), sb) && extractMethodName(infix.getRight(), sb);
|
} else if (callMethod.startsWith("V")) {
|
||||||
} else if (node.getType() == Token.STRING) {
|
isStatic = false;
|
||||||
sb.append(((StringLiteral) node).getValue());
|
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
callMethod = callMethod.substring(1);
|
||||||
|
MethodReference method = MethodReference.parseIfPossible(callMethod);
|
||||||
|
if (method == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isStatic) {
|
||||||
|
writer.appendMethodBody(method).append('(');
|
||||||
|
printList(node.getArguments());
|
||||||
|
writer.append(')');
|
||||||
|
} else {
|
||||||
|
print(node.getArguments().get(0));
|
||||||
|
writer.append('.').appendMethod(method.getDescriptor()).append('(');
|
||||||
|
if (node.getArguments().size() > 1) {
|
||||||
|
print(node.getArguments().get(1));
|
||||||
|
}
|
||||||
|
for (int i = 2; i < node.getArguments().size(); ++i) {
|
||||||
|
writer.append(',').ws();
|
||||||
|
print(node.getArguments().get(i));
|
||||||
|
}
|
||||||
|
writer.append(')');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getJavaMethod(AstNode node) {
|
||||||
|
if (!(node instanceof StringLiteral)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String str = ((StringLiteral) node).getValue();
|
||||||
|
if (!str.startsWith("$$JSO$$_")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return str.substring("$$JSO$$_".length());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void print(ConditionalExpression node, int precedence) throws IOException {
|
private void print(ConditionalExpression node, int precedence) throws IOException {
|
||||||
|
|
|
@ -39,7 +39,7 @@ class JSBodyAstEmitter implements JSBodyEmitter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void emit(InjectorContext context) throws IOException {
|
public void emit(InjectorContext context) throws IOException {
|
||||||
AstWriter astWriter = new AstWriter(null, context.getWriter());
|
AstWriter astWriter = new AstWriter(context.getWriter());
|
||||||
int paramIndex = 0;
|
int paramIndex = 0;
|
||||||
if (!isStatic) {
|
if (!isStatic) {
|
||||||
int index = paramIndex++;
|
int index = paramIndex++;
|
||||||
|
@ -55,7 +55,7 @@ class JSBodyAstEmitter implements JSBodyEmitter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void emit(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
|
public void emit(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
|
||||||
AstWriter astWriter = new AstWriter(context.getDiagnostics(), writer);
|
AstWriter astWriter = new AstWriter(writer);
|
||||||
int paramIndex = 1;
|
int paramIndex = 1;
|
||||||
if (!isStatic) {
|
if (!isStatic) {
|
||||||
int index = paramIndex++;
|
int index = paramIndex++;
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.jso.plugin;
|
||||||
|
|
||||||
|
import org.mozilla.javascript.Token;
|
||||||
|
import org.mozilla.javascript.ast.AstNode;
|
||||||
|
import org.mozilla.javascript.ast.FunctionCall;
|
||||||
|
import org.mozilla.javascript.ast.InfixExpression;
|
||||||
|
import org.mozilla.javascript.ast.Name;
|
||||||
|
import org.mozilla.javascript.ast.NodeVisitor;
|
||||||
|
import org.mozilla.javascript.ast.PropertyGet;
|
||||||
|
import org.mozilla.javascript.ast.StringLiteral;
|
||||||
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
|
import org.teavm.model.ClassReaderSource;
|
||||||
|
import org.teavm.model.ElementModifier;
|
||||||
|
import org.teavm.model.MethodReader;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
class JavaInvocationValidator implements NodeVisitor {
|
||||||
|
private ClassReaderSource classSource;
|
||||||
|
private Diagnostics diagnostics;
|
||||||
|
private CallLocation location;
|
||||||
|
|
||||||
|
public JavaInvocationValidator(ClassReaderSource classSource, Diagnostics diagnostics) {
|
||||||
|
this.classSource = classSource;
|
||||||
|
this.diagnostics = diagnostics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(CallLocation location, AstNode root) {
|
||||||
|
this.location = location;
|
||||||
|
root.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean visit(AstNode node) {
|
||||||
|
if (node instanceof FunctionCall) {
|
||||||
|
return validateCall((FunctionCall) node);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean validateCall(FunctionCall call) {
|
||||||
|
if (!(call.getTarget() instanceof PropertyGet)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyGet propertyGet = (PropertyGet) call.getTarget();
|
||||||
|
MethodReference methodRef = getJavaMethodSelector(propertyGet.getTarget());
|
||||||
|
if (methodRef == null || !propertyGet.getProperty().getIdentifier().equals("invoke")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (AstNode arg : call.getArguments()) {
|
||||||
|
arg.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodReader method = classSource.resolve(methodRef);
|
||||||
|
if (method == null) {
|
||||||
|
diagnostics.error(location, "Java method not found: {{m0}}", methodRef);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int requiredParams = methodRef.parameterCount();
|
||||||
|
if (!method.hasModifier(ElementModifier.STATIC)) {
|
||||||
|
++requiredParams;
|
||||||
|
}
|
||||||
|
if (call.getArguments().size() != requiredParams) {
|
||||||
|
diagnostics.error(location, "Invalid number of arguments for method {{m0}}. Expected: " + requiredParams
|
||||||
|
+ ", encountered: " + call.getArguments().size(), methodRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder("$$JSO$$_");
|
||||||
|
sb.append(method.hasModifier(ElementModifier.STATIC) ? 'S' : "V");
|
||||||
|
sb.append(method.getReference().toString());
|
||||||
|
StringLiteral newTarget = new StringLiteral();
|
||||||
|
newTarget.setValue(sb.toString());
|
||||||
|
propertyGet.setTarget(newTarget);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.error(location, "javaMethods.get method should take exactly one argument");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
StringBuilder nameBuilder = new StringBuilder();
|
||||||
|
if (!extractMethodName(call.getArguments().get(0), nameBuilder)) {
|
||||||
|
diagnostics.error(location, "javaMethods.get method should take string constant");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodReference method = MethodReference.parseIfPossible(nameBuilder.toString());
|
||||||
|
if (method == null) {
|
||||||
|
diagnostics.error(location, "Wrong method reference: " + nameBuilder);
|
||||||
|
}
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -318,7 +318,7 @@ class JavascriptNativeProcessor {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method == null || method.hasModifier(ElementModifier.STATIC)) {
|
if (method.hasModifier(ElementModifier.STATIC)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,6 +579,8 @@ class JavascriptNativeProcessor {
|
||||||
} else {
|
} else {
|
||||||
expr = rootNode;
|
expr = rootNode;
|
||||||
}
|
}
|
||||||
|
JavaInvocationValidator javaValidator = new JavaInvocationValidator(classSource, diagnostics);
|
||||||
|
javaValidator.validate(location, expr);
|
||||||
repository.emitters.put(proxyMethod, new JSBodyAstEmitter(isStatic, expr, parameterNames));
|
repository.emitters.put(proxyMethod, new JSBodyAstEmitter(isStatic, expr, parameterNames));
|
||||||
}
|
}
|
||||||
repository.methodMap.put(methodToProcess.getReference(), proxyMethod);
|
repository.methodMap.put(methodToProcess.getReference(), proxyMethod);
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class AstWriterTest {
|
||||||
SourceWriterBuilder builder = new SourceWriterBuilder(null);
|
SourceWriterBuilder builder = new SourceWriterBuilder(null);
|
||||||
builder.setMinified(true);
|
builder.setMinified(true);
|
||||||
sourceWriter = builder.build(sb);
|
sourceWriter = builder.build(sb);
|
||||||
writer = new AstWriter(null, sourceWriter);
|
writer = new AstWriter(sourceWriter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.jso.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.teavm.jso.JSBody;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class JavaInvocationTest {
|
||||||
|
@Test
|
||||||
|
public void callStaticMethod() {
|
||||||
|
assertEquals(7, staticInvocation(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSBody(params = { "a" }, script = "return javaMethods.get('org.teavm.jso.test.JavaInvocationTest.sum(II)I')"
|
||||||
|
+ ".invoke(a, 2);")
|
||||||
|
private static native int staticInvocation(int a);
|
||||||
|
|
||||||
|
private static int sum(int a, int b) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user