Minor improvements and bugfixes

This commit is contained in:
Alexey Andreev 2015-01-20 18:10:13 +04:00
parent 3935d27f5b
commit 525fd89374
6 changed files with 140 additions and 117 deletions

View File

@ -16,7 +16,6 @@
package org.teavm.callgraph;
import java.util.Objects;
import org.teavm.model.CallLocation;
import org.teavm.model.InstructionLocation;
/**
@ -27,15 +26,11 @@ public class DefaultCallSite implements CallSite {
private InstructionLocation location;
private DefaultCallGraphNode callee;
private DefaultCallGraphNode caller;
private CallLocation exactLocation;
DefaultCallSite(InstructionLocation location, DefaultCallGraphNode callee, DefaultCallGraphNode caller) {
this.location = location;
this.callee = callee;
this.caller = caller;
if (caller != null) {
exactLocation = new CallLocation(caller.getMethod(), location);
}
}
@Override
@ -43,10 +38,6 @@ public class DefaultCallSite implements CallSite {
return location;
}
public CallLocation getExactLocation() {
return exactLocation;
}
@Override
public DefaultCallGraphNode getCallee() {
return callee;

View File

@ -18,6 +18,7 @@ package org.teavm.diagnostics;
import org.teavm.model.FieldReference;
import org.teavm.model.InstructionLocation;
import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
/**
*
@ -58,4 +59,9 @@ public class DefaultProblemTextConsumer implements ProblemTextConsumer {
public void appendLocation(InstructionLocation location) {
sb.append(location);
}
@Override
public void appendType(ValueType type) {
sb.append(type);
}
}

View File

@ -16,10 +16,7 @@
package org.teavm.diagnostics;
import java.util.Arrays;
import org.teavm.model.CallLocation;
import org.teavm.model.FieldReference;
import org.teavm.model.InstructionLocation;
import org.teavm.model.MethodReference;
import org.teavm.model.*;
/**
*
@ -81,6 +78,9 @@ public class Problem {
case 'c':
type = ParamType.CLASS;
break;
case 't':
type = ParamType.TYPE;
break;
case 'm':
type = ParamType.METHOD;
break;
@ -113,6 +113,12 @@ public class Problem {
}
consumer.appendClass((String)param);
break;
case TYPE:
if (!(param instanceof ValueType)) {
return index;
}
consumer.appendType((ValueType)param);
break;
case METHOD:
if (!(param instanceof MethodReference)) {
return index;
@ -145,6 +151,7 @@ public class Problem {
enum ParamType {
CLASS,
TYPE,
METHOD,
FIELD,
LOCATION

View File

@ -18,6 +18,7 @@ package org.teavm.diagnostics;
import org.teavm.model.FieldReference;
import org.teavm.model.InstructionLocation;
import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
/**
*
@ -28,6 +29,8 @@ public interface ProblemTextConsumer {
void appendClass(String className);
void appendType(ValueType type);
void appendMethod(MethodReference method);
void appendField(FieldReference field);

View File

@ -65,10 +65,6 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, TICKS_PER_PROFILE);
buildProfile(kind, subMonitor, profile, classLoader);
}
IMarker[] markers = getProject().findMarkers(TeaVMEclipsePlugin.PROBLEM_MARKER_ID, true, IResource.DEPTH_INFINITE);
for (IMarker marker : markers) {
System.out.println("MARKER INSTALLED: " + marker.getId());
}
} finally {
monitor.done();
sourceContainers = null;
@ -131,7 +127,8 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
monitor.beginTask("Running TeaVM", 10000);
tool.generate();
if (!tool.wasCancelled()) {
putMarkers(tool.getDependencyInfo().getCallGraph(), tool.getProblemProvider().getProblems());
putMarkers(tool.getDependencyInfo().getCallGraph(), tool.getProblemProvider().getProblems(),
profile);
setClasses(profile, classesToResources(tool.getClasses()));
refreshTarget(tool.getTargetDirectory());
}
@ -235,80 +232,88 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
for (IMarker marker : markers) {
String projectName = (String)marker.getAttribute(TeaVMEclipsePlugin.PROBLEM_MARKER_PROJECT_ATTRIBUTE);
String profileName = (String)marker.getAttribute(TeaVMEclipsePlugin.PROBLEM_MARKER_PROFILE_ATTRIBUTE);
if (projectName.equals(getProject().getName()) && profileName.equals(profile.getName())) {
if (projectName.equals(getProject().getName()) && (profileName == null ||
profileName.equals(profile.getName()))) {
marker.delete();
System.out.println("MARKER REMOVED: " + marker.getId() + " while building project " +
getProject().getName());
}
}
}
getProject().deleteMarkers(TeaVMEclipsePlugin.CONFIG_MARKER_ID, true, IResource.DEPTH_INFINITE);
}
private void putMarkers(CallGraph cg, List<Problem> problems) throws CoreException {
private void putMarkers(CallGraph cg, List<Problem> problems, TeaVMProfile profile) throws CoreException {
for (Problem problem : problems) {
putMarker(cg, problem);
putMarker(cg, problem, profile);
}
}
private void putMarker(CallGraph cg, Problem problem) throws CoreException {
private void putMarker(CallGraph cg, Problem problem, TeaVMProfile profile) throws CoreException {
if (problem.getLocation() == null || problem.getLocation().getMethod() == null) {
putMarkerAtDefaultLocation(problem);
putMarkerAtDefaultLocation(problem, profile);
return;
}
CallGraphNode problemNode = cg.getNode(problem.getLocation().getMethod());
if (problemNode == null) {
putMarkerAtDefaultLocation(problem);
putMarkerAtDefaultLocation(problem, profile);
return;
}
Set<CallSite> callSites = new HashSet<>();
collectCallSites(callSites, problemNode);
String messagePrefix = problemAsString(problem);
boolean wasPut = false;
for (CallSite callSite : callSites) {
IResource resource = findResource(new CallLocation(callSite.getCaller().getMethod(),
callSite.getLocation()));
if (resource == null) {
continue;
}
wasPut = true;
CallGraphNode node = problemNode;
StringBuilder sb = new StringBuilder(messagePrefix);
while (node != callSite.getCaller()) {
sb.append(", used by ").append(getFullMethodName(node.getMethod()));
Iterator<? extends CallSite> callerCallSites = node.getCallerCallSites().iterator();
if (!callerCallSites.hasNext()) {
break;
}
node = callerCallSites.next().getCaller();
}
putMarker(resource, callSite.getLocation(), callSite.getCaller().getMethod(), sb.toString());
}
IResource resource = findResource(problem.getLocation());
boolean wasPut = false;
if (resource != null) {
putMarker(resource, problem.getLocation().getSourceLocation(), problem.getLocation().getMethod(),
messagePrefix);
wasPut = true;
wasPut |= putMarker(resource, problem.getLocation().getSourceLocation(), problem.getLocation().getMethod(),
messagePrefix, profile, false);
}
if (!wasPut) {
putMarkerAtDefaultLocation(problem);
wasPut |= putMarkersAtCallSites(problemNode, new HashSet<CallGraphNode>(), messagePrefix, profile,
false);
}
if (!wasPut) {
wasPut |= putMarkersAtCallSites(problemNode, new HashSet<CallGraphNode>(), messagePrefix, profile, true);
}
if (!wasPut) {
putMarkerAtDefaultLocation(problem, profile);
}
}
private void putMarker(IResource resource, InstructionLocation location, MethodReference method,
String text) throws CoreException {
IMarker marker = resource.createMarker(TeaVMEclipsePlugin.PROBLEM_MARKER_ID);
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
marker.setAttribute(IMarker.MESSAGE, text);
marker.setAttribute(TeaVMEclipsePlugin.PROBLEM_MARKER_PROJECT_ATTRIBUTE, getProject().getName());
private boolean putMarkersAtCallSites(CallGraphNode node, Set<CallGraphNode> visited, String problem,
TeaVMProfile profile, boolean force) throws CoreException {
if (!visited.add(node)) {
return false;
}
boolean wasPut = true;
for (CallSite callSite : node.getCallerCallSites()) {
IResource resource = findResource(new CallLocation(callSite.getCaller().getMethod(),
callSite.getLocation()));
if (resource != null) {
wasPut = putMarker(resource, callSite.getLocation(), callSite.getCaller().getMethod(), problem,
profile, force);
}
wasPut |= putMarkersAtCallSites(callSite.getCaller(), visited, problem + ", used by " +
getFullMethodName(callSite.getCaller().getMethod()), profile, force);
}
return wasPut;
}
private boolean putMarker(IResource resource, InstructionLocation location, MethodReference method,
String text, TeaVMProfile profile, boolean force) throws CoreException {
Integer lineNumber = location != null ? location.getLine() : null;
if (lineNumber == null) {
lineNumber = findMethodLocation(method, resource);
}
if (lineNumber == null) {
if (!force) {
return false;
}
lineNumber = 1;
}
IMarker marker = resource.createMarker(TeaVMEclipsePlugin.PROBLEM_MARKER_ID);
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
marker.setAttribute(IMarker.MESSAGE, text);
marker.setAttribute(TeaVMEclipsePlugin.PROBLEM_MARKER_PROJECT_ATTRIBUTE, getProject().getName());
marker.setAttribute(TeaVMEclipsePlugin.PROBLEM_MARKER_PROFILE_ATTRIBUTE, profile.getName());
marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
return true;
}
private IResource findResource(CallLocation location) {
@ -334,19 +339,12 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
return resource;
}
private void collectCallSites(Set<CallSite> callSites, CallGraphNode node) {
for (CallSite callSite : node.getCallerCallSites()) {
if (callSites.add(callSite)) {
collectCallSites(callSites, callSite.getCaller());
}
}
}
private void putMarkerAtDefaultLocation(Problem problem) throws CoreException {
private void putMarkerAtDefaultLocation(Problem problem, TeaVMProfile profile) throws CoreException {
IMarker marker = getProject().createMarker(TeaVMEclipsePlugin.PROBLEM_MARKER_ID);
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
marker.setAttribute(IMarker.MESSAGE, problemAsString(problem));
marker.setAttribute(TeaVMEclipsePlugin.PROBLEM_MARKER_PROJECT_ATTRIBUTE, getProject().getName());
marker.setAttribute(TeaVMEclipsePlugin.PROBLEM_MARKER_PROFILE_ATTRIBUTE, profile.getName());
}
private Integer findMethodLocation(MethodReference methodRef, IResource resource) throws CoreException {
@ -364,12 +362,12 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
}
for (IMethod method : type.getMethods()) {
StringBuilder sb = new StringBuilder();
sb.append('(');
sb.append(method.getElementName()).append('(');
for (String paramType : method.getParameterTypes()) {
sb.append(Signature.getTypeErasure(paramType));
}
sb.append(')').append(Signature.getTypeErasure(method.getReturnType()));
if (sb.toString().equals(methodRef.toString())) {
if (sb.toString().equals(methodRef.getDescriptor().toString())) {
return getLineNumber(method);
}
}
@ -401,6 +399,9 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
@Override public void appendClass(String cls) {
sb.append(getSimpleClassName(cls));
}
@Override public void appendType(ValueType type) {
sb.append(getTypeName(type));
}
@Override public void append(String text) {
sb.append(text);
}
@ -472,7 +473,7 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
private String getSimpleClassName(String className) {
int index = className.lastIndexOf('.');
return className.substring(index + 1);
return className.substring(index + 1).replace('$', '.');
}
private TeaVMProjectSettings getProjectSettings() {

View File

@ -95,10 +95,10 @@ class JavascriptNativeProcessor {
cutPrefix(method.getName(), 3);
}
Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
addPropertyGet(propertyName, invoke.getInstance(), result);
addPropertyGet(propertyName, invoke.getInstance(), result, invoke.getLocation());
if (result != null) {
result = unwrap(callLocation, result, method.getResultType());
copyVar(result, invoke.getReceiver());
copyVar(result, invoke.getReceiver(), invoke.getLocation());
}
} else if (isProperSetter(method.getDescriptor())) {
String propertyName;
@ -110,28 +110,30 @@ class JavascriptNativeProcessor {
}
Variable wrapped = wrapArgument(callLocation, invoke.getArguments().get(0),
method.parameterType(0));
addPropertySet(propertyName, invoke.getInstance(), wrapped);
addPropertySet(propertyName, invoke.getInstance(), wrapped, invoke.getLocation());
} else {
diagnostics.error(callLocation, "Method " + invoke.getMethod() + " is not " +
"a proper native JavaScript property declaration");
diagnostics.error(callLocation, "Method {{m0}} is not a proper native JavaScript property " +
"declaration", invoke.getMethod());
continue;
}
} else if (method.getAnnotations().get(JSIndexer.class.getName()) != null) {
if (isProperGetIndexer(method.getDescriptor())) {
Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
addIndexerGet(invoke.getInstance(), wrap(invoke.getArguments().get(0),
method.parameterType(0)), result);
method.parameterType(0), invoke.getLocation()), result, invoke.getLocation());
if (result != null) {
result = unwrap(callLocation, result, method.getResultType());
copyVar(result, invoke.getReceiver());
copyVar(result, invoke.getReceiver(), invoke.getLocation());
}
} else if (isProperSetIndexer(method.getDescriptor())) {
Variable index = wrap(invoke.getArguments().get(0), method.parameterType(0));
Variable value = wrap(invoke.getArguments().get(1), method.parameterType(1));
addIndexerSet(invoke.getInstance(), index, value);
Variable index = wrap(invoke.getArguments().get(0), method.parameterType(0),
invoke.getLocation());
Variable value = wrap(invoke.getArguments().get(1), method.parameterType(1),
invoke.getLocation());
addIndexerSet(invoke.getInstance(), index, value, invoke.getLocation());
} else {
diagnostics.error(callLocation, "Method " + invoke.getMethod() + " is not " +
"a proper native JavaScript indexer declaration");
diagnostics.error(callLocation, "Method {{m0}} is not a proper native JavaScript indexer " +
"declaration", invoke.getMethod());
continue;
}
} else {
@ -140,17 +142,17 @@ class JavascriptNativeProcessor {
boolean isConstructor = false;
if (constructorAnnot != null) {
if (!isSupportedType(method.getResultType())) {
diagnostics.error(callLocation, "Method " + invoke.getMethod() + " is not " +
"a proper native JavaScript constructor declaration");
diagnostics.error(callLocation, "Method {{m0}} is not a proper native JavaScript " +
"constructor declaration", invoke.getMethod());
continue;
}
AnnotationValue nameVal = constructorAnnot.getValue("value");
name = nameVal != null ? constructorAnnot.getValue("value").getString() : "";
if (name.isEmpty()) {
if (!method.getName().startsWith("new") || method.getName().length() == 3) {
diagnostics.error(callLocation, "Method " + invoke.getMethod() + " is not " +
"declared as a native JavaScript constructor, but its name does " +
"not satisfy conventions");
diagnostics.error(callLocation, "Method {{m0}} is not declared as a native " +
"JavaScript constructor, but its name does not satisfy conventions",
invoke.getMethod());
continue;
}
name = method.getName().substring(3);
@ -165,15 +167,15 @@ class JavascriptNativeProcessor {
}
}
if (method.getResultType() != ValueType.VOID && !isSupportedType(method.getResultType())) {
diagnostics.error(callLocation, "Method " + invoke.getMethod() + " is not " +
"a proper native JavaScript method declaration");
diagnostics.error(callLocation, "Method {{m0}} is not a proper native JavaScript method " +
"declaration", invoke.getMethod());
continue;
}
}
for (ValueType arg : method.getParameterTypes()) {
if (!isSupportedType(arg)) {
diagnostics.error(callLocation, "Method " + invoke.getMethod() + " is not " +
"a proper native JavaScript method or constructor declaration");
diagnostics.error(callLocation, "Method {{m0}} is not a proper native JavaScript method " +
"or constructor declaration", invoke.getMethod());
continue;
}
}
@ -186,7 +188,9 @@ class JavascriptNativeProcessor {
newInvoke.setType(InvocationType.SPECIAL);
newInvoke.setReceiver(result);
newInvoke.getArguments().add(invoke.getInstance());
newInvoke.getArguments().add(addStringWrap(addString(name)));
newInvoke.getArguments().add(addStringWrap(addString(name, invoke.getLocation()),
invoke.getLocation()));
newInvoke.setLocation(invoke.getLocation());
for (int k = 0; k < invoke.getArguments().size(); ++k) {
Variable arg = wrapArgument(callLocation, invoke.getArguments().get(k),
method.parameterType(k));
@ -195,7 +199,7 @@ class JavascriptNativeProcessor {
replacement.add(newInvoke);
if (result != null) {
result = unwrap(callLocation, result, method.getResultType());
copyVar(result, invoke.getReceiver());
copyVar(result, invoke.getReceiver(), invoke.getLocation());
}
}
block.getInstructions().set(j, replacement.get(0));
@ -205,19 +209,21 @@ class JavascriptNativeProcessor {
}
}
private void addPropertyGet(String propertyName, Variable instance, Variable receiver) {
Variable nameVar = addStringWrap(addString(propertyName));
private void addPropertyGet(String propertyName, Variable instance, Variable receiver,
InstructionLocation location) {
Variable nameVar = addStringWrap(addString(propertyName, location), location);
InvokeInstruction insn = new InvokeInstruction();
insn.setType(InvocationType.SPECIAL);
insn.setMethod(new MethodReference(JS.class, "get", JSObject.class, JSObject.class, JSObject.class));
insn.setReceiver(receiver);
insn.getArguments().add(instance);
insn.getArguments().add(nameVar);
insn.setLocation(location);
replacement.add(insn);
}
private void addPropertySet(String propertyName, Variable instance, Variable value) {
Variable nameVar = addStringWrap(addString(propertyName));
private void addPropertySet(String propertyName, Variable instance, Variable value, InstructionLocation location) {
Variable nameVar = addStringWrap(addString(propertyName, location), location);
InvokeInstruction insn = new InvokeInstruction();
insn.setType(InvocationType.SPECIAL);
insn.setMethod(new MethodReference(JS.class, "set", JSObject.class, JSObject.class,
@ -225,20 +231,22 @@ class JavascriptNativeProcessor {
insn.getArguments().add(instance);
insn.getArguments().add(nameVar);
insn.getArguments().add(value);
insn.setLocation(location);
replacement.add(insn);
}
private void addIndexerGet(Variable array, Variable index, Variable receiver) {
private void addIndexerGet(Variable array, Variable index, Variable receiver, InstructionLocation location) {
InvokeInstruction insn = new InvokeInstruction();
insn.setType(InvocationType.SPECIAL);
insn.setMethod(new MethodReference(JS.class, "get", JSObject.class, JSObject.class, JSObject.class));
insn.setReceiver(receiver);
insn.getArguments().add(array);
insn.getArguments().add(index);
insn.setLocation(location);
replacement.add(insn);
}
private void addIndexerSet(Variable array, Variable index, Variable value) {
private void addIndexerSet(Variable array, Variable index, Variable value, InstructionLocation location) {
InvokeInstruction insn = new InvokeInstruction();
insn.setType(InvocationType.SPECIAL);
insn.setMethod(new MethodReference(JS.class, "set", JSObject.class, JSObject.class,
@ -246,25 +254,28 @@ class JavascriptNativeProcessor {
insn.getArguments().add(array);
insn.getArguments().add(index);
insn.getArguments().add(value);
insn.setLocation(location);
replacement.add(insn);
}
private void copyVar(Variable a, Variable b) {
private void copyVar(Variable a, Variable b, InstructionLocation location) {
AssignInstruction insn = new AssignInstruction();
insn.setAssignee(a);
insn.setReceiver(b);
insn.setLocation(location);
replacement.add(insn);
}
private Variable addStringWrap(Variable var) {
return wrap(var, ValueType.object("java.lang.String"));
private Variable addStringWrap(Variable var, InstructionLocation location) {
return wrap(var, ValueType.object("java.lang.String"), location);
}
private Variable addString(String str) {
private Variable addString(String str, InstructionLocation location) {
Variable var = program.createVariable();
StringConstantInstruction nameInsn = new StringConstantInstruction();
nameInsn.setReceiver(var);
nameInsn.setConstant(str);
nameInsn.setLocation(location);
replacement.add(nameInsn);
return var;
}
@ -273,19 +284,19 @@ class JavascriptNativeProcessor {
if (type instanceof ValueType.Primitive) {
switch (((ValueType.Primitive)type).getKind()) {
case BOOLEAN:
return unwrap(var, "unwrapBoolean", ValueType.BOOLEAN);
return unwrap(var, "unwrapBoolean", ValueType.BOOLEAN, location.getSourceLocation());
case BYTE:
return unwrap(var, "unwrapByte", ValueType.BYTE);
return unwrap(var, "unwrapByte", ValueType.BYTE, location.getSourceLocation());
case SHORT:
return unwrap(var, "unwrapShort", ValueType.SHORT);
return unwrap(var, "unwrapShort", ValueType.SHORT, location.getSourceLocation());
case INTEGER:
return unwrap(var, "unwrapInt", ValueType.INTEGER);
return unwrap(var, "unwrapInt", ValueType.INTEGER, location.getSourceLocation());
case CHARACTER:
return unwrap(var, "unwrapCharacter", ValueType.CHARACTER);
return unwrap(var, "unwrapCharacter", ValueType.CHARACTER, location.getSourceLocation());
case DOUBLE:
return unwrap(var, "unwrapDouble", ValueType.DOUBLE);
return unwrap(var, "unwrapDouble", ValueType.DOUBLE, location.getSourceLocation());
case FLOAT:
return unwrap(var, "unwrapFloat", ValueType.FLOAT);
return unwrap(var, "unwrapFloat", ValueType.FLOAT, location.getSourceLocation());
case LONG:
break;
}
@ -294,22 +305,23 @@ class JavascriptNativeProcessor {
if (className.equals(JSObject.class.getName())) {
return var;
} else if (className.equals("java.lang.String")) {
return unwrap(var, "unwrapString", ValueType.object("java.lang.String"));
return unwrap(var, "unwrapString", ValueType.object("java.lang.String"), location.getSourceLocation());
} else {
Variable result = program.createVariable();
CastInstruction castInsn = new CastInstruction();
castInsn.setReceiver(result);
castInsn.setValue(var);
castInsn.setTargetType(type);
castInsn.setLocation(location.getSourceLocation());
replacement.add(castInsn);
return result;
}
}
diagnostics.error(location, "Unsupported type: " + type);
diagnostics.error(location, "Unsupported type: {{t0}}", type);
return var;
}
private Variable unwrap(Variable var, String methodName, ValueType resultType) {
private Variable unwrap(Variable var, String methodName, ValueType resultType, InstructionLocation location) {
Variable result = program.createVariable();
InvokeInstruction insn = new InvokeInstruction();
insn.setMethod(new MethodReference(JS.class.getName(), methodName, ValueType.object(JSObject.class.getName()),
@ -317,6 +329,7 @@ class JavascriptNativeProcessor {
insn.getArguments().add(var);
insn.setReceiver(result);
insn.setType(InvocationType.SPECIAL);
insn.setLocation(location);
replacement.add(insn);
return result;
}
@ -329,28 +342,29 @@ class JavascriptNativeProcessor {
return wrapFunctor(location, var, cls);
}
}
return wrap(var, type);
return wrap(var, type, location.getSourceLocation());
}
private Variable wrapFunctor(CallLocation location, Variable var, ClassReader type) {
if (!type.hasModifier(ElementModifier.INTERFACE) || type.getMethods().size() != 1) {
diagnostics.error(location, "Wrong functor: " + type.getName());
diagnostics.error(location, "Wrong functor: {{c0}}", type.getName());
return var;
}
String name = type.getMethods().iterator().next().getName();
Variable functor = program.createVariable();
Variable nameVar = addStringWrap(addString(name));
Variable nameVar = addStringWrap(addString(name, location.getSourceLocation()), location.getSourceLocation());
InvokeInstruction insn = new InvokeInstruction();
insn.setType(InvocationType.SPECIAL);
insn.setMethod(new MethodReference(JS.class, "function", JSObject.class, JSObject.class, JSObject.class));
insn.setReceiver(functor);
insn.getArguments().add(var);
insn.getArguments().add(nameVar);
insn.setLocation(location.getSourceLocation());
replacement.add(insn);
return functor;
}
private Variable wrap(Variable var, ValueType type) {
private Variable wrap(Variable var, ValueType type, InstructionLocation location) {
if (type instanceof ValueType.Object) {
String className = ((ValueType.Object)type).getClassName();
if (!className.equals("java.lang.String")) {
@ -364,6 +378,7 @@ class JavascriptNativeProcessor {
insn.getArguments().add(var);
insn.setReceiver(result);
insn.setType(InvocationType.SPECIAL);
insn.setLocation(location);
replacement.add(insn);
return result;
}