From 8988d4fc64fad2e75a93616ba2c2605d6293d7ab Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Wed, 19 Feb 2014 11:40:02 +0400 Subject: [PATCH] Removes unecessary dependency error when building JavaScriptBody support --- .../teavm/dependency/DependencyChecker.java | 1 + .../dependency/DependencyGraphBuilder.java | 47 +++++++++++++++++-- .../html4j/JavaScriptBodyDependency.java | 6 ++- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java index 56fff81a2..58078199e 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -141,6 +141,7 @@ public class DependencyChecker implements DependencyInfo { } public void schedulePropagation(final DependencyConsumer consumer, final String type) { + System.out.print(""); executor.executeFast(new Runnable() { @Override public void run() { consumer.consume(type); diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java index 47229da51..d05dc6ebd 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -66,6 +66,7 @@ class DependencyGraphBuilder { private static class VirtualCallPropagationListener implements DependencyConsumer { private final DependencyNode node; + private final ClassReader filterClass; private final MethodDescriptor methodDesc; private final DependencyChecker checker; private final DependencyNode[] parameters; @@ -73,10 +74,11 @@ class DependencyGraphBuilder { private final DependencyStack stack; private final ConcurrentMap knownMethods = new ConcurrentHashMap<>(); - public VirtualCallPropagationListener(DependencyNode node, MethodDescriptor methodDesc, - DependencyChecker checker, DependencyNode[] parameters, DependencyNode result, - DependencyStack stack) { + public VirtualCallPropagationListener(DependencyNode node, ClassReader filterClass, + MethodDescriptor methodDesc, DependencyChecker checker, DependencyNode[] parameters, + DependencyNode result, DependencyStack stack) { this.node = node; + this.filterClass = filterClass; this.methodDesc = methodDesc; this.checker = checker; this.parameters = parameters; @@ -93,6 +95,9 @@ class DependencyGraphBuilder { if (className.startsWith("[")) { className = "java.lang.Object"; } + if (!isAssignableFrom(checker.getClassSource(), filterClass, className)) { + return; + } MethodReference methodRef = new MethodReference(className, methodDesc); MethodDependency methodDep = checker.linkMethod(methodRef, stack); 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 DependencyNode node; private String type; @@ -197,6 +222,18 @@ class DependencyGraphBuilder { public void cast(VariableReader receiver, VariableReader value, ValueType targetType) { DependencyNode valueNode = nodes[value.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); } @@ -351,7 +388,8 @@ class DependencyGraphBuilder { private void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method, List arguments) { - if (dependencyChecker.linkMethod(method, callerStack).isMissing()) { + MethodDependency methodDep = dependencyChecker.linkMethod(method, callerStack); + if (methodDep.isMissing()) { return; } DependencyNode[] actualArgs = new DependencyNode[arguments.size() + 1]; @@ -360,6 +398,7 @@ class DependencyGraphBuilder { } actualArgs[0] = nodes[instance.getIndex()]; DependencyConsumer listener = new VirtualCallPropagationListener(nodes[instance.getIndex()], + dependencyChecker.getClassSource().get(methodDep.getMethod().getOwnerName()), method.getDescriptor(), dependencyChecker, actualArgs, receiver != null ? nodes[receiver.getIndex()] : null, callerStack); nodes[instance.getIndex()].addConsumer(listener); diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java index 02fa7c6a1..27b02be6d 100644 --- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java +++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java @@ -44,7 +44,11 @@ public class JavaScriptBodyDependency implements DependencyListener { @Override 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