mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Dependency API supports multiple occurence of reaching events for
different location
This commit is contained in:
parent
cd0664d695
commit
1fff443c36
|
@ -31,12 +31,12 @@ public class ClassLookupDependencySupport implements DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void classAchieved(DependencyAgent agent, String className) {
|
public void classAchieved(DependencyAgent agent, String className, CallLocation location) {
|
||||||
allClasses.propagate(agent.getType(className));
|
allClasses.propagate(agent.getType(className));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(final DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(final DependencyAgent agent, MethodDependency method, final CallLocation location) {
|
||||||
MethodReference ref = method.getReference();
|
MethodReference ref = method.getReference();
|
||||||
if (ref.getClassName().equals("java.lang.Class") && ref.getName().equals("forNameImpl")) {
|
if (ref.getClassName().equals("java.lang.Class") && ref.getName().equals("forNameImpl")) {
|
||||||
allClasses.addConsumer(new DependencyConsumer() {
|
allClasses.addConsumer(new DependencyConsumer() {
|
||||||
|
@ -47,7 +47,7 @@ public class ClassLookupDependencySupport implements DependencyListener {
|
||||||
}
|
}
|
||||||
MethodReader initMethod = cls.getMethod(new MethodDescriptor("<clinit>", ValueType.VOID));
|
MethodReader initMethod = cls.getMethod(new MethodDescriptor("<clinit>", ValueType.VOID));
|
||||||
if (initMethod != null) {
|
if (initMethod != null) {
|
||||||
agent.linkMethod(initMethod.getReference(), null).use();
|
agent.linkMethod(initMethod.getReference(), location).use();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -55,6 +55,6 @@ public class ClassLookupDependencySupport implements DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fieldAchieved(DependencyAgent dependencyChecker, FieldDependency field) {
|
public void fieldAchieved(DependencyAgent dependencyChecker, FieldDependency field, CallLocation location) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.classlib.impl;
|
package org.teavm.classlib.impl;
|
||||||
|
|
||||||
import org.teavm.dependency.*;
|
import org.teavm.dependency.*;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
import org.teavm.model.MethodReader;
|
import org.teavm.model.MethodReader;
|
||||||
|
@ -35,7 +36,7 @@ public class EnumDependencySupport implements DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void classAchieved(DependencyAgent agent, String className) {
|
public void classAchieved(DependencyAgent agent, String className, CallLocation location) {
|
||||||
ClassReader cls = agent.getClassSource().get(className);
|
ClassReader cls = agent.getClassSource().get(className);
|
||||||
if (cls == null || cls.getParent() == null || !cls.getParent().equals("java.lang.Enum")) {
|
if (cls == null || cls.getParent() == null || !cls.getParent().equals("java.lang.Enum")) {
|
||||||
return;
|
return;
|
||||||
|
@ -45,25 +46,25 @@ public class EnumDependencySupport implements DependencyListener {
|
||||||
MethodReader method = cls.getMethod(new MethodDescriptor("values",
|
MethodReader method = cls.getMethod(new MethodDescriptor("values",
|
||||||
ValueType.arrayOf(ValueType.object(cls.getName()))));
|
ValueType.arrayOf(ValueType.object(cls.getName()))));
|
||||||
if (method != null) {
|
if (method != null) {
|
||||||
agent.linkMethod(method.getReference(), null).use();
|
agent.linkMethod(method.getReference(), location).use();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
if (method.getReference().getClassName().equals("java.lang.Class") &&
|
if (method.getReference().getClassName().equals("java.lang.Class") &&
|
||||||
method.getReference().getName().equals("getEnumConstantsImpl")) {
|
method.getReference().getName().equals("getEnumConstantsImpl")) {
|
||||||
unlocked = true;
|
unlocked = true;
|
||||||
allEnums.connect(method.getResult().getArrayItem());
|
allEnums.connect(method.getResult().getArrayItem());
|
||||||
method.getResult().propagate(agent.getType("[java.lang.Enum"));
|
method.getResult().propagate(agent.getType("[java.lang.Enum"));
|
||||||
for (String cls : agent.getAchievableClasses()) {
|
for (String cls : agent.getAchievableClasses()) {
|
||||||
classAchieved(agent, cls);
|
classAchieved(agent, cls, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fieldAchieved(DependencyAgent agent, FieldDependency field) {
|
public void fieldAchieved(DependencyAgent agent, FieldDependency field, CallLocation location) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ public class NewInstanceDependencySupport implements DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void classAchieved(DependencyAgent agent, String className) {
|
public void classAchieved(DependencyAgent agent, String className, CallLocation location) {
|
||||||
ClassReader cls = agent.getClassSource().get(className);
|
ClassReader cls = agent.getClassSource().get(className);
|
||||||
if (cls == null) {
|
if (cls == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -46,24 +46,24 @@ public class NewInstanceDependencySupport implements DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(final DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(final DependencyAgent agent, MethodDependency method, final CallLocation location) {
|
||||||
MethodReader reader = method.getMethod();
|
MethodReader reader = method.getMethod();
|
||||||
if (reader.getOwnerName().equals("java.lang.Class") && reader.getName().equals("newInstance")) {
|
if (reader.getOwnerName().equals("java.lang.Class") && reader.getName().equals("newInstance")) {
|
||||||
allClassesNode.connect(method.getResult());
|
allClassesNode.connect(method.getResult());
|
||||||
method.getResult().addConsumer(new DependencyConsumer() {
|
method.getResult().addConsumer(new DependencyConsumer() {
|
||||||
@Override public void consume(DependencyAgentType type) {
|
@Override public void consume(DependencyAgentType type) {
|
||||||
attachConstructor(agent, type.getName());
|
attachConstructor(agent, type.getName(), location);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attachConstructor(DependencyAgent checker, String type) {
|
private void attachConstructor(DependencyAgent checker, String type, CallLocation location) {
|
||||||
MethodReference ref = new MethodReference(type, new MethodDescriptor("<init>", ValueType.VOID));
|
MethodReference ref = new MethodReference(type, new MethodDescriptor("<init>", ValueType.VOID));
|
||||||
checker.linkMethod(ref, null).use();
|
checker.linkMethod(ref, location).use();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fieldAchieved(DependencyAgent dependencyAgent, FieldDependency field) {
|
public void fieldAchieved(DependencyAgent dependencyAgent, FieldDependency field, CallLocation location) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.teavm.codegen.SourceWriter;
|
||||||
import org.teavm.dependency.*;
|
import org.teavm.dependency.*;
|
||||||
import org.teavm.javascript.ni.Generator;
|
import org.teavm.javascript.ni.Generator;
|
||||||
import org.teavm.javascript.ni.GeneratorContext;
|
import org.teavm.javascript.ni.GeneratorContext;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
|
@ -34,6 +35,7 @@ import org.teavm.model.ValueType;
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public class ServiceLoaderSupport implements Generator, DependencyListener {
|
public class ServiceLoaderSupport implements Generator, DependencyListener {
|
||||||
|
private Set<String> achievedClasses;
|
||||||
private Map<String, List<String>> serviceMap = new HashMap<>();
|
private Map<String, List<String>> serviceMap = new HashMap<>();
|
||||||
private DependencyNode allClassesNode;
|
private DependencyNode allClassesNode;
|
||||||
private ClassLoader classLoader;
|
private ClassLoader classLoader;
|
||||||
|
@ -82,7 +84,10 @@ public class ServiceLoaderSupport implements Generator, DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void classAchieved(DependencyAgent agent, String className) {
|
public void classAchieved(DependencyAgent agent, String className, CallLocation location) {
|
||||||
|
if (!achievedClasses.add(className)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Enumeration<URL> resources = classLoader.getResources("META-INF/services/" + className);
|
Enumeration<URL> resources = classLoader.getResources("META-INF/services/" + className);
|
||||||
while (resources.hasMoreElements()) {
|
while (resources.hasMoreElements()) {
|
||||||
|
@ -118,25 +123,25 @@ public class ServiceLoaderSupport implements Generator, DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(final DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(final DependencyAgent agent, MethodDependency method, final CallLocation location) {
|
||||||
MethodReference ref = method.getReference();
|
MethodReference ref = method.getReference();
|
||||||
if (ref.getClassName().equals("java.util.ServiceLoader") && ref.getName().equals("loadServices")) {
|
if (ref.getClassName().equals("java.util.ServiceLoader") && ref.getName().equals("loadServices")) {
|
||||||
method.getResult().propagate(agent.getType("[java.lang.Object"));
|
method.getResult().propagate(agent.getType("[java.lang.Object"));
|
||||||
allClassesNode.connect(method.getResult().getArrayItem());
|
allClassesNode.connect(method.getResult().getArrayItem());
|
||||||
method.getResult().getArrayItem().addConsumer(new DependencyConsumer() {
|
method.getResult().getArrayItem().addConsumer(new DependencyConsumer() {
|
||||||
@Override public void consume(DependencyAgentType type) {
|
@Override public void consume(DependencyAgentType type) {
|
||||||
initConstructor(agent, type.getName());
|
initConstructor(agent, type.getName(), location);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initConstructor(DependencyAgent agent, String type) {
|
private void initConstructor(DependencyAgent agent, String type, CallLocation location) {
|
||||||
MethodReference ctor = new MethodReference(type, new MethodDescriptor("<init>", ValueType.VOID));
|
MethodReference ctor = new MethodReference(type, new MethodDescriptor("<init>", ValueType.VOID));
|
||||||
agent.linkMethod(ctor, null).use();
|
agent.linkMethod(ctor, location).use();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fieldAchieved(DependencyAgent agent, FieldDependency field) {
|
public void fieldAchieved(DependencyAgent agent, FieldDependency field, CallLocation location) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.teavm.dependency.DependencyPlugin;
|
||||||
import org.teavm.dependency.MethodDependency;
|
import org.teavm.dependency.MethodDependency;
|
||||||
import org.teavm.javascript.ni.Generator;
|
import org.teavm.javascript.ni.Generator;
|
||||||
import org.teavm.javascript.ni.GeneratorContext;
|
import org.teavm.javascript.ni.GeneratorContext;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,7 +53,7 @@ public class CharacterNativeGenerator implements Generator, DependencyPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
switch (method.getReference().getName()) {
|
switch (method.getReference().getName()) {
|
||||||
case "obtainDigitMapping":
|
case "obtainDigitMapping":
|
||||||
case "obtainClasses":
|
case "obtainClasses":
|
||||||
|
|
|
@ -186,7 +186,7 @@ public class ClassNativeGenerator implements Generator, Injector, DependencyPlug
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency graph) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency graph, CallLocation location) {
|
||||||
switch (graph.getReference().getName()) {
|
switch (graph.getReference().getName()) {
|
||||||
case "voidClass":
|
case "voidClass":
|
||||||
case "booleanClass":
|
case "booleanClass":
|
||||||
|
@ -205,8 +205,8 @@ public class ClassNativeGenerator implements Generator, Injector, DependencyPlug
|
||||||
graph.getResult().propagate(agent.getType("java.lang.Class"));
|
graph.getResult().propagate(agent.getType("java.lang.Class"));
|
||||||
break;
|
break;
|
||||||
case "newInstance":
|
case "newInstance":
|
||||||
agent.linkMethod(new MethodReference(InstantiationException.class.getName(), "<init>",
|
agent.linkMethod(new MethodReference(InstantiationException.class, "<init>", void.class),
|
||||||
ValueType.VOID), null).use();
|
location).use();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.teavm.javascript.ni.Generator;
|
||||||
import org.teavm.javascript.ni.GeneratorContext;
|
import org.teavm.javascript.ni.GeneratorContext;
|
||||||
import org.teavm.javascript.ni.Injector;
|
import org.teavm.javascript.ni.Injector;
|
||||||
import org.teavm.javascript.ni.InjectorContext;
|
import org.teavm.javascript.ni.InjectorContext;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,7 +59,7 @@ public class ObjectNativeGenerator implements Generator, Injector, DependencyPlu
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
switch (method.getReference().getName()) {
|
switch (method.getReference().getName()) {
|
||||||
case "clone":
|
case "clone":
|
||||||
method.getVariable(0).connect(method.getResult());
|
method.getVariable(0).connect(method.getResult());
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.teavm.dependency.DependencyPlugin;
|
||||||
import org.teavm.dependency.MethodDependency;
|
import org.teavm.dependency.MethodDependency;
|
||||||
import org.teavm.javascript.ni.Injector;
|
import org.teavm.javascript.ni.Injector;
|
||||||
import org.teavm.javascript.ni.InjectorContext;
|
import org.teavm.javascript.ni.InjectorContext;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,7 +30,7 @@ import org.teavm.model.MethodReference;
|
||||||
*/
|
*/
|
||||||
public class StringNativeGenerator implements Injector, DependencyPlugin {
|
public class StringNativeGenerator implements Injector, DependencyPlugin {
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
switch (method.getReference().getName()) {
|
switch (method.getReference().getName()) {
|
||||||
case "wrap":
|
case "wrap":
|
||||||
method.getVariable(1).connect(method.getResult());
|
method.getVariable(1).connect(method.getResult());
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.teavm.codegen.SourceWriter;
|
||||||
import org.teavm.dependency.*;
|
import org.teavm.dependency.*;
|
||||||
import org.teavm.javascript.ni.Generator;
|
import org.teavm.javascript.ni.Generator;
|
||||||
import org.teavm.javascript.ni.GeneratorContext;
|
import org.teavm.javascript.ni.GeneratorContext;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.FieldReference;
|
import org.teavm.model.FieldReference;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ public class SystemNativeGenerator implements Generator, DependencyPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
switch (method.getReference().getName()) {
|
switch (method.getReference().getName()) {
|
||||||
case "doArrayCopy":
|
case "doArrayCopy":
|
||||||
achieveArrayCopy(method);
|
achieveArrayCopy(method);
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.teavm.codegen.SourceWriter;
|
||||||
import org.teavm.dependency.*;
|
import org.teavm.dependency.*;
|
||||||
import org.teavm.javascript.ni.Generator;
|
import org.teavm.javascript.ni.Generator;
|
||||||
import org.teavm.javascript.ni.GeneratorContext;
|
import org.teavm.javascript.ni.GeneratorContext;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
@ -38,7 +39,7 @@ public class ArrayNativeGenerator implements Generator, DependencyPlugin {
|
||||||
ValueType.INTEGER, ValueType.LONG, ValueType.FLOAT, ValueType.DOUBLE, ValueType.BOOLEAN };
|
ValueType.INTEGER, ValueType.LONG, ValueType.FLOAT, ValueType.DOUBLE, ValueType.BOOLEAN };
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
switch (method.getReference().getName()) {
|
switch (method.getReference().getName()) {
|
||||||
case "getLength":
|
case "getLength":
|
||||||
achieveGetLength(agent, method);
|
achieveGetLength(agent, method);
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.teavm.dependency.DependencyPlugin;
|
||||||
import org.teavm.dependency.MethodDependency;
|
import org.teavm.dependency.MethodDependency;
|
||||||
import org.teavm.javascript.ni.Generator;
|
import org.teavm.javascript.ni.Generator;
|
||||||
import org.teavm.javascript.ni.GeneratorContext;
|
import org.teavm.javascript.ni.GeneratorContext;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,7 +71,7 @@ public class DateNativeGenerator implements Generator, DependencyPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
switch (method.getMethod().getName()) {
|
switch (method.getMethod().getName()) {
|
||||||
case "toString":
|
case "toString":
|
||||||
case "toLocaleFormat":
|
case "toLocaleFormat":
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.teavm.dependency.DependencyPlugin;
|
||||||
import org.teavm.dependency.MethodDependency;
|
import org.teavm.dependency.MethodDependency;
|
||||||
import org.teavm.javascript.ni.Generator;
|
import org.teavm.javascript.ni.Generator;
|
||||||
import org.teavm.javascript.ni.GeneratorContext;
|
import org.teavm.javascript.ni.GeneratorContext;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,7 +35,7 @@ public class TimerNativeGenerator implements Generator, DependencyPlugin {
|
||||||
"performOnce", void.class);
|
"performOnce", void.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
switch (method.getReference().getName()) {
|
switch (method.getReference().getName()) {
|
||||||
case "scheduleOnce": {
|
case "scheduleOnce": {
|
||||||
MethodDependency performMethod = agent.linkMethod(performOnceRef, null);
|
MethodDependency performMethod = agent.linkMethod(performOnceRef, null);
|
||||||
|
|
|
@ -69,16 +69,19 @@ public class DefaultCallGraphNode implements CallGraphNode {
|
||||||
return safeCallersCallSites;
|
return safeCallersCallSites;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCallSite(MethodReference method, InstructionLocation location) {
|
public boolean addCallSite(MethodReference method, InstructionLocation location) {
|
||||||
DefaultCallGraphNode callee = graph.getNode(method);
|
DefaultCallGraphNode callee = graph.getNode(method);
|
||||||
DefaultCallSite callSite = new DefaultCallSite(location, callee, this);
|
DefaultCallSite callSite = new DefaultCallSite(location, callee, this);
|
||||||
if (callSites.add(callSite)) {
|
if (callSites.add(callSite)) {
|
||||||
callee.callerCallSites.add(callSite);
|
callee.callerCallSites.add(callSite);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCallSite(MethodReference method) {
|
public boolean addCallSite(MethodReference method) {
|
||||||
addCallSite(method, null);
|
return addCallSite(method, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.callgraph;
|
package org.teavm.callgraph;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.InstructionLocation;
|
import org.teavm.model.InstructionLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,11 +27,15 @@ public class DefaultCallSite implements CallSite {
|
||||||
private InstructionLocation location;
|
private InstructionLocation location;
|
||||||
private DefaultCallGraphNode callee;
|
private DefaultCallGraphNode callee;
|
||||||
private DefaultCallGraphNode caller;
|
private DefaultCallGraphNode caller;
|
||||||
|
private CallLocation exactLocation;
|
||||||
|
|
||||||
DefaultCallSite(InstructionLocation location, DefaultCallGraphNode callee, DefaultCallGraphNode caller) {
|
DefaultCallSite(InstructionLocation location, DefaultCallGraphNode callee, DefaultCallGraphNode caller) {
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.callee = callee;
|
this.callee = callee;
|
||||||
this.caller = caller;
|
this.caller = caller;
|
||||||
|
if (caller != null) {
|
||||||
|
exactLocation = new CallLocation(caller.getMethod(), location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,6 +43,10 @@ public class DefaultCallSite implements CallSite {
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CallLocation getExactLocation() {
|
||||||
|
return exactLocation;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultCallGraphNode getCallee() {
|
public DefaultCallGraphNode getCallee() {
|
||||||
return callee;
|
return callee;
|
||||||
|
|
|
@ -26,7 +26,6 @@ import org.teavm.callgraph.CallGraph;
|
||||||
import org.teavm.callgraph.DefaultCallGraph;
|
import org.teavm.callgraph.DefaultCallGraph;
|
||||||
import org.teavm.callgraph.DefaultCallGraphNode;
|
import org.teavm.callgraph.DefaultCallGraphNode;
|
||||||
import org.teavm.common.CachedMapper;
|
import org.teavm.common.CachedMapper;
|
||||||
import org.teavm.common.CachedMapper.KeyListener;
|
|
||||||
import org.teavm.common.Mapper;
|
import org.teavm.common.Mapper;
|
||||||
import org.teavm.common.ServiceRepository;
|
import org.teavm.common.ServiceRepository;
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
|
@ -109,37 +108,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
return createClassDependency(preimage);
|
return createClassDependency(preimage);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
methodCache.addKeyListener(new KeyListener<MethodReference>() {
|
|
||||||
@Override public void keyAdded(MethodReference key) {
|
|
||||||
MethodDependency graph = methodCache.getKnown(key);
|
|
||||||
if (!graph.isMissing()) {
|
|
||||||
for (DependencyListener listener : listeners) {
|
|
||||||
listener.methodAchieved(DependencyChecker.this, graph);
|
|
||||||
}
|
|
||||||
activateDependencyPlugin(graph);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
fieldCache.addKeyListener(new KeyListener<FieldReference>() {
|
|
||||||
@Override public void keyAdded(FieldReference key) {
|
|
||||||
FieldDependency fieldDep = fieldCache.getKnown(key);
|
|
||||||
if (!fieldDep.isMissing()) {
|
|
||||||
for (DependencyListener listener : listeners) {
|
|
||||||
listener.fieldAchieved(DependencyChecker.this, fieldDep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
classCache.addKeyListener(new KeyListener<String>() {
|
|
||||||
@Override public void keyAdded(String key) {
|
|
||||||
ClassDependency classDep = classCache.getKnown(key);
|
|
||||||
if (!classDep.isMissing()) {
|
|
||||||
for (DependencyListener listener : listeners) {
|
|
||||||
listener.classAchieved(DependencyChecker.this, key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DependencyCheckerInterruptor getInterruptor() {
|
public DependencyCheckerInterruptor getInterruptor() {
|
||||||
|
@ -234,26 +202,33 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
@Override
|
@Override
|
||||||
public ClassDependency linkClass(String className, CallLocation callLocation) {
|
public ClassDependency linkClass(String className, CallLocation callLocation) {
|
||||||
ClassDependency dep = classCache.map(className);
|
ClassDependency dep = classCache.map(className);
|
||||||
|
boolean added = true;
|
||||||
if (callLocation != null && callLocation.getMethod() != null) {
|
if (callLocation != null && callLocation.getMethod() != null) {
|
||||||
DefaultCallGraphNode callGraphNode = callGraph.getNode(callLocation.getMethod());
|
DefaultCallGraphNode callGraphNode = callGraph.getNode(callLocation.getMethod());
|
||||||
addClassAccess(callGraphNode, className, callLocation.getSourceLocation());
|
added = addClassAccess(callGraphNode, className, callLocation.getSourceLocation());
|
||||||
|
}
|
||||||
|
if (!dep.isMissing() && added) {
|
||||||
|
for (DependencyListener listener : listeners) {
|
||||||
|
listener.classAchieved(DependencyChecker.this, className, callLocation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return dep;
|
return dep;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addClassAccess(DefaultCallGraphNode node, String className, InstructionLocation loc) {
|
private boolean addClassAccess(DefaultCallGraphNode node, String className, InstructionLocation loc) {
|
||||||
if (!node.addClassAccess(className, loc)) {
|
if (!node.addClassAccess(className, loc)) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
ClassReader cls = classSource.get(className);
|
ClassReader cls = classSource.get(className);
|
||||||
if (cls != null) {
|
if (cls != null) {
|
||||||
if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) {
|
if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) {
|
||||||
addClassAccess(node, cls.getParent(), loc);
|
return addClassAccess(node, cls.getParent(), loc);
|
||||||
}
|
}
|
||||||
for (String iface : cls.getInterfaces()) {
|
for (String iface : cls.getInterfaces()) {
|
||||||
addClassAccess(node, iface, loc);
|
return addClassAccess(node, iface, loc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassDependency createClassDependency(String className) {
|
private ClassDependency createClassDependency(String className) {
|
||||||
|
@ -276,10 +251,19 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
callGraph.getNode(methodRef);
|
callGraph.getNode(methodRef);
|
||||||
|
boolean added = true;
|
||||||
if (callLocation != null && callLocation.getMethod() != null) {
|
if (callLocation != null && callLocation.getMethod() != null) {
|
||||||
callGraph.getNode(callLocation.getMethod()).addCallSite(methodRef, callLocation.getSourceLocation());
|
added = callGraph.getNode(callLocation.getMethod()).addCallSite(methodRef,
|
||||||
|
callLocation.getSourceLocation());
|
||||||
}
|
}
|
||||||
return methodCache.map(methodRef);
|
MethodDependency graph = methodCache.map(methodRef);
|
||||||
|
if (!graph.isMissing() && added) {
|
||||||
|
for (DependencyListener listener : listeners) {
|
||||||
|
listener.methodAchieved(this, graph, callLocation);
|
||||||
|
}
|
||||||
|
activateDependencyPlugin(graph, callLocation);
|
||||||
|
}
|
||||||
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initClass(ClassDependency cls, final CallLocation callLocation) {
|
void initClass(ClassDependency cls, final CallLocation callLocation) {
|
||||||
|
@ -404,8 +388,9 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldDependency linkField(final FieldReference fieldRef, final CallLocation location) {
|
public FieldDependency linkField(final FieldReference fieldRef, final CallLocation location) {
|
||||||
|
boolean added = true;
|
||||||
if (location != null) {
|
if (location != null) {
|
||||||
callGraph.getNode(location.getMethod()).addFieldAccess(fieldRef, location.getSourceLocation());
|
added = callGraph.getNode(location.getMethod()).addFieldAccess(fieldRef, location.getSourceLocation());
|
||||||
}
|
}
|
||||||
FieldDependency dep = fieldCache.map(fieldRef);
|
FieldDependency dep = fieldCache.map(fieldRef);
|
||||||
if (!dep.isMissing()) {
|
if (!dep.isMissing()) {
|
||||||
|
@ -415,6 +400,11 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (!dep.isMissing() && added) {
|
||||||
|
for (DependencyListener listener : listeners) {
|
||||||
|
listener.fieldAchieved(DependencyChecker.this, dep, location);
|
||||||
|
}
|
||||||
|
}
|
||||||
return dep;
|
return dep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +434,18 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
return dep;
|
return dep;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void activateDependencyPlugin(MethodDependency methodDep) {
|
private void activateDependencyPlugin(MethodDependency methodDep, CallLocation location) {
|
||||||
|
attachDependencyPlugin(methodDep);
|
||||||
|
if (methodDep.dependencyPlugin != null) {
|
||||||
|
methodDep.dependencyPlugin.methodAchieved(this, methodDep, location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void attachDependencyPlugin(MethodDependency methodDep) {
|
||||||
|
if (methodDep.dependencyPluginAttached) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
methodDep.dependencyPluginAttached = true;
|
||||||
AnnotationReader depAnnot = methodDep.getMethod().getAnnotations().get(PluggableDependency.class.getName());
|
AnnotationReader depAnnot = methodDep.getMethod().getAnnotations().get(PluggableDependency.class.getName());
|
||||||
if (depAnnot == null) {
|
if (depAnnot == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -457,13 +458,11 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
throw new RuntimeException("Dependency plugin not found: " + depClassName, e);
|
throw new RuntimeException("Dependency plugin not found: " + depClassName, e);
|
||||||
}
|
}
|
||||||
DependencyPlugin plugin;
|
|
||||||
try {
|
try {
|
||||||
plugin = (DependencyPlugin)depClass.newInstance();
|
methodDep.dependencyPlugin = (DependencyPlugin)depClass.newInstance();
|
||||||
} catch (IllegalAccessException | InstantiationException e) {
|
} catch (IllegalAccessException | InstantiationException e) {
|
||||||
throw new RuntimeException("Can't instantiate dependency plugin " + depClassName, e);
|
throw new RuntimeException("Can't instantiate dependency plugin " + depClassName, e);
|
||||||
}
|
}
|
||||||
plugin.methodAchieved(this, methodDep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.dependency;
|
package org.teavm.dependency;
|
||||||
|
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
|
@ -22,9 +24,9 @@ package org.teavm.dependency;
|
||||||
public interface DependencyListener {
|
public interface DependencyListener {
|
||||||
void started(DependencyAgent agent);
|
void started(DependencyAgent agent);
|
||||||
|
|
||||||
void classAchieved(DependencyAgent agent, String className);
|
void classAchieved(DependencyAgent agent, String className, CallLocation location);
|
||||||
|
|
||||||
void methodAchieved(DependencyAgent agent, MethodDependency method);
|
void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location);
|
||||||
|
|
||||||
void fieldAchieved(DependencyAgent agent, FieldDependency field);
|
void fieldAchieved(DependencyAgent agent, FieldDependency field, CallLocation location);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,12 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.dependency;
|
package org.teavm.dependency;
|
||||||
|
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public interface DependencyPlugin {
|
public interface DependencyPlugin {
|
||||||
void methodAchieved(DependencyAgent checker, MethodDependency method);
|
void methodAchieved(DependencyAgent checker, MethodDependency method, CallLocation location);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@ public class MethodDependency implements MethodDependencyInfo {
|
||||||
private MethodReader method;
|
private MethodReader method;
|
||||||
private MethodReference reference;
|
private MethodReference reference;
|
||||||
private boolean used;
|
private boolean used;
|
||||||
|
DependencyPlugin dependencyPlugin;
|
||||||
|
boolean dependencyPluginAttached;
|
||||||
|
|
||||||
MethodDependency(DependencyChecker dependencyChecker, DependencyNode[] variableNodes, int parameterCount,
|
MethodDependency(DependencyChecker dependencyChecker, DependencyNode[] variableNodes, int parameterCount,
|
||||||
DependencyNode resultNode, DependencyNode thrown, MethodReader method, MethodReference reference) {
|
DependencyNode resultNode, DependencyNode thrown, MethodReader method, MethodReference reference) {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.tooling;
|
package org.teavm.tooling;
|
||||||
|
|
||||||
import org.teavm.dependency.*;
|
import org.teavm.dependency.*;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.ClassReaderSource;
|
import org.teavm.model.ClassReaderSource;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
@ -35,7 +36,7 @@ class TestExceptionDependency implements DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void classAchieved(DependencyAgent agent, String className) {
|
public void classAchieved(DependencyAgent agent, String className, CallLocation location) {
|
||||||
if (isException(agent.getClassSource(), className)) {
|
if (isException(agent.getClassSource(), className)) {
|
||||||
allClasses.propagate(agent.getType(className));
|
allClasses.propagate(agent.getType(className));
|
||||||
}
|
}
|
||||||
|
@ -56,13 +57,13 @@ class TestExceptionDependency implements DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
if (method.getReference().equals(getMessageRef)) {
|
if (method.getReference().equals(getMessageRef)) {
|
||||||
allClasses.connect(method.getVariable(1));
|
allClasses.connect(method.getVariable(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fieldAchieved(DependencyAgent agent, FieldDependency field) {
|
public void fieldAchieved(DependencyAgent agent, FieldDependency field, CallLocation location) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.teavm.codegen.SourceWriter;
|
||||||
import org.teavm.dependency.*;
|
import org.teavm.dependency.*;
|
||||||
import org.teavm.javascript.Renderer;
|
import org.teavm.javascript.Renderer;
|
||||||
import org.teavm.javascript.RenderingContext;
|
import org.teavm.javascript.RenderingContext;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.vm.BuildTarget;
|
import org.teavm.vm.BuildTarget;
|
||||||
import org.teavm.vm.spi.AbstractRendererListener;
|
import org.teavm.vm.spi.AbstractRendererListener;
|
||||||
|
|
||||||
|
@ -74,14 +75,14 @@ public class EntryPointGenerator extends AbstractRendererListener implements Dep
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void classAchieved(DependencyAgent agent, String className) {
|
public void classAchieved(DependencyAgent agent, String className, CallLocation location) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fieldAchieved(DependencyAgent agent, FieldDependency field) {
|
public void fieldAchieved(DependencyAgent agent, FieldDependency field, CallLocation location) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,27 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.html4j;
|
package org.teavm.html4j;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import net.java.html.js.JavaScriptBody;
|
import net.java.html.js.JavaScriptBody;
|
||||||
import org.teavm.dependency.*;
|
import org.teavm.dependency.DependencyAgent;
|
||||||
import org.teavm.model.*;
|
import org.teavm.dependency.DependencyAgentType;
|
||||||
|
import org.teavm.dependency.DependencyConsumer;
|
||||||
|
import org.teavm.dependency.DependencyListener;
|
||||||
|
import org.teavm.dependency.DependencyNode;
|
||||||
|
import org.teavm.dependency.FieldDependency;
|
||||||
|
import org.teavm.dependency.MethodDependency;
|
||||||
|
import org.teavm.model.AnnotationReader;
|
||||||
|
import org.teavm.model.AnnotationValue;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
|
import org.teavm.model.ClassReader;
|
||||||
|
import org.teavm.model.ClassReaderSource;
|
||||||
|
import org.teavm.model.ElementModifier;
|
||||||
|
import org.teavm.model.MethodDescriptor;
|
||||||
|
import org.teavm.model.MethodReader;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -25,6 +43,7 @@ import org.teavm.model.*;
|
||||||
*/
|
*/
|
||||||
public class JavaScriptBodyDependency implements DependencyListener {
|
public class JavaScriptBodyDependency implements DependencyListener {
|
||||||
private DependencyNode allClassesNode;
|
private DependencyNode allClassesNode;
|
||||||
|
private Map<MethodReference, Set<MethodReference>> achievedMethods = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void started(DependencyAgent agent) {
|
public void started(DependencyAgent agent) {
|
||||||
|
@ -43,7 +62,7 @@ public class JavaScriptBodyDependency implements DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void classAchieved(DependencyAgent agent, String className) {
|
public void classAchieved(DependencyAgent agent, String className, CallLocation location) {
|
||||||
ClassReader cls = agent.getClassSource().get(className);
|
ClassReader cls = agent.getClassSource().get(className);
|
||||||
if (cls != null && !cls.hasModifier(ElementModifier.ABSTRACT) &&
|
if (cls != null && !cls.hasModifier(ElementModifier.ABSTRACT) &&
|
||||||
!cls.hasModifier(ElementModifier.INTERFACE)) {
|
!cls.hasModifier(ElementModifier.INTERFACE)) {
|
||||||
|
@ -52,13 +71,21 @@ public class JavaScriptBodyDependency implements DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
|
Set<MethodReference> methodsToAchieve = achievedMethods.get(method.getReference());
|
||||||
|
if (methodsToAchieve != null) {
|
||||||
|
for (MethodReference methodToAchieve : methodsToAchieve) {
|
||||||
|
agent.linkMethod(methodToAchieve, location);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
achievedMethods.put(method.getReference(), new HashSet<MethodReference>());
|
||||||
if (method.isMissing()) {
|
if (method.isMissing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AnnotationReader annot = method.getMethod().getAnnotations().get(JavaScriptBody.class.getName());
|
AnnotationReader annot = method.getMethod().getAnnotations().get(JavaScriptBody.class.getName());
|
||||||
if (annot != null) {
|
if (annot != null) {
|
||||||
includeDefaultDependencies(agent);
|
includeDefaultDependencies(agent, location);
|
||||||
AnnotationValue javacall = annot.getValue("javacall");
|
AnnotationValue javacall = annot.getValue("javacall");
|
||||||
if (method.getResult() != null) {
|
if (method.getResult() != null) {
|
||||||
allClassesNode.connect(method.getResult());
|
allClassesNode.connect(method.getResult());
|
||||||
|
@ -74,26 +101,26 @@ public class JavaScriptBodyDependency implements DependencyListener {
|
||||||
}
|
}
|
||||||
if (javacall != null && javacall.getBoolean()) {
|
if (javacall != null && javacall.getBoolean()) {
|
||||||
String body = annot.getValue("body").getString();
|
String body = annot.getValue("body").getString();
|
||||||
new GeneratorJsCallback(agent, method).parse(body);
|
new GeneratorJsCallback(agent, method, location).parse(body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void includeDefaultDependencies(DependencyAgent agent) {
|
private void includeDefaultDependencies(DependencyAgent agent, CallLocation location) {
|
||||||
agent.linkMethod(JavaScriptConvGenerator.fromJsMethod, null).use();
|
agent.linkMethod(JavaScriptConvGenerator.fromJsMethod, location).use();
|
||||||
agent.linkMethod(JavaScriptConvGenerator.toJsMethod, null).use();
|
agent.linkMethod(JavaScriptConvGenerator.toJsMethod, location).use();
|
||||||
agent.linkMethod(JavaScriptConvGenerator.intValueMethod, null).use();
|
agent.linkMethod(JavaScriptConvGenerator.intValueMethod, location).use();
|
||||||
agent.linkMethod(JavaScriptConvGenerator.valueOfIntMethod, null).use();
|
agent.linkMethod(JavaScriptConvGenerator.valueOfIntMethod, location).use();
|
||||||
agent.linkMethod(JavaScriptConvGenerator.booleanValueMethod, null).use();
|
agent.linkMethod(JavaScriptConvGenerator.booleanValueMethod, location).use();
|
||||||
agent.linkMethod(JavaScriptConvGenerator.valueOfBooleanMethod, null).use();
|
agent.linkMethod(JavaScriptConvGenerator.valueOfBooleanMethod, location).use();
|
||||||
agent.linkMethod(JavaScriptConvGenerator.doubleValueMethod, null).use();
|
agent.linkMethod(JavaScriptConvGenerator.doubleValueMethod, location).use();
|
||||||
agent.linkMethod(JavaScriptConvGenerator.valueOfDoubleMethod, null).use();
|
agent.linkMethod(JavaScriptConvGenerator.valueOfDoubleMethod, location).use();
|
||||||
agent.linkMethod(JavaScriptConvGenerator.charValueMethod, null).use();
|
agent.linkMethod(JavaScriptConvGenerator.charValueMethod, location).use();
|
||||||
agent.linkMethod(JavaScriptConvGenerator.valueOfCharMethod, null).use();
|
agent.linkMethod(JavaScriptConvGenerator.valueOfCharMethod, location).use();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fieldAchieved(DependencyAgent agent, FieldDependency fieldDep) {
|
public void fieldAchieved(DependencyAgent agent, FieldDependency fieldDep, CallLocation location) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MethodReader findMethod(ClassReaderSource classSource, String clsName, MethodDescriptor desc) {
|
private static MethodReader findMethod(ClassReaderSource classSource, String clsName, MethodDescriptor desc) {
|
||||||
|
@ -126,15 +153,18 @@ public class JavaScriptBodyDependency implements DependencyListener {
|
||||||
private class GeneratorJsCallback extends JsCallback {
|
private class GeneratorJsCallback extends JsCallback {
|
||||||
private DependencyAgent agent;
|
private DependencyAgent agent;
|
||||||
private MethodDependency caller;
|
private MethodDependency caller;
|
||||||
public GeneratorJsCallback(DependencyAgent agent, MethodDependency caller) {
|
private CallLocation location;
|
||||||
|
public GeneratorJsCallback(DependencyAgent agent, MethodDependency caller, CallLocation location) {
|
||||||
this.agent = agent;
|
this.agent = agent;
|
||||||
this.caller = caller;
|
this.caller = caller;
|
||||||
|
this.location = location;
|
||||||
}
|
}
|
||||||
@Override protected CharSequence callMethod(String ident, String fqn, String method, String params) {
|
@Override protected CharSequence callMethod(String ident, String fqn, String method, String params) {
|
||||||
MethodDescriptor desc = MethodDescriptor.parse(method + params + "V");
|
MethodDescriptor desc = MethodDescriptor.parse(method + params + "V");
|
||||||
MethodReader reader = findMethod(agent.getClassSource(), fqn, desc);
|
MethodReader reader = findMethod(agent.getClassSource(), fqn, desc);
|
||||||
MethodReference ref = reader != null ? reader.getReference() : new MethodReference(fqn, desc);
|
MethodReference ref = reader != null ? reader.getReference() : new MethodReference(fqn, desc);
|
||||||
MethodDependency methodDep = agent.linkMethod(ref, null);
|
MethodDependency methodDep = agent.linkMethod(ref, location);
|
||||||
|
achievedMethods.get(caller.getReference()).add(ref);
|
||||||
if (!methodDep.isMissing()) {
|
if (!methodDep.isMissing()) {
|
||||||
if (reader.hasModifier(ElementModifier.STATIC) || reader.hasModifier(ElementModifier.FINAL)) {
|
if (reader.hasModifier(ElementModifier.STATIC) || reader.hasModifier(ElementModifier.FINAL)) {
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
|
@ -154,8 +184,7 @@ public class JavaScriptBodyDependency implements DependencyListener {
|
||||||
private MethodReader superMethod;
|
private MethodReader superMethod;
|
||||||
private ClassReader superClass;
|
private ClassReader superClass;
|
||||||
private MethodDependency caller;
|
private MethodDependency caller;
|
||||||
public VirtualCallbackConsumer(DependencyAgent agent, MethodReader superMethod,
|
public VirtualCallbackConsumer(DependencyAgent agent, MethodReader superMethod, MethodDependency caller) {
|
||||||
MethodDependency caller) {
|
|
||||||
this.agent = agent;
|
this.agent = agent;
|
||||||
this.superMethod = superMethod;
|
this.superMethod = superMethod;
|
||||||
this.caller = caller;
|
this.caller = caller;
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.teavm.javascript.ast.Expr;
|
||||||
import org.teavm.javascript.ast.InvocationExpr;
|
import org.teavm.javascript.ast.InvocationExpr;
|
||||||
import org.teavm.javascript.ni.Injector;
|
import org.teavm.javascript.ni.Injector;
|
||||||
import org.teavm.javascript.ni.InjectorContext;
|
import org.teavm.javascript.ni.InjectorContext;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.MethodReader;
|
import org.teavm.model.MethodReader;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
@ -112,7 +113,8 @@ public class JSNativeGenerator implements Injector, DependencyPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(final DependencyAgent agent, final MethodDependency method) {
|
public void methodAchieved(final DependencyAgent agent, final MethodDependency method,
|
||||||
|
final CallLocation location) {
|
||||||
switch (method.getReference().getName()) {
|
switch (method.getReference().getName()) {
|
||||||
case "invoke":
|
case "invoke":
|
||||||
case "instantiate":
|
case "instantiate":
|
||||||
|
@ -120,7 +122,7 @@ public class JSNativeGenerator implements Injector, DependencyPlugin {
|
||||||
for (int i = 0; i < method.getReference().parameterCount(); ++i) {
|
for (int i = 0; i < method.getReference().parameterCount(); ++i) {
|
||||||
method.getVariable(i).addConsumer(new DependencyConsumer() {
|
method.getVariable(i).addConsumer(new DependencyConsumer() {
|
||||||
@Override public void consume(DependencyAgentType type) {
|
@Override public void consume(DependencyAgentType type) {
|
||||||
achieveFunctorMethods(agent, type.getName(), method);
|
achieveFunctorMethods(agent, type.getName(), method, location);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -131,14 +133,15 @@ public class JSNativeGenerator implements Injector, DependencyPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void achieveFunctorMethods(DependencyAgent agent, String type, MethodDependency caller) {
|
private void achieveFunctorMethods(DependencyAgent agent, String type, MethodDependency caller,
|
||||||
|
CallLocation location) {
|
||||||
if (caller.isMissing()) {
|
if (caller.isMissing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ClassReader cls = agent.getClassSource().get(type);
|
ClassReader cls = agent.getClassSource().get(type);
|
||||||
if (cls != null) {
|
if (cls != null) {
|
||||||
for (MethodReader method : cls.getMethods()) {
|
for (MethodReader method : cls.getMethods()) {
|
||||||
agent.linkMethod(method.getReference(), null).use();
|
agent.linkMethod(method.getReference(), location).use();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.teavm.dependency.DependencyAgent;
|
||||||
import org.teavm.dependency.DependencyListener;
|
import org.teavm.dependency.DependencyListener;
|
||||||
import org.teavm.dependency.FieldDependency;
|
import org.teavm.dependency.FieldDependency;
|
||||||
import org.teavm.dependency.MethodDependency;
|
import org.teavm.dependency.MethodDependency;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -30,11 +31,11 @@ class ResourceAccessorDependencyListener implements DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void classAchieved(DependencyAgent agent, String className) {
|
public void classAchieved(DependencyAgent agent, String className, CallLocation location) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
switch (method.getReference().getName()) {
|
switch (method.getReference().getName()) {
|
||||||
case "castToString":
|
case "castToString":
|
||||||
method.getResult().propagate(agent.getType("java.lang.String"));
|
method.getResult().propagate(agent.getType("java.lang.String"));
|
||||||
|
@ -43,6 +44,6 @@ class ResourceAccessorDependencyListener implements DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fieldAchieved(DependencyAgent agent, FieldDependency field) {
|
public void fieldAchieved(DependencyAgent agent, FieldDependency field, CallLocation location) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user