Removes unecessary dependency error when building JavaScriptBody support

This commit is contained in:
konsoletyper 2014-02-19 11:40:02 +04:00
parent 2c08f75b0a
commit 8988d4fc64
3 changed files with 49 additions and 5 deletions

View File

@ -141,6 +141,7 @@ public class DependencyChecker implements DependencyInfo {
} }
public void schedulePropagation(final DependencyConsumer consumer, final String type) { public void schedulePropagation(final DependencyConsumer consumer, final String type) {
System.out.print("");
executor.executeFast(new Runnable() { executor.executeFast(new Runnable() {
@Override public void run() { @Override public void run() {
consumer.consume(type); consumer.consume(type);

View File

@ -66,6 +66,7 @@ class DependencyGraphBuilder {
private static class VirtualCallPropagationListener implements DependencyConsumer { private static class VirtualCallPropagationListener implements DependencyConsumer {
private final DependencyNode node; private final DependencyNode node;
private final ClassReader filterClass;
private final MethodDescriptor methodDesc; private final MethodDescriptor methodDesc;
private final DependencyChecker checker; private final DependencyChecker checker;
private final DependencyNode[] parameters; private final DependencyNode[] parameters;
@ -73,10 +74,11 @@ class DependencyGraphBuilder {
private final DependencyStack stack; private final DependencyStack stack;
private final ConcurrentMap<MethodReference, MethodReference> knownMethods = new ConcurrentHashMap<>(); private final ConcurrentMap<MethodReference, MethodReference> knownMethods = new ConcurrentHashMap<>();
public VirtualCallPropagationListener(DependencyNode node, MethodDescriptor methodDesc, public VirtualCallPropagationListener(DependencyNode node, ClassReader filterClass,
DependencyChecker checker, DependencyNode[] parameters, DependencyNode result, MethodDescriptor methodDesc, DependencyChecker checker, DependencyNode[] parameters,
DependencyStack stack) { DependencyNode result, DependencyStack stack) {
this.node = node; this.node = node;
this.filterClass = filterClass;
this.methodDesc = methodDesc; this.methodDesc = methodDesc;
this.checker = checker; this.checker = checker;
this.parameters = parameters; this.parameters = parameters;
@ -93,6 +95,9 @@ class DependencyGraphBuilder {
if (className.startsWith("[")) { if (className.startsWith("[")) {
className = "java.lang.Object"; className = "java.lang.Object";
} }
if (!isAssignableFrom(checker.getClassSource(), filterClass, className)) {
return;
}
MethodReference methodRef = new MethodReference(className, methodDesc); MethodReference methodRef = new MethodReference(className, methodDesc);
MethodDependency methodDep = checker.linkMethod(methodRef, stack); MethodDependency methodDep = checker.linkMethod(methodRef, stack);
if (!methodDep.isMissing() && knownMethods.putIfAbsent(methodRef, methodRef) == null) { if (!methodDep.isMissing() && knownMethods.putIfAbsent(methodRef, methodRef) == null) {
@ -120,6 +125,26 @@ class DependencyGraphBuilder {
} }
} }
private static boolean isAssignableFrom(ClassReaderSource classSource, ClassReader supertype,
String subtypeName) {
if (supertype.getName().equals(subtypeName)) {
return true;
}
ClassReader subtype = classSource.get(subtypeName);
if (subtype == null) {
return false;
}
if (subtype.getParent() != null && isAssignableFrom(classSource, supertype, subtype.getParent())) {
return true;
}
for (String iface : subtype.getInterfaces()) {
if (isAssignableFrom(classSource, supertype, iface)) {
return true;
}
}
return false;
}
private static class TypePropagationRunner implements Runnable { private static class TypePropagationRunner implements Runnable {
private DependencyNode node; private DependencyNode node;
private String type; private String type;
@ -197,6 +222,18 @@ class DependencyGraphBuilder {
public void cast(VariableReader receiver, VariableReader value, ValueType targetType) { public void cast(VariableReader receiver, VariableReader value, ValueType targetType) {
DependencyNode valueNode = nodes[value.getIndex()]; DependencyNode valueNode = nodes[value.getIndex()];
DependencyNode receiverNode = nodes[receiver.getIndex()]; DependencyNode receiverNode = nodes[receiver.getIndex()];
if (targetType instanceof ValueType.Object) {
String targetClsName = ((ValueType.Object)targetType).getClassName();
final ClassReader targetClass = dependencyChecker.getClassSource().get(targetClsName);
if (targetClass != null) {
valueNode.connect(receiverNode, new DependencyTypeFilter() {
@Override public boolean match(String type) {
return isAssignableFrom(dependencyChecker.getClassSource(), targetClass, type);
}
});
return;
}
}
valueNode.connect(receiverNode); valueNode.connect(receiverNode);
} }
@ -351,7 +388,8 @@ class DependencyGraphBuilder {
private void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method, private void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method,
List<? extends VariableReader> arguments) { List<? extends VariableReader> arguments) {
if (dependencyChecker.linkMethod(method, callerStack).isMissing()) { MethodDependency methodDep = dependencyChecker.linkMethod(method, callerStack);
if (methodDep.isMissing()) {
return; return;
} }
DependencyNode[] actualArgs = new DependencyNode[arguments.size() + 1]; DependencyNode[] actualArgs = new DependencyNode[arguments.size() + 1];
@ -360,6 +398,7 @@ class DependencyGraphBuilder {
} }
actualArgs[0] = nodes[instance.getIndex()]; actualArgs[0] = nodes[instance.getIndex()];
DependencyConsumer listener = new VirtualCallPropagationListener(nodes[instance.getIndex()], DependencyConsumer listener = new VirtualCallPropagationListener(nodes[instance.getIndex()],
dependencyChecker.getClassSource().get(methodDep.getMethod().getOwnerName()),
method.getDescriptor(), dependencyChecker, actualArgs, method.getDescriptor(), dependencyChecker, actualArgs,
receiver != null ? nodes[receiver.getIndex()] : null, callerStack); receiver != null ? nodes[receiver.getIndex()] : null, callerStack);
nodes[instance.getIndex()].addConsumer(listener); nodes[instance.getIndex()].addConsumer(listener);

View File

@ -44,7 +44,11 @@ public class JavaScriptBodyDependency implements DependencyListener {
@Override @Override
public void classAchieved(DependencyChecker dependencyChecker, String className) { public void classAchieved(DependencyChecker dependencyChecker, String className) {
allClassesNode.propagate(className); ClassReader cls = dependencyChecker.getClassSource().get(className);
if (cls != null && !cls.hasModifier(ElementModifier.ABSTRACT) &&
!cls.hasModifier(ElementModifier.INTERFACE)) {
allClassesNode.propagate(className);
}
} }
@Override @Override