diff --git a/teavm-core/src/main/java/org/teavm/callgraph/CallGraph.java b/teavm-core/src/main/java/org/teavm/callgraph/CallGraph.java new file mode 100644 index 000000000..213ce96d7 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/callgraph/CallGraph.java @@ -0,0 +1,41 @@ +/* + * Copyright 2014 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.callgraph; + +import java.util.Collection; +import org.teavm.model.FieldReference; +import org.teavm.model.MethodReference; + +/** + *

Root object for traversing through call graph. Graph does not represent polymorphic calls. + * Instead, it generated multiple call sites for one location.

+ * + * @author Alexey Andreev + */ +public interface CallGraph { + /** + *

Get node corresponding to the specific method.

+ * + * @param method a method to lookup node for. + * @return the node that corresponds to the specified method or null, if this method is never + * called. + */ + CallGraphNode getNode(MethodReference method); + + Collection getFieldAccess(FieldReference reference); + + Collection getClassAccess(String className); +} diff --git a/teavm-core/src/main/java/org/teavm/callgraph/CallGraphNode.java b/teavm-core/src/main/java/org/teavm/callgraph/CallGraphNode.java new file mode 100644 index 000000000..b027e3bed --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/callgraph/CallGraphNode.java @@ -0,0 +1,49 @@ +/* + * Copyright 2014 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.callgraph; + +import java.util.Collection; +import org.teavm.model.MethodReference; + +/** + * Represents a method with information about what methods does it call and what method do call the method. + * @author Alexey Andreev + */ +public interface CallGraphNode { + /* + * Returns reference to entire call graph. + */ + CallGraph getGraph(); + + /** + * Returns the method that this node represents. + */ + MethodReference getMethod(); + + /** + * Returns immutable collection of all call sites that are in the method. + */ + Collection getCallSites(); + + /** + * Returns immutable collection of all call sites that call this method. + */ + Collection getCallerCallSites(); + + Collection getFieldAccessSites(); + + Collection getClassAccessSites(); +} diff --git a/teavm-core/src/main/java/org/teavm/callgraph/CallSite.java b/teavm-core/src/main/java/org/teavm/callgraph/CallSite.java new file mode 100644 index 000000000..3aa170b13 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/callgraph/CallSite.java @@ -0,0 +1,41 @@ +/* + * Copyright 2014 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.callgraph; + +import org.teavm.model.InstructionLocation; + +/** + *

Call site that represents exact place in the code that calls a method.

. + * @author Alexey Andreev + */ +public interface CallSite { + /** + *

Gets location of the call site

. + * + * @return location of the call site or null if no debug information found for this call site. + */ + InstructionLocation getLocation(); + + /** + *

Gets a method that this call site invokes.

+ */ + CallGraphNode getCallee(); + + /** + *

Gets a method that contains this call site.

+ */ + CallGraphNode getCaller(); +} diff --git a/teavm-core/src/main/java/org/teavm/callgraph/ClassAccessSite.java b/teavm-core/src/main/java/org/teavm/callgraph/ClassAccessSite.java new file mode 100644 index 000000000..51bbb2528 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/callgraph/ClassAccessSite.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 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.callgraph; + +import org.teavm.model.InstructionLocation; + +/** + * + * @author Alexey Andreev + */ +public interface ClassAccessSite { + InstructionLocation getLocation(); + + CallGraphNode getCallee(); + + String getClassName(); +} diff --git a/teavm-core/src/main/java/org/teavm/callgraph/DefaultCallGraph.java b/teavm-core/src/main/java/org/teavm/callgraph/DefaultCallGraph.java new file mode 100644 index 000000000..67249c67d --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/callgraph/DefaultCallGraph.java @@ -0,0 +1,72 @@ +/* + * Copyright 2014 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.callgraph; + +import java.util.*; +import org.teavm.model.FieldReference; +import org.teavm.model.MethodReference; + +/** + * + * @author Alexey Andreev + */ +public class DefaultCallGraph implements CallGraph { + private Map nodes = new HashMap<>(); + private Map> fieldAccessSites = new HashMap<>(); + private Map> classAccessSites = new HashMap<>(); + + @Override + public DefaultCallGraphNode getNode(MethodReference method) { + DefaultCallGraphNode node = nodes.get(method); + if (node == null) { + node = new DefaultCallGraphNode(this); + nodes.put(method, node); + } + return nodes.get(method); + } + + @Override + public Collection getFieldAccess(FieldReference reference) { + Set resultSet = fieldAccessSites.get(reference); + return resultSet != null ? Collections.unmodifiableSet(resultSet) : + Collections.emptySet(); + } + + void addFieldAccess(DefaultFieldAccessSite accessSite) { + Set sites = fieldAccessSites.get(accessSite.getField()); + if (sites == null) { + sites = new HashSet<>(); + fieldAccessSites.put(accessSite.getField(), sites); + } + sites.add(accessSite); + } + + @Override + public Collection getClassAccess(String className) { + Set resultSet = classAccessSites.get(className); + return resultSet != null ? Collections.unmodifiableSet(resultSet) : + Collections.emptySet(); + } + + void addClassAccess(DefaultClassAccessSite accessSite) { + Set sites = classAccessSites.get(accessSite.getClassName()); + if (sites == null) { + sites = new HashSet<>(); + classAccessSites.put(accessSite.getClassName(), sites); + } + sites.add(accessSite); + } +} diff --git a/teavm-core/src/main/java/org/teavm/callgraph/DefaultCallGraphNode.java b/teavm-core/src/main/java/org/teavm/callgraph/DefaultCallGraphNode.java new file mode 100644 index 000000000..2b54ef7ee --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/callgraph/DefaultCallGraphNode.java @@ -0,0 +1,113 @@ +/* + * Copyright 2014 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.callgraph; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import org.teavm.model.FieldReference; +import org.teavm.model.InstructionLocation; +import org.teavm.model.MethodReference; + +/** + * + * @author Alexey Andreev + */ +public class DefaultCallGraphNode implements CallGraphNode { + private DefaultCallGraph graph; + private MethodReference method; + private Set callSites; + private transient Set safeCallSites; + private List callerCallSites; + private transient List safeCallersCallSites; + private Set fieldAccessSites; + private transient Set safeFieldAccessSites; + private Set classAccessSites; + private transient Set safeClassAccessSites; + + DefaultCallGraphNode(DefaultCallGraph graph) { + this.graph = graph; + } + + @Override + public DefaultCallGraph getGraph() { + return graph; + } + + @Override + public MethodReference getMethod() { + return method; + } + + @Override + public Collection getCallSites() { + if (safeCallSites == null) { + safeCallSites = Collections.unmodifiableSet(callSites); + } + return safeCallSites; + } + + @Override + public Collection getCallerCallSites() { + if (safeCallersCallSites == null) { + safeCallersCallSites = Collections.unmodifiableList(callerCallSites); + } + return safeCallersCallSites; + } + + public void addCallSite(MethodReference method, InstructionLocation location) { + DefaultCallGraphNode callee = graph.getNode(method); + DefaultCallSite callSite = new DefaultCallSite(location, callee, this); + if (callSites.add(callSite)) { + callee.callerCallSites.add(callSite); + } + } + + public void addCallSite(MethodReference method) { + addCallSite(method, null); + } + + @Override + public Collection getFieldAccessSites() { + if (safeFieldAccessSites == null) { + safeFieldAccessSites = Collections.unmodifiableSet(fieldAccessSites); + } + return safeFieldAccessSites; + } + + public void addFieldAccess(FieldReference field, InstructionLocation location) { + DefaultFieldAccessSite site = new DefaultFieldAccessSite(location, this, field); + if (fieldAccessSites.add(site)) { + graph.addFieldAccess(site); + } + } + + @Override + public Collection getClassAccessSites() { + if (safeClassAccessSites == null) { + safeClassAccessSites = Collections.unmodifiableSet(classAccessSites); + } + return safeClassAccessSites; + } + + public void addClassAccess(String className, InstructionLocation location) { + DefaultClassAccessSite site = new DefaultClassAccessSite(location, this, className); + if (classAccessSites.add(site)) { + graph.addClassAccess(site); + } + } +} diff --git a/teavm-core/src/main/java/org/teavm/callgraph/DefaultCallSite.java b/teavm-core/src/main/java/org/teavm/callgraph/DefaultCallSite.java new file mode 100644 index 000000000..badb1d35f --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/callgraph/DefaultCallSite.java @@ -0,0 +1,68 @@ +/* + * Copyright 2014 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.callgraph; + +import java.util.Objects; +import org.teavm.model.InstructionLocation; + +/** + * + * @author Alexey Andreev + */ +public class DefaultCallSite implements CallSite { + private InstructionLocation location; + private DefaultCallGraphNode callee; + private DefaultCallGraphNode caller; + + DefaultCallSite(InstructionLocation location, DefaultCallGraphNode callee, DefaultCallGraphNode caller) { + this.location = location; + this.callee = callee; + this.caller = caller; + } + + @Override + public InstructionLocation getLocation() { + return location; + } + + @Override + public DefaultCallGraphNode getCallee() { + return callee; + } + + @Override + public DefaultCallGraphNode getCaller() { + return caller; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof DefaultCallSite)) { + return false; + } + DefaultCallSite other = (DefaultCallSite)obj; + return Objects.equals(callee.getMethod(), other.callee.getMethod()) && + Objects.equals(location, other.location); + } + + @Override + public int hashCode() { + return Objects.hash(callee.getMethod(), location); + } +} diff --git a/teavm-core/src/main/java/org/teavm/callgraph/DefaultClassAccessSite.java b/teavm-core/src/main/java/org/teavm/callgraph/DefaultClassAccessSite.java new file mode 100644 index 000000000..66ddc1bb4 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/callgraph/DefaultClassAccessSite.java @@ -0,0 +1,49 @@ +/* + * Copyright 2014 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.callgraph; + +import org.teavm.model.InstructionLocation; + +/** + * + * @author Alexey Andreev + */ +public class DefaultClassAccessSite implements ClassAccessSite { + private InstructionLocation location; + private CallGraphNode callee; + private String className; + + DefaultClassAccessSite(InstructionLocation location, CallGraphNode callee, String className) { + this.location = location; + this.callee = callee; + this.className = className; + } + + @Override + public InstructionLocation getLocation() { + return location; + } + + @Override + public CallGraphNode getCallee() { + return callee; + } + + @Override + public String getClassName() { + return className; + } +} diff --git a/teavm-core/src/main/java/org/teavm/callgraph/DefaultFieldAccessSite.java b/teavm-core/src/main/java/org/teavm/callgraph/DefaultFieldAccessSite.java new file mode 100644 index 000000000..52594377d --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/callgraph/DefaultFieldAccessSite.java @@ -0,0 +1,69 @@ +/* + * Copyright 2014 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.callgraph; + +import java.util.Objects; +import org.teavm.model.FieldReference; +import org.teavm.model.InstructionLocation; + +/** + * + * @author Alexey Andreev + */ +public class DefaultFieldAccessSite implements FieldAccessSite { + private InstructionLocation location; + private CallGraphNode callee; + private FieldReference field; + + DefaultFieldAccessSite(InstructionLocation location, CallGraphNode callee, FieldReference field) { + this.location = location; + this.callee = callee; + this.field = field; + } + + @Override + public InstructionLocation getLocation() { + return null; + } + + @Override + public CallGraphNode getCallee() { + return null; + } + + @Override + public FieldReference getField() { + return null; + } + + @Override + public int hashCode() { + return Objects.hash(location, callee, field); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof DefaultFieldAccessSite)) { + return false; + } + DefaultFieldAccessSite other = (DefaultFieldAccessSite)obj; + return Objects.equals(location, other.location) && Objects.equals(callee, other.callee) && + Objects.equals(field, other.field); + } +} diff --git a/teavm-core/src/main/java/org/teavm/callgraph/FieldAccessSite.java b/teavm-core/src/main/java/org/teavm/callgraph/FieldAccessSite.java new file mode 100644 index 000000000..938a8721f --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/callgraph/FieldAccessSite.java @@ -0,0 +1,31 @@ +/* + * Copyright 2014 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.callgraph; + +import org.teavm.model.FieldReference; +import org.teavm.model.InstructionLocation; + +/** + * + * @author Alexey Andreev + */ +public interface FieldAccessSite { + InstructionLocation getLocation(); + + CallGraphNode getCallee(); + + FieldReference getField(); +} diff --git a/teavm-core/src/main/java/org/teavm/dependency/ClassDependency.java b/teavm-core/src/main/java/org/teavm/dependency/ClassDependency.java index 17b85d577..c3ff7e859 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/ClassDependency.java +++ b/teavm-core/src/main/java/org/teavm/dependency/ClassDependency.java @@ -16,6 +16,8 @@ package org.teavm.dependency; import org.teavm.model.ClassReader; +import org.teavm.model.InstructionLocation; +import org.teavm.model.MethodReference; /** * @@ -24,13 +26,11 @@ import org.teavm.model.ClassReader; public class ClassDependency implements ClassDependencyInfo { private DependencyChecker checker; private String className; - private DependencyStack stack; private ClassReader classReader; - ClassDependency(DependencyChecker checker, String className, DependencyStack stack, ClassReader classReader) { + ClassDependency(DependencyChecker checker, String className, ClassReader classReader) { this.checker = checker; this.className = className; - this.stack = stack; this.classReader = classReader; } @@ -48,14 +48,9 @@ public class ClassDependency implements ClassDependencyInfo { return classReader; } - @Override - public DependencyStack getStack() { - return stack; - } - - public void initClass(DependencyStack stack) { + public void initClass(MethodReference caller, InstructionLocation location) { if (!isMissing()) { - checker.initClass(this, stack); + checker.initClass(this, caller, location); } } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/ClassDependencyInfo.java b/teavm-core/src/main/java/org/teavm/dependency/ClassDependencyInfo.java index 46ecc9c72..84c695720 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/ClassDependencyInfo.java +++ b/teavm-core/src/main/java/org/teavm/dependency/ClassDependencyInfo.java @@ -23,6 +23,4 @@ public interface ClassDependencyInfo { String getClassName(); boolean isMissing(); - - DependencyStack getStack(); } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java index 07cb02d55..4862610b8 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java @@ -16,10 +16,8 @@ package org.teavm.dependency; import org.teavm.common.ServiceRepository; -import org.teavm.model.ClassHolder; -import org.teavm.model.Diagnostics; -import org.teavm.model.FieldReference; -import org.teavm.model.MethodReference; +import org.teavm.diagnostics.Diagnostics; +import org.teavm.model.*; /** * @@ -34,11 +32,11 @@ public interface DependencyAgent extends DependencyInfo, ServiceRepository { void submitClass(ClassHolder cls); - MethodDependency linkMethod(MethodReference methodRef, DependencyStack stack); + MethodDependency linkMethod(MethodReference methodRef, MethodReference caller, InstructionLocation location); - ClassDependency linkClass(String className, final DependencyStack stack); + ClassDependency linkClass(String className, MethodReference caller, InstructionLocation location); - FieldDependency linkField(FieldReference fieldRef, DependencyStack stack); + FieldDependency linkField(FieldReference fieldRef, MethodReference caller, InstructionLocation location); Diagnostics getDiagnostics(); } 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 d2bbfbd50..1e43dad3a 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -17,8 +17,11 @@ package org.teavm.dependency; import java.io.IOException; import java.util.*; +import org.teavm.callgraph.CallGraph; +import org.teavm.callgraph.DefaultCallGraph; import org.teavm.common.*; import org.teavm.common.CachedMapper.KeyListener; +import org.teavm.diagnostics.Diagnostics; import org.teavm.model.*; import org.teavm.model.util.ModelUtils; @@ -33,9 +36,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { private ClassLoader classLoader; private Mapper methodReaderCache; private Mapper fieldReaderCache; - private Map stacks = new HashMap<>(); - private Map fieldStacks = new HashMap<>(); - private Map classStacks = new HashMap<>(); private CachedMapper methodCache; private CachedMapper fieldCache; private CachedMapper classCache; @@ -51,6 +51,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { private DependencyCheckerInterruptor interruptor; private boolean interrupted; private Diagnostics diagnostics; + private DefaultCallGraph callGraph = new DefaultCallGraph(); public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, Diagnostics diagnostics) { @@ -72,26 +73,24 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { @Override public MethodDependency map(MethodReference preimage) { MethodReader method = methodReaderCache.map(preimage); if (method != null && !method.getReference().equals(preimage)) { - stacks.put(method.getReference(), stacks.get(preimage)); return methodCache.map(method.getReference()); } - return createMethodDep(preimage, method, stacks.get(preimage)); + return createMethodDep(preimage, method); } }); fieldCache = new CachedMapper<>(new Mapper() { @Override public FieldDependency map(FieldReference preimage) { FieldReader field = fieldReaderCache.map(preimage); if (field != null && !field.getReference().equals(preimage)) { - fieldStacks.put(field.getReference(), fieldStacks.get(preimage)); return fieldCache.map(field.getReference()); } - return createFieldNode(preimage, field, fieldStacks.get(preimage)); + return createFieldNode(preimage, field); } }); classCache = new CachedMapper<>(new Mapper() { @Override public ClassDependency map(String preimage) { - return createClassDependency(preimage, classStacks.get(preimage)); + return createClassDependency(preimage); } }); methodCache.addKeyListener(new KeyListener() { @@ -167,7 +166,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { @Override public String generateClassName() { - return "$$tmp$$.TempClass" + classNameSuffix++; + return "$$teavm_generated_class$$" + classNameSuffix++; } @Override @@ -189,7 +188,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { if (parameters.length + 1 != argumentTypes.length) { throw new IllegalArgumentException("argumentTypes length does not match the number of method's arguments"); } - MethodDependency method = linkMethod(methodRef, DependencyStack.ROOT); + MethodDependency method = linkMethod(methodRef, null, null); method.use(); DependencyNode[] varNodes = method.getVariables(); varNodes[0].propagate(getType(methodRef.getClassName())); @@ -218,7 +217,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { @Override public ClassDependency linkClass(String className, DependencyStack stack) { - classStacks.put(className, stack); return classCache.map(className); } @@ -239,21 +237,26 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { } @Override - public MethodDependency linkMethod(MethodReference methodRef, DependencyStack stack) { + public MethodDependency linkMethod(MethodReference methodRef, MethodReference caller, + InstructionLocation location) { if (methodRef == null) { throw new IllegalArgumentException(); } - stacks.put(methodRef, stack); + callGraph.addNode(methodRef); + if (caller != null) { + callGraph.addNode(caller); + callGraph.getNode(caller).addCallSite(methodRef, location); + } return methodCache.map(methodRef); } - void initClass(ClassDependency cls, final DependencyStack stack) { + void initClass(ClassDependency cls, final MethodReference caller, final InstructionLocation location) { ClassReader reader = cls.getClassReader(); final MethodReader method = reader.getMethod(new MethodDescriptor("", void.class)); if (method != null) { tasks.add(new Runnable() { @Override public void run() { - linkMethod(method.getReference(), stack).use(); + linkMethod(method.getReference(), caller, location).use(); } }); } @@ -373,7 +376,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { } @Override - public FieldDependency linkField(FieldReference fieldRef, DependencyStack stack) { + public FieldDependency linkField(FieldReference fieldRef, MethodReference caller, InstructionLocation location) { fieldStacks.put(fieldRef, stack); return fieldCache.map(fieldRef); } @@ -434,25 +437,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { return methodCache.getKnown(methodRef); } - public DependencyViolations getViolations() { - if (dependencyViolations == null) { - dependencyViolations = new DependencyViolations(missingMethods, missingClasses, missingFields); - } - return dependencyViolations; - } - - public void checkForViolations() { - getViolations().checkForViolations(); - } - - public boolean hasViolations() { - return getViolations().hasSevereViolations(); - } - - public void showViolations(Appendable sb) throws IOException { - getViolations().showViolations(sb); - } - public void processDependencies() { interrupted = false; int index = 0; @@ -477,4 +461,8 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { public Diagnostics getDiagnostics() { return diagnostics; } + + public CallGraph getCallGraph() { + return callGraph; + } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyClassSource.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyClassSource.java index 681fb0df8..672a7416c 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyClassSource.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyClassSource.java @@ -22,6 +22,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.teavm.common.CachedMapper; import org.teavm.common.Mapper; +import org.teavm.diagnostics.Diagnostics; import org.teavm.model.*; import org.teavm.model.util.ModelUtils; 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 dfdb9e71b..92cff7e72 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -18,6 +18,7 @@ package org.teavm.dependency; import java.util.HashSet; import java.util.List; import java.util.Set; +import org.teavm.callgraph.DefaultCallGraphNode; import org.teavm.model.*; import org.teavm.model.instructions.*; import org.teavm.model.util.ListingBuilder; @@ -31,7 +32,8 @@ class DependencyGraphBuilder { private DependencyNode[] nodes; private DependencyNode resultNode; private ProgramReader program; - private DependencyStack callerStack; + private DefaultCallGraphNode caller; + private InstructionLocation currentLocation; private ExceptionConsumer currentExceptionConsumer; public DependencyGraphBuilder(DependencyChecker dependencyChecker) { @@ -50,7 +52,6 @@ class DependencyGraphBuilder { } resultNode = dep.getResult(); nodes = dep.getVariables(); - callerStack = new DependencyStack(method.getReference(), dep.getStack()); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlockReader block = program.basicBlockAt(i); currentExceptionConsumer = createExceptionConsumer(dep, block); @@ -62,7 +63,7 @@ class DependencyGraphBuilder { } for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) { if (tryCatch.getExceptionType() != null) { - dependencyChecker.linkClass(tryCatch.getExceptionType(), callerStack); + dependencyChecker.linkClass(tryCatch.getExceptionType(), caller.getMethod(), null); } } } @@ -116,20 +117,23 @@ class DependencyGraphBuilder { private final DependencyChecker checker; private final DependencyNode[] parameters; private final DependencyNode result; - private final DependencyStack stack; + private final DefaultCallGraphNode caller; + private final InstructionLocation location; private final Set knownMethods = new HashSet<>(); private ExceptionConsumer exceptionConsumer; public VirtualCallConsumer(DependencyNode node, ClassReader filterClass, MethodDescriptor methodDesc, DependencyChecker checker, DependencyNode[] parameters, - DependencyNode result, DependencyStack stack, ExceptionConsumer exceptionConsumer) { + DependencyNode result, DefaultCallGraphNode caller, InstructionLocation location, + ExceptionConsumer exceptionConsumer) { this.node = node; this.filterClass = filterClass; this.methodDesc = methodDesc; this.checker = checker; this.parameters = parameters; this.result = result; - this.stack = stack; + this.caller = caller; + this.location = location; this.exceptionConsumer = exceptionConsumer; } @@ -147,7 +151,7 @@ class DependencyGraphBuilder { return; } MethodReference methodRef = new MethodReference(className, methodDesc); - MethodDependency methodDep = checker.linkMethod(methodRef, stack); + MethodDependency methodDep = checker.linkMethod(methodRef, caller.getMethod(), location); if (!methodDep.isMissing() && knownMethods.add(methodRef)) { methodDep.use(); DependencyNode[] targetParams = methodDep.getVariables(); @@ -185,7 +189,7 @@ class DependencyGraphBuilder { private InstructionReader reader = new InstructionReader() { @Override public void location(InstructionLocation location) { - callerStack = new DependencyStack(callerStack.getMethod(), location, callerStack.getCause()); + currentLocation = location; } @Override @@ -200,7 +204,7 @@ class DependencyGraphBuilder { } if (cst instanceof ValueType.Object) { final String className = ((ValueType.Object)cst).getClassName(); - dependencyChecker.linkClass(className, callerStack); + dependencyChecker.linkClass(className, caller.getMethod(), currentLocation); } } @@ -228,7 +232,7 @@ class DependencyGraphBuilder { public void stringConstant(VariableReader receiver, String cst) { nodes[receiver.getIndex()].propagate(dependencyChecker.getType("java.lang.String")); MethodDependency method = dependencyChecker.linkMethod(new MethodReference(String.class, - "", char[].class, void.class), callerStack); + "", char[].class, void.class), caller.getMethod(), currentLocation); method.use(); } @@ -316,7 +320,7 @@ class DependencyGraphBuilder { nodes[receiver.getIndex()].propagate(dependencyChecker.getType("[" + itemType)); String className = extractClassName(itemType); if (className != null) { - dependencyChecker.linkClass(className, callerStack); + dependencyChecker.linkClass(className, caller.getMethod(), currentLocation); } } @@ -338,7 +342,7 @@ class DependencyGraphBuilder { nodes[receiver.getIndex()].propagate(dependencyChecker.getType(sb.toString())); String className = extractClassName(itemType); if (className != null) { - dependencyChecker.linkClass(className, callerStack); + dependencyChecker.linkClass(className, caller.getMethod(), currentLocation); } } @@ -350,7 +354,7 @@ class DependencyGraphBuilder { @Override public void getField(VariableReader receiver, VariableReader instance, FieldReference field, ValueType fieldType) { - FieldDependency fieldDep = dependencyChecker.linkField(field, callerStack); + FieldDependency fieldDep = dependencyChecker.linkField(field, caller.getMethod(), currentLocation); DependencyNode receiverNode = nodes[receiver.getIndex()]; fieldDep.getValue().connect(receiverNode); initClass(field.getClassName()); @@ -358,7 +362,7 @@ class DependencyGraphBuilder { @Override public void putField(VariableReader instance, FieldReference field, VariableReader value) { - FieldDependency fieldDep = dependencyChecker.linkField(field, callerStack); + FieldDependency fieldDep = dependencyChecker.linkField(field, caller.getMethod(), currentLocation); DependencyNode valueNode = nodes[value.getIndex()]; valueNode.connect(fieldDep.getValue()); initClass(field.getClassName()); @@ -420,7 +424,7 @@ class DependencyGraphBuilder { private void invokeSpecial(VariableReader receiver, VariableReader instance, MethodReference method, List arguments) { - MethodDependency methodDep = dependencyChecker.linkMethod(method, callerStack); + MethodDependency methodDep = dependencyChecker.linkMethod(method, caller.getMethod(), currentLocation); if (methodDep.isMissing()) { return; } @@ -441,7 +445,7 @@ class DependencyGraphBuilder { private void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method, List arguments) { - MethodDependency methodDep = dependencyChecker.linkMethod(method, callerStack); + MethodDependency methodDep = dependencyChecker.linkMethod(method, caller.getMethod(), currentLocation); if (methodDep.isMissing()) { return; } @@ -453,7 +457,7 @@ class DependencyGraphBuilder { DependencyConsumer listener = new VirtualCallConsumer(nodes[instance.getIndex()], dependencyChecker.getClassSource().get(methodDep.getMethod().getOwnerName()), method.getDescriptor(), dependencyChecker, actualArgs, - receiver != null ? nodes[receiver.getIndex()] : null, callerStack, + receiver != null ? nodes[receiver.getIndex()] : null, caller, currentLocation, currentExceptionConsumer); nodes[instance.getIndex()].addConsumer(listener); } @@ -462,13 +466,14 @@ class DependencyGraphBuilder { public void isInstance(VariableReader receiver, VariableReader value, final ValueType type) { String className = extractClassName(type); if (className != null) { - dependencyChecker.linkClass(className, callerStack); + dependencyChecker.linkClass(className, caller.getMethod(), currentLocation); } } @Override public void initClass(final String className) { - dependencyChecker.linkClass(className, callerStack).initClass(callerStack); + dependencyChecker.linkClass(className, caller.getMethod(), currentLocation) + .initClass(caller.getMethod(), currentLocation); } @Override @@ -476,8 +481,8 @@ class DependencyGraphBuilder { DependencyNode valueNode = nodes[value.getIndex()]; DependencyNode receiverNode = nodes[receiver.getIndex()]; valueNode.connect(receiverNode); - dependencyChecker.linkMethod(new MethodReference("java.lang.NullPointerException", - "", ValueType.VOID), callerStack).use(); + dependencyChecker.linkMethod(new MethodReference(NullPointerException.class, "", void.class), + caller.getMethod(), currentLocation).use(); currentExceptionConsumer.consume(dependencyChecker.getType("java.lang.NullPointerException")); } }; diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyStack.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyStack.java deleted file mode 100644 index 7072ddc44..000000000 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyStack.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2014 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.dependency; - -import org.teavm.model.InstructionLocation; -import org.teavm.model.MethodReference; - -/** - * - * @author Alexey Andreev - */ -public class DependencyStack { - public static final DependencyStack ROOT = new DependencyStack(); - private MethodReference method; - private DependencyStack cause; - private InstructionLocation location; - - private DependencyStack() { - } - - public DependencyStack(MethodReference method) { - this(method, ROOT); - } - - public DependencyStack(MethodReference method, InstructionLocation location) { - this(method, location, ROOT); - } - - public DependencyStack(MethodReference method, DependencyStack cause) { - this(method, null, cause); - } - - public DependencyStack(MethodReference method, InstructionLocation location, DependencyStack cause) { - if (method == null || cause == null) { - throw new IllegalArgumentException("Arguments must not be null"); - } - this.method = method; - this.location = location; - this.cause = cause; - } - - public MethodReference getMethod() { - return method; - } - - public DependencyStack getCause() { - return cause; - } - - public InstructionLocation getLocation() { - return location; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - DependencyStack stack = this; - while (true) { - if (stack.method == null) { - sb.append(" used by ROOT\n"); - break; - } else { - sb.append(" used by " + stack.method); - if (stack.location != null) { - sb.append(" : ").append(stack.location.getLine()); - } - stack = stack.cause; - } - } - return sb.toString(); - } -} diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyViolations.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyViolations.java deleted file mode 100644 index 1e3d5997e..000000000 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyViolations.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2014 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.dependency; - -import java.io.IOException; -import java.util.*; - -/** - * - * @author Alexey Andreev - */ -public class DependencyViolations { - private final Set missingMethods; - private final Set missingClasses; - private final Set missingFields; - - DependencyViolations(Collection missingMethods, - Collection missingClasses, - Collection missingFields) { - this.missingMethods = Collections.unmodifiableSet(new HashSet<>(missingMethods)); - this.missingClasses = Collections.unmodifiableSet(new HashSet<>(missingClasses)); - this.missingFields = Collections.unmodifiableSet(new HashSet<>(missingFields)); - } - - public Set getMissingMethods() { - return missingMethods; - } - - public Set getMissingClasses() { - return missingClasses; - } - - public Set getMissingFields() { - return missingFields; - } - - public boolean hasSevereViolations() { - return !missingMethods.isEmpty() || !missingClasses.isEmpty() || !missingFields.isEmpty(); - } - - public void checkForViolations() { - if (!hasSevereViolations()) { - return; - } - StringBuilder sb = new StringBuilder(); - try { - showViolations(sb); - } catch (IOException e) { - throw new AssertionError("StringBuilder should not throw IOException"); - } - throw new IllegalStateException(sb.toString()); - } - - public void showViolations(Appendable sb) throws IOException { - List items = new ArrayList<>(); - Map stackMap = new HashMap<>(); - for (ClassDependencyInfo cls : missingClasses) { - stackMap.put(cls.getClassName(), cls.getStack()); - items.add(cls.getClassName()); - } - for (MethodDependencyInfo method : missingMethods) { - stackMap.put(method.getReference().toString(), method.getStack()); - items.add(method.getReference().toString()); - } - for (FieldDependencyInfo field : missingFields) { - stackMap.put(field.getReference().toString(), field.getStack()); - items.add(field.getReference().toString()); - } - Collections.sort(items); - sb.append("Can't compile due to the following violations:\n"); - for (String item : items) { - sb.append("Missing ").append(item).append("\n"); - DependencyStack stack = stackMap.get(item); - if (stack == null) { - sb.append(" at unknown location\n"); - } else { - while (stack.getMethod() != null) { - sb.append(" at ").append(stack.getMethod().toString()); - if (stack.getLocation() != null) { - sb.append(":").append(String.valueOf(stack.getLocation().getLine())); - } - sb.append("\n"); - stack = stack.getCause(); - } - } - sb.append('\n'); - } - } -} diff --git a/teavm-core/src/main/java/org/teavm/dependency/FieldDependencyInfo.java b/teavm-core/src/main/java/org/teavm/dependency/FieldDependencyInfo.java index 80f1ce936..6e7e1156f 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/FieldDependencyInfo.java +++ b/teavm-core/src/main/java/org/teavm/dependency/FieldDependencyInfo.java @@ -27,6 +27,4 @@ public interface FieldDependencyInfo { FieldReference getReference(); boolean isMissing(); - - DependencyStack getStack(); } diff --git a/teavm-core/src/main/java/org/teavm/dependency/MethodDependencyInfo.java b/teavm-core/src/main/java/org/teavm/dependency/MethodDependencyInfo.java index 4f06ebfec..cc3359a3a 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/MethodDependencyInfo.java +++ b/teavm-core/src/main/java/org/teavm/dependency/MethodDependencyInfo.java @@ -39,6 +39,4 @@ public interface MethodDependencyInfo { boolean isUsed(); boolean isMissing(); - - DependencyStack getStack(); } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyDiagnostics.java b/teavm-core/src/main/java/org/teavm/diagnostics/DependencyDiagnostics.java similarity index 64% rename from teavm-core/src/main/java/org/teavm/dependency/DependencyDiagnostics.java rename to teavm-core/src/main/java/org/teavm/diagnostics/DependencyDiagnostics.java index ac6cb6604..08d666ddc 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyDiagnostics.java +++ b/teavm-core/src/main/java/org/teavm/diagnostics/DependencyDiagnostics.java @@ -13,26 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.dependency; +package org.teavm.diagnostics; import java.util.ArrayList; import java.util.List; -import org.teavm.model.Diagnostics; import org.teavm.model.InstructionLocation; -import org.teavm.vm.DiagnosticsProblem; -import org.teavm.vm.DiagnosticsProblemSeverity; +import org.teavm.model.MethodReference; /** * * @author Alexey Andreev */ class DependencyDiagnostics implements Diagnostics { - private List problems = new ArrayList<>(); - private List severeProblems = new ArrayList<>(); + private List problems = new ArrayList<>(); + private List severeProblems = new ArrayList<>(); @Override - public void error(InstructionLocation location, String error) { - DiagnosticsProblem violation = new DiagnosticsProblem(DiagnosticsProblemSeverity.ERROR, location, error); + public void error(MethodReference method, InstructionLocation location, String error, Object[] params) { + Problem violation = new Problem(ProblemSeverity.ERROR, location, error); problems.add(violation); severeProblems.add(violation); } @@ -44,7 +42,7 @@ class DependencyDiagnostics implements Diagnostics { @Override public void warning(InstructionLocation location, String error) { - DiagnosticsProblem violation = new DiagnosticsProblem(DiagnosticsProblemSeverity.WARNING, location, error); + Problem violation = new Problem(ProblemSeverity.WARNING, location, error); problems.add(violation); } @@ -53,11 +51,11 @@ class DependencyDiagnostics implements Diagnostics { warning(null, error); } - public List getProblems() { + public List getProblems() { return problems; } - public List getSevereProblems() { + public List getSevereProblems() { return severeProblems; } } diff --git a/teavm-core/src/main/java/org/teavm/model/Diagnostics.java b/teavm-core/src/main/java/org/teavm/diagnostics/Diagnostics.java similarity index 76% rename from teavm-core/src/main/java/org/teavm/model/Diagnostics.java rename to teavm-core/src/main/java/org/teavm/diagnostics/Diagnostics.java index f7b046100..a061bbac9 100644 --- a/teavm-core/src/main/java/org/teavm/model/Diagnostics.java +++ b/teavm-core/src/main/java/org/teavm/diagnostics/Diagnostics.java @@ -13,19 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.model; +package org.teavm.diagnostics; +import org.teavm.model.CallLocation; /** * * @author Alexey Andreev */ public interface Diagnostics { - void error(InstructionLocation location, String error); + void error(CallLocation location, String error, Object... params); - void error(String error); - - void warning(InstructionLocation location, String error); - - void warning(String error); + void warning(CallLocation location, String error, Object... params); } diff --git a/teavm-core/src/main/java/org/teavm/vm/DiagnosticsProblem.java b/teavm-core/src/main/java/org/teavm/diagnostics/Problem.java similarity index 66% rename from teavm-core/src/main/java/org/teavm/vm/DiagnosticsProblem.java rename to teavm-core/src/main/java/org/teavm/diagnostics/Problem.java index 233d17ab7..b7d0eeec4 100644 --- a/teavm-core/src/main/java/org/teavm/vm/DiagnosticsProblem.java +++ b/teavm-core/src/main/java/org/teavm/diagnostics/Problem.java @@ -13,30 +13,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.vm; +package org.teavm.diagnostics; -import org.teavm.model.InstructionLocation; +import java.util.Arrays; +import org.teavm.model.CallLocation; /** * * @author Alexey Andreev */ -public class DiagnosticsProblem { - private DiagnosticsProblemSeverity severity; - private InstructionLocation location; +public class Problem { + private ProblemSeverity severity; + private CallLocation location; private String text; + private Object[] params; - public DiagnosticsProblem(DiagnosticsProblemSeverity severity, InstructionLocation location, String text) { + public Problem(ProblemSeverity severity, CallLocation location, String text, Object[] params) { this.severity = severity; this.location = location; this.text = text; + this.params = Arrays.copyOf(params, params.length); } - public DiagnosticsProblemSeverity getSeverity() { + public ProblemSeverity getSeverity() { return severity; } - public InstructionLocation getLocation() { + public CallLocation getLocation() { return location; } diff --git a/teavm-core/src/main/java/org/teavm/vm/DiagnosticsProblemSeverity.java b/teavm-core/src/main/java/org/teavm/diagnostics/ProblemSeverity.java similarity index 91% rename from teavm-core/src/main/java/org/teavm/vm/DiagnosticsProblemSeverity.java rename to teavm-core/src/main/java/org/teavm/diagnostics/ProblemSeverity.java index 8fa47a89f..1a09fca6e 100644 --- a/teavm-core/src/main/java/org/teavm/vm/DiagnosticsProblemSeverity.java +++ b/teavm-core/src/main/java/org/teavm/diagnostics/ProblemSeverity.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.vm; +package org.teavm.diagnostics; /** * * @author Alexey Andreev */ -public enum DiagnosticsProblemSeverity { +public enum ProblemSeverity { ERROR, WARNING } diff --git a/teavm-core/src/main/java/org/teavm/javascript/NullPointerExceptionTransformer.java b/teavm-core/src/main/java/org/teavm/javascript/NullPointerExceptionTransformer.java index 3d66705cb..3d9f3126e 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/NullPointerExceptionTransformer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/NullPointerExceptionTransformer.java @@ -15,6 +15,7 @@ */ package org.teavm.javascript; +import org.teavm.diagnostics.Diagnostics; import org.teavm.model.*; import org.teavm.model.instructions.InvocationType; import org.teavm.model.instructions.InvokeInstruction; diff --git a/teavm-core/src/main/java/org/teavm/model/CallLocation.java b/teavm-core/src/main/java/org/teavm/model/CallLocation.java new file mode 100644 index 000000000..11017cb3d --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/CallLocation.java @@ -0,0 +1,57 @@ +/* + * Copyright 2014 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.model; + +import java.util.Objects; + +/** + * + * @author Alexey Andreev + */ +public class CallLocation { + private MethodReference method; + private InstructionLocation sourceLocation; + + public CallLocation(MethodReference method, InstructionLocation sourceLocation) { + this.method = method; + this.sourceLocation = sourceLocation; + } + + public MethodReference getMethod() { + return method; + } + + public InstructionLocation getSourceLocation() { + return sourceLocation; + } + + @Override + public int hashCode() { + return Objects.hash(method, sourceLocation); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof CallLocation)) { + return false; + } + CallLocation other = (CallLocation)obj; + return Objects.equals(method, other.method) && Objects.equals(sourceLocation, other.sourceLocation); + } +} diff --git a/teavm-core/src/main/java/org/teavm/model/ClassHolderTransformer.java b/teavm-core/src/main/java/org/teavm/model/ClassHolderTransformer.java index 4ae8cdcb0..c7eeebc92 100644 --- a/teavm-core/src/main/java/org/teavm/model/ClassHolderTransformer.java +++ b/teavm-core/src/main/java/org/teavm/model/ClassHolderTransformer.java @@ -15,6 +15,8 @@ */ package org.teavm.model; +import org.teavm.diagnostics.Diagnostics; + /** * diff --git a/teavm-core/src/main/java/org/teavm/vm/Violations.java b/teavm-core/src/main/java/org/teavm/vm/Violations.java index 20d2f0ca1..fe1cbe11e 100644 --- a/teavm-core/src/main/java/org/teavm/vm/Violations.java +++ b/teavm-core/src/main/java/org/teavm/vm/Violations.java @@ -20,6 +20,7 @@ import java.util.Set; import org.teavm.dependency.ClassDependencyInfo; import org.teavm.dependency.FieldDependencyInfo; import org.teavm.dependency.MethodDependencyInfo; +import org.teavm.diagnostics.Problem; /** * @@ -32,9 +33,9 @@ public interface Violations { Set getMissingFields(); - List getDiagnosticsProblems(); + List getDiagnosticsProblems(); - List getSevereDiagnosticsProblems(); + List getSevereDiagnosticsProblems(); boolean hasSevereViolations(); diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSObjectClassTransformer.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSObjectClassTransformer.java index cc82e5072..2033ca5df 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSObjectClassTransformer.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSObjectClassTransformer.java @@ -15,6 +15,7 @@ */ package org.teavm.jso.plugin; +import org.teavm.diagnostics.Diagnostics; import org.teavm.model.*; /** diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java index 456966d75..1dcf7a086 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java @@ -16,6 +16,7 @@ package org.teavm.jso.plugin; import java.util.*; +import org.teavm.diagnostics.Diagnostics; import org.teavm.javascript.ni.PreserveOriginalName; import org.teavm.jso.*; import org.teavm.model.*;