mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Refuse from CallStack for complete CallGraph
This commit is contained in:
parent
e736cf09d7
commit
30781bb16e
41
teavm-core/src/main/java/org/teavm/callgraph/CallGraph.java
Normal file
41
teavm-core/src/main/java/org/teavm/callgraph/CallGraph.java
Normal file
|
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Root object for traversing through call graph. Graph does not represent polymorphic calls.
|
||||||
|
* Instead, it generated multiple call sites for one location.</p>
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public interface CallGraph {
|
||||||
|
/**
|
||||||
|
* <p>Get node corresponding to the specific method.</p>
|
||||||
|
*
|
||||||
|
* @param method a method to lookup node for.
|
||||||
|
* @return the node that corresponds to the specified method or <code>null</code>, if this method is never
|
||||||
|
* called.
|
||||||
|
*/
|
||||||
|
CallGraphNode getNode(MethodReference method);
|
||||||
|
|
||||||
|
Collection<? extends FieldAccessSite> getFieldAccess(FieldReference reference);
|
||||||
|
|
||||||
|
Collection<? extends ClassAccessSite> getClassAccess(String className);
|
||||||
|
}
|
|
@ -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<? extends CallSite> getCallSites();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns immutable collection of all call sites that call this method.
|
||||||
|
*/
|
||||||
|
Collection<? extends CallSite> getCallerCallSites();
|
||||||
|
|
||||||
|
Collection<? extends FieldAccessSite> getFieldAccessSites();
|
||||||
|
|
||||||
|
Collection<? extends ClassAccessSite> getClassAccessSites();
|
||||||
|
}
|
41
teavm-core/src/main/java/org/teavm/callgraph/CallSite.java
Normal file
41
teavm-core/src/main/java/org/teavm/callgraph/CallSite.java
Normal file
|
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Call site that represents exact place in the code that calls a method.</p>.
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public interface CallSite {
|
||||||
|
/**
|
||||||
|
* <p>Gets location of the call site</p>.
|
||||||
|
*
|
||||||
|
* @return location of the call site or <code>null</code> if no debug information found for this call site.
|
||||||
|
*/
|
||||||
|
InstructionLocation getLocation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Gets a method that this call site invokes.</p>
|
||||||
|
*/
|
||||||
|
CallGraphNode getCallee();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Gets a method that contains this call site.</p>
|
||||||
|
*/
|
||||||
|
CallGraphNode getCaller();
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
|
@ -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<MethodReference, DefaultCallGraphNode> nodes = new HashMap<>();
|
||||||
|
private Map<FieldReference, Set<DefaultFieldAccessSite>> fieldAccessSites = new HashMap<>();
|
||||||
|
private Map<String, Set<DefaultClassAccessSite>> 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<DefaultFieldAccessSite> getFieldAccess(FieldReference reference) {
|
||||||
|
Set<DefaultFieldAccessSite> resultSet = fieldAccessSites.get(reference);
|
||||||
|
return resultSet != null ? Collections.unmodifiableSet(resultSet) :
|
||||||
|
Collections.<DefaultFieldAccessSite>emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addFieldAccess(DefaultFieldAccessSite accessSite) {
|
||||||
|
Set<DefaultFieldAccessSite> sites = fieldAccessSites.get(accessSite.getField());
|
||||||
|
if (sites == null) {
|
||||||
|
sites = new HashSet<>();
|
||||||
|
fieldAccessSites.put(accessSite.getField(), sites);
|
||||||
|
}
|
||||||
|
sites.add(accessSite);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<DefaultClassAccessSite> getClassAccess(String className) {
|
||||||
|
Set<DefaultClassAccessSite> resultSet = classAccessSites.get(className);
|
||||||
|
return resultSet != null ? Collections.unmodifiableSet(resultSet) :
|
||||||
|
Collections.<DefaultClassAccessSite>emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addClassAccess(DefaultClassAccessSite accessSite) {
|
||||||
|
Set<DefaultClassAccessSite> sites = classAccessSites.get(accessSite.getClassName());
|
||||||
|
if (sites == null) {
|
||||||
|
sites = new HashSet<>();
|
||||||
|
classAccessSites.put(accessSite.getClassName(), sites);
|
||||||
|
}
|
||||||
|
sites.add(accessSite);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<DefaultCallSite> callSites;
|
||||||
|
private transient Set<DefaultCallSite> safeCallSites;
|
||||||
|
private List<DefaultCallSite> callerCallSites;
|
||||||
|
private transient List<DefaultCallSite> safeCallersCallSites;
|
||||||
|
private Set<DefaultFieldAccessSite> fieldAccessSites;
|
||||||
|
private transient Set<DefaultFieldAccessSite> safeFieldAccessSites;
|
||||||
|
private Set<DefaultClassAccessSite> classAccessSites;
|
||||||
|
private transient Set<DefaultClassAccessSite> safeClassAccessSites;
|
||||||
|
|
||||||
|
DefaultCallGraphNode(DefaultCallGraph graph) {
|
||||||
|
this.graph = graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DefaultCallGraph getGraph() {
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodReference getMethod() {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<DefaultCallSite> getCallSites() {
|
||||||
|
if (safeCallSites == null) {
|
||||||
|
safeCallSites = Collections.unmodifiableSet(callSites);
|
||||||
|
}
|
||||||
|
return safeCallSites;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<DefaultCallSite> 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<DefaultFieldAccessSite> 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<? extends ClassAccessSite> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
|
@ -16,6 +16,8 @@
|
||||||
package org.teavm.dependency;
|
package org.teavm.dependency;
|
||||||
|
|
||||||
import org.teavm.model.ClassReader;
|
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 {
|
public class ClassDependency implements ClassDependencyInfo {
|
||||||
private DependencyChecker checker;
|
private DependencyChecker checker;
|
||||||
private String className;
|
private String className;
|
||||||
private DependencyStack stack;
|
|
||||||
private ClassReader classReader;
|
private ClassReader classReader;
|
||||||
|
|
||||||
ClassDependency(DependencyChecker checker, String className, DependencyStack stack, ClassReader classReader) {
|
ClassDependency(DependencyChecker checker, String className, ClassReader classReader) {
|
||||||
this.checker = checker;
|
this.checker = checker;
|
||||||
this.className = className;
|
this.className = className;
|
||||||
this.stack = stack;
|
|
||||||
this.classReader = classReader;
|
this.classReader = classReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,14 +48,9 @@ public class ClassDependency implements ClassDependencyInfo {
|
||||||
return classReader;
|
return classReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void initClass(MethodReference caller, InstructionLocation location) {
|
||||||
public DependencyStack getStack() {
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initClass(DependencyStack stack) {
|
|
||||||
if (!isMissing()) {
|
if (!isMissing()) {
|
||||||
checker.initClass(this, stack);
|
checker.initClass(this, caller, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,4 @@ public interface ClassDependencyInfo {
|
||||||
String getClassName();
|
String getClassName();
|
||||||
|
|
||||||
boolean isMissing();
|
boolean isMissing();
|
||||||
|
|
||||||
DependencyStack getStack();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,8 @@
|
||||||
package org.teavm.dependency;
|
package org.teavm.dependency;
|
||||||
|
|
||||||
import org.teavm.common.ServiceRepository;
|
import org.teavm.common.ServiceRepository;
|
||||||
import org.teavm.model.ClassHolder;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.model.Diagnostics;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.FieldReference;
|
|
||||||
import org.teavm.model.MethodReference;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -34,11 +32,11 @@ public interface DependencyAgent extends DependencyInfo, ServiceRepository {
|
||||||
|
|
||||||
void submitClass(ClassHolder cls);
|
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();
|
Diagnostics getDiagnostics();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,11 @@ package org.teavm.dependency;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import org.teavm.callgraph.CallGraph;
|
||||||
|
import org.teavm.callgraph.DefaultCallGraph;
|
||||||
import org.teavm.common.*;
|
import org.teavm.common.*;
|
||||||
import org.teavm.common.CachedMapper.KeyListener;
|
import org.teavm.common.CachedMapper.KeyListener;
|
||||||
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.util.ModelUtils;
|
import org.teavm.model.util.ModelUtils;
|
||||||
|
|
||||||
|
@ -33,9 +36,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
private ClassLoader classLoader;
|
private ClassLoader classLoader;
|
||||||
private Mapper<MethodReference, MethodReader> methodReaderCache;
|
private Mapper<MethodReference, MethodReader> methodReaderCache;
|
||||||
private Mapper<FieldReference, FieldReader> fieldReaderCache;
|
private Mapper<FieldReference, FieldReader> fieldReaderCache;
|
||||||
private Map<MethodReference, DependencyStack> stacks = new HashMap<>();
|
|
||||||
private Map<FieldReference, DependencyStack> fieldStacks = new HashMap<>();
|
|
||||||
private Map<String, DependencyStack> classStacks = new HashMap<>();
|
|
||||||
private CachedMapper<MethodReference, MethodDependency> methodCache;
|
private CachedMapper<MethodReference, MethodDependency> methodCache;
|
||||||
private CachedMapper<FieldReference, FieldDependency> fieldCache;
|
private CachedMapper<FieldReference, FieldDependency> fieldCache;
|
||||||
private CachedMapper<String, ClassDependency> classCache;
|
private CachedMapper<String, ClassDependency> classCache;
|
||||||
|
@ -51,6 +51,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
private DependencyCheckerInterruptor interruptor;
|
private DependencyCheckerInterruptor interruptor;
|
||||||
private boolean interrupted;
|
private boolean interrupted;
|
||||||
private Diagnostics diagnostics;
|
private Diagnostics diagnostics;
|
||||||
|
private DefaultCallGraph callGraph = new DefaultCallGraph();
|
||||||
|
|
||||||
public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services,
|
public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services,
|
||||||
Diagnostics diagnostics) {
|
Diagnostics diagnostics) {
|
||||||
|
@ -72,26 +73,24 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
@Override public MethodDependency map(MethodReference preimage) {
|
@Override public MethodDependency map(MethodReference preimage) {
|
||||||
MethodReader method = methodReaderCache.map(preimage);
|
MethodReader method = methodReaderCache.map(preimage);
|
||||||
if (method != null && !method.getReference().equals(preimage)) {
|
if (method != null && !method.getReference().equals(preimage)) {
|
||||||
stacks.put(method.getReference(), stacks.get(preimage));
|
|
||||||
return methodCache.map(method.getReference());
|
return methodCache.map(method.getReference());
|
||||||
}
|
}
|
||||||
return createMethodDep(preimage, method, stacks.get(preimage));
|
return createMethodDep(preimage, method);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
fieldCache = new CachedMapper<>(new Mapper<FieldReference, FieldDependency>() {
|
fieldCache = new CachedMapper<>(new Mapper<FieldReference, FieldDependency>() {
|
||||||
@Override public FieldDependency map(FieldReference preimage) {
|
@Override public FieldDependency map(FieldReference preimage) {
|
||||||
FieldReader field = fieldReaderCache.map(preimage);
|
FieldReader field = fieldReaderCache.map(preimage);
|
||||||
if (field != null && !field.getReference().equals(preimage)) {
|
if (field != null && !field.getReference().equals(preimage)) {
|
||||||
fieldStacks.put(field.getReference(), fieldStacks.get(preimage));
|
|
||||||
return fieldCache.map(field.getReference());
|
return fieldCache.map(field.getReference());
|
||||||
}
|
}
|
||||||
return createFieldNode(preimage, field, fieldStacks.get(preimage));
|
return createFieldNode(preimage, field);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
classCache = new CachedMapper<>(new Mapper<String, ClassDependency>() {
|
classCache = new CachedMapper<>(new Mapper<String, ClassDependency>() {
|
||||||
@Override public ClassDependency map(String preimage) {
|
@Override public ClassDependency map(String preimage) {
|
||||||
return createClassDependency(preimage, classStacks.get(preimage));
|
return createClassDependency(preimage);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
methodCache.addKeyListener(new KeyListener<MethodReference>() {
|
methodCache.addKeyListener(new KeyListener<MethodReference>() {
|
||||||
|
@ -167,7 +166,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String generateClassName() {
|
public String generateClassName() {
|
||||||
return "$$tmp$$.TempClass" + classNameSuffix++;
|
return "$$teavm_generated_class$$" + classNameSuffix++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -189,7 +188,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
if (parameters.length + 1 != argumentTypes.length) {
|
if (parameters.length + 1 != argumentTypes.length) {
|
||||||
throw new IllegalArgumentException("argumentTypes length does not match the number of method's arguments");
|
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();
|
method.use();
|
||||||
DependencyNode[] varNodes = method.getVariables();
|
DependencyNode[] varNodes = method.getVariables();
|
||||||
varNodes[0].propagate(getType(methodRef.getClassName()));
|
varNodes[0].propagate(getType(methodRef.getClassName()));
|
||||||
|
@ -218,7 +217,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDependency linkClass(String className, DependencyStack stack) {
|
public ClassDependency linkClass(String className, DependencyStack stack) {
|
||||||
classStacks.put(className, stack);
|
|
||||||
return classCache.map(className);
|
return classCache.map(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,21 +237,26 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MethodDependency linkMethod(MethodReference methodRef, DependencyStack stack) {
|
public MethodDependency linkMethod(MethodReference methodRef, MethodReference caller,
|
||||||
|
InstructionLocation location) {
|
||||||
if (methodRef == null) {
|
if (methodRef == null) {
|
||||||
throw new IllegalArgumentException();
|
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);
|
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();
|
ClassReader reader = cls.getClassReader();
|
||||||
final MethodReader method = reader.getMethod(new MethodDescriptor("<clinit>", void.class));
|
final MethodReader method = reader.getMethod(new MethodDescriptor("<clinit>", void.class));
|
||||||
if (method != null) {
|
if (method != null) {
|
||||||
tasks.add(new Runnable() {
|
tasks.add(new Runnable() {
|
||||||
@Override public void run() {
|
@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
|
@Override
|
||||||
public FieldDependency linkField(FieldReference fieldRef, DependencyStack stack) {
|
public FieldDependency linkField(FieldReference fieldRef, MethodReference caller, InstructionLocation location) {
|
||||||
fieldStacks.put(fieldRef, stack);
|
fieldStacks.put(fieldRef, stack);
|
||||||
return fieldCache.map(fieldRef);
|
return fieldCache.map(fieldRef);
|
||||||
}
|
}
|
||||||
|
@ -434,25 +437,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
return methodCache.getKnown(methodRef);
|
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() {
|
public void processDependencies() {
|
||||||
interrupted = false;
|
interrupted = false;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
@ -477,4 +461,8 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
public Diagnostics getDiagnostics() {
|
public Diagnostics getDiagnostics() {
|
||||||
return diagnostics;
|
return diagnostics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CallGraph getCallGraph() {
|
||||||
|
return callGraph;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import org.teavm.common.CachedMapper;
|
import org.teavm.common.CachedMapper;
|
||||||
import org.teavm.common.Mapper;
|
import org.teavm.common.Mapper;
|
||||||
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.util.ModelUtils;
|
import org.teavm.model.util.ModelUtils;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.teavm.dependency;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.teavm.callgraph.DefaultCallGraphNode;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.instructions.*;
|
import org.teavm.model.instructions.*;
|
||||||
import org.teavm.model.util.ListingBuilder;
|
import org.teavm.model.util.ListingBuilder;
|
||||||
|
@ -31,7 +32,8 @@ class DependencyGraphBuilder {
|
||||||
private DependencyNode[] nodes;
|
private DependencyNode[] nodes;
|
||||||
private DependencyNode resultNode;
|
private DependencyNode resultNode;
|
||||||
private ProgramReader program;
|
private ProgramReader program;
|
||||||
private DependencyStack callerStack;
|
private DefaultCallGraphNode caller;
|
||||||
|
private InstructionLocation currentLocation;
|
||||||
private ExceptionConsumer currentExceptionConsumer;
|
private ExceptionConsumer currentExceptionConsumer;
|
||||||
|
|
||||||
public DependencyGraphBuilder(DependencyChecker dependencyChecker) {
|
public DependencyGraphBuilder(DependencyChecker dependencyChecker) {
|
||||||
|
@ -50,7 +52,6 @@ class DependencyGraphBuilder {
|
||||||
}
|
}
|
||||||
resultNode = dep.getResult();
|
resultNode = dep.getResult();
|
||||||
nodes = dep.getVariables();
|
nodes = dep.getVariables();
|
||||||
callerStack = new DependencyStack(method.getReference(), dep.getStack());
|
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
BasicBlockReader block = program.basicBlockAt(i);
|
BasicBlockReader block = program.basicBlockAt(i);
|
||||||
currentExceptionConsumer = createExceptionConsumer(dep, block);
|
currentExceptionConsumer = createExceptionConsumer(dep, block);
|
||||||
|
@ -62,7 +63,7 @@ class DependencyGraphBuilder {
|
||||||
}
|
}
|
||||||
for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) {
|
for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) {
|
||||||
if (tryCatch.getExceptionType() != null) {
|
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 DependencyChecker checker;
|
||||||
private final DependencyNode[] parameters;
|
private final DependencyNode[] parameters;
|
||||||
private final DependencyNode result;
|
private final DependencyNode result;
|
||||||
private final DependencyStack stack;
|
private final DefaultCallGraphNode caller;
|
||||||
|
private final InstructionLocation location;
|
||||||
private final Set<MethodReference> knownMethods = new HashSet<>();
|
private final Set<MethodReference> knownMethods = new HashSet<>();
|
||||||
private ExceptionConsumer exceptionConsumer;
|
private ExceptionConsumer exceptionConsumer;
|
||||||
|
|
||||||
public VirtualCallConsumer(DependencyNode node, ClassReader filterClass,
|
public VirtualCallConsumer(DependencyNode node, ClassReader filterClass,
|
||||||
MethodDescriptor methodDesc, DependencyChecker checker, DependencyNode[] parameters,
|
MethodDescriptor methodDesc, DependencyChecker checker, DependencyNode[] parameters,
|
||||||
DependencyNode result, DependencyStack stack, ExceptionConsumer exceptionConsumer) {
|
DependencyNode result, DefaultCallGraphNode caller, InstructionLocation location,
|
||||||
|
ExceptionConsumer exceptionConsumer) {
|
||||||
this.node = node;
|
this.node = node;
|
||||||
this.filterClass = filterClass;
|
this.filterClass = filterClass;
|
||||||
this.methodDesc = methodDesc;
|
this.methodDesc = methodDesc;
|
||||||
this.checker = checker;
|
this.checker = checker;
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
this.result = result;
|
this.result = result;
|
||||||
this.stack = stack;
|
this.caller = caller;
|
||||||
|
this.location = location;
|
||||||
this.exceptionConsumer = exceptionConsumer;
|
this.exceptionConsumer = exceptionConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +151,7 @@ class DependencyGraphBuilder {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MethodReference methodRef = new MethodReference(className, methodDesc);
|
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)) {
|
if (!methodDep.isMissing() && knownMethods.add(methodRef)) {
|
||||||
methodDep.use();
|
methodDep.use();
|
||||||
DependencyNode[] targetParams = methodDep.getVariables();
|
DependencyNode[] targetParams = methodDep.getVariables();
|
||||||
|
@ -185,7 +189,7 @@ class DependencyGraphBuilder {
|
||||||
private InstructionReader reader = new InstructionReader() {
|
private InstructionReader reader = new InstructionReader() {
|
||||||
@Override
|
@Override
|
||||||
public void location(InstructionLocation location) {
|
public void location(InstructionLocation location) {
|
||||||
callerStack = new DependencyStack(callerStack.getMethod(), location, callerStack.getCause());
|
currentLocation = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -200,7 +204,7 @@ class DependencyGraphBuilder {
|
||||||
}
|
}
|
||||||
if (cst instanceof ValueType.Object) {
|
if (cst instanceof ValueType.Object) {
|
||||||
final String className = ((ValueType.Object)cst).getClassName();
|
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) {
|
public void stringConstant(VariableReader receiver, String cst) {
|
||||||
nodes[receiver.getIndex()].propagate(dependencyChecker.getType("java.lang.String"));
|
nodes[receiver.getIndex()].propagate(dependencyChecker.getType("java.lang.String"));
|
||||||
MethodDependency method = dependencyChecker.linkMethod(new MethodReference(String.class,
|
MethodDependency method = dependencyChecker.linkMethod(new MethodReference(String.class,
|
||||||
"<init>", char[].class, void.class), callerStack);
|
"<init>", char[].class, void.class), caller.getMethod(), currentLocation);
|
||||||
method.use();
|
method.use();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +320,7 @@ class DependencyGraphBuilder {
|
||||||
nodes[receiver.getIndex()].propagate(dependencyChecker.getType("[" + itemType));
|
nodes[receiver.getIndex()].propagate(dependencyChecker.getType("[" + itemType));
|
||||||
String className = extractClassName(itemType);
|
String className = extractClassName(itemType);
|
||||||
if (className != null) {
|
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()));
|
nodes[receiver.getIndex()].propagate(dependencyChecker.getType(sb.toString()));
|
||||||
String className = extractClassName(itemType);
|
String className = extractClassName(itemType);
|
||||||
if (className != null) {
|
if (className != null) {
|
||||||
dependencyChecker.linkClass(className, callerStack);
|
dependencyChecker.linkClass(className, caller.getMethod(), currentLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +354,7 @@ class DependencyGraphBuilder {
|
||||||
@Override
|
@Override
|
||||||
public void getField(VariableReader receiver, VariableReader instance, FieldReference field,
|
public void getField(VariableReader receiver, VariableReader instance, FieldReference field,
|
||||||
ValueType fieldType) {
|
ValueType fieldType) {
|
||||||
FieldDependency fieldDep = dependencyChecker.linkField(field, callerStack);
|
FieldDependency fieldDep = dependencyChecker.linkField(field, caller.getMethod(), currentLocation);
|
||||||
DependencyNode receiverNode = nodes[receiver.getIndex()];
|
DependencyNode receiverNode = nodes[receiver.getIndex()];
|
||||||
fieldDep.getValue().connect(receiverNode);
|
fieldDep.getValue().connect(receiverNode);
|
||||||
initClass(field.getClassName());
|
initClass(field.getClassName());
|
||||||
|
@ -358,7 +362,7 @@ class DependencyGraphBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putField(VariableReader instance, FieldReference field, VariableReader value) {
|
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()];
|
DependencyNode valueNode = nodes[value.getIndex()];
|
||||||
valueNode.connect(fieldDep.getValue());
|
valueNode.connect(fieldDep.getValue());
|
||||||
initClass(field.getClassName());
|
initClass(field.getClassName());
|
||||||
|
@ -420,7 +424,7 @@ class DependencyGraphBuilder {
|
||||||
|
|
||||||
private void invokeSpecial(VariableReader receiver, VariableReader instance, MethodReference method,
|
private void invokeSpecial(VariableReader receiver, VariableReader instance, MethodReference method,
|
||||||
List<? extends VariableReader> arguments) {
|
List<? extends VariableReader> arguments) {
|
||||||
MethodDependency methodDep = dependencyChecker.linkMethod(method, callerStack);
|
MethodDependency methodDep = dependencyChecker.linkMethod(method, caller.getMethod(), currentLocation);
|
||||||
if (methodDep.isMissing()) {
|
if (methodDep.isMissing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -441,7 +445,7 @@ 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) {
|
||||||
MethodDependency methodDep = dependencyChecker.linkMethod(method, callerStack);
|
MethodDependency methodDep = dependencyChecker.linkMethod(method, caller.getMethod(), currentLocation);
|
||||||
if (methodDep.isMissing()) {
|
if (methodDep.isMissing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -453,7 +457,7 @@ class DependencyGraphBuilder {
|
||||||
DependencyConsumer listener = new VirtualCallConsumer(nodes[instance.getIndex()],
|
DependencyConsumer listener = new VirtualCallConsumer(nodes[instance.getIndex()],
|
||||||
dependencyChecker.getClassSource().get(methodDep.getMethod().getOwnerName()),
|
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, caller, currentLocation,
|
||||||
currentExceptionConsumer);
|
currentExceptionConsumer);
|
||||||
nodes[instance.getIndex()].addConsumer(listener);
|
nodes[instance.getIndex()].addConsumer(listener);
|
||||||
}
|
}
|
||||||
|
@ -462,13 +466,14 @@ class DependencyGraphBuilder {
|
||||||
public void isInstance(VariableReader receiver, VariableReader value, final ValueType type) {
|
public void isInstance(VariableReader receiver, VariableReader value, final ValueType type) {
|
||||||
String className = extractClassName(type);
|
String className = extractClassName(type);
|
||||||
if (className != null) {
|
if (className != null) {
|
||||||
dependencyChecker.linkClass(className, callerStack);
|
dependencyChecker.linkClass(className, caller.getMethod(), currentLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initClass(final String className) {
|
public void initClass(final String className) {
|
||||||
dependencyChecker.linkClass(className, callerStack).initClass(callerStack);
|
dependencyChecker.linkClass(className, caller.getMethod(), currentLocation)
|
||||||
|
.initClass(caller.getMethod(), currentLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -476,8 +481,8 @@ class DependencyGraphBuilder {
|
||||||
DependencyNode valueNode = nodes[value.getIndex()];
|
DependencyNode valueNode = nodes[value.getIndex()];
|
||||||
DependencyNode receiverNode = nodes[receiver.getIndex()];
|
DependencyNode receiverNode = nodes[receiver.getIndex()];
|
||||||
valueNode.connect(receiverNode);
|
valueNode.connect(receiverNode);
|
||||||
dependencyChecker.linkMethod(new MethodReference("java.lang.NullPointerException",
|
dependencyChecker.linkMethod(new MethodReference(NullPointerException.class, "<init>", void.class),
|
||||||
"<init>", ValueType.VOID), callerStack).use();
|
caller.getMethod(), currentLocation).use();
|
||||||
currentExceptionConsumer.consume(dependencyChecker.getType("java.lang.NullPointerException"));
|
currentExceptionConsumer.consume(dependencyChecker.getType("java.lang.NullPointerException"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<MethodDependencyInfo> missingMethods;
|
|
||||||
private final Set<ClassDependencyInfo> missingClasses;
|
|
||||||
private final Set<FieldDependencyInfo> missingFields;
|
|
||||||
|
|
||||||
DependencyViolations(Collection<? extends MethodDependencyInfo> missingMethods,
|
|
||||||
Collection<? extends ClassDependencyInfo> missingClasses,
|
|
||||||
Collection<? extends FieldDependencyInfo> missingFields) {
|
|
||||||
this.missingMethods = Collections.unmodifiableSet(new HashSet<>(missingMethods));
|
|
||||||
this.missingClasses = Collections.unmodifiableSet(new HashSet<>(missingClasses));
|
|
||||||
this.missingFields = Collections.unmodifiableSet(new HashSet<>(missingFields));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<MethodDependencyInfo> getMissingMethods() {
|
|
||||||
return missingMethods;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<ClassDependencyInfo> getMissingClasses() {
|
|
||||||
return missingClasses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<FieldDependencyInfo> 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<String> items = new ArrayList<>();
|
|
||||||
Map<String, DependencyStack> 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');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -27,6 +27,4 @@ public interface FieldDependencyInfo {
|
||||||
FieldReference getReference();
|
FieldReference getReference();
|
||||||
|
|
||||||
boolean isMissing();
|
boolean isMissing();
|
||||||
|
|
||||||
DependencyStack getStack();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,4 @@ public interface MethodDependencyInfo {
|
||||||
boolean isUsed();
|
boolean isUsed();
|
||||||
|
|
||||||
boolean isMissing();
|
boolean isMissing();
|
||||||
|
|
||||||
DependencyStack getStack();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,26 +13,24 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.dependency;
|
package org.teavm.diagnostics;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.teavm.model.Diagnostics;
|
|
||||||
import org.teavm.model.InstructionLocation;
|
import org.teavm.model.InstructionLocation;
|
||||||
import org.teavm.vm.DiagnosticsProblem;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.vm.DiagnosticsProblemSeverity;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
class DependencyDiagnostics implements Diagnostics {
|
class DependencyDiagnostics implements Diagnostics {
|
||||||
private List<DiagnosticsProblem> problems = new ArrayList<>();
|
private List<Problem> problems = new ArrayList<>();
|
||||||
private List<DiagnosticsProblem> severeProblems = new ArrayList<>();
|
private List<Problem> severeProblems = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void error(InstructionLocation location, String error) {
|
public void error(MethodReference method, InstructionLocation location, String error, Object[] params) {
|
||||||
DiagnosticsProblem violation = new DiagnosticsProblem(DiagnosticsProblemSeverity.ERROR, location, error);
|
Problem violation = new Problem(ProblemSeverity.ERROR, location, error);
|
||||||
problems.add(violation);
|
problems.add(violation);
|
||||||
severeProblems.add(violation);
|
severeProblems.add(violation);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +42,7 @@ class DependencyDiagnostics implements Diagnostics {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void warning(InstructionLocation location, String error) {
|
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);
|
problems.add(violation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,11 +51,11 @@ class DependencyDiagnostics implements Diagnostics {
|
||||||
warning(null, error);
|
warning(null, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DiagnosticsProblem> getProblems() {
|
public List<Problem> getProblems() {
|
||||||
return problems;
|
return problems;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DiagnosticsProblem> getSevereProblems() {
|
public List<Problem> getSevereProblems() {
|
||||||
return severeProblems;
|
return severeProblems;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,19 +13,16 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.model;
|
package org.teavm.diagnostics;
|
||||||
|
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public interface Diagnostics {
|
public interface Diagnostics {
|
||||||
void error(InstructionLocation location, String error);
|
void error(CallLocation location, String error, Object... params);
|
||||||
|
|
||||||
void error(String error);
|
void warning(CallLocation location, String error, Object... params);
|
||||||
|
|
||||||
void warning(InstructionLocation location, String error);
|
|
||||||
|
|
||||||
void warning(String error);
|
|
||||||
}
|
}
|
|
@ -13,30 +13,33 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* 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 <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public class DiagnosticsProblem {
|
public class Problem {
|
||||||
private DiagnosticsProblemSeverity severity;
|
private ProblemSeverity severity;
|
||||||
private InstructionLocation location;
|
private CallLocation location;
|
||||||
private String text;
|
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.severity = severity;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
this.params = Arrays.copyOf(params, params.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiagnosticsProblemSeverity getSeverity() {
|
public ProblemSeverity getSeverity() {
|
||||||
return severity;
|
return severity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstructionLocation getLocation() {
|
public CallLocation getLocation() {
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,13 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.vm;
|
package org.teavm.diagnostics;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public enum DiagnosticsProblemSeverity {
|
public enum ProblemSeverity {
|
||||||
ERROR,
|
ERROR,
|
||||||
WARNING
|
WARNING
|
||||||
}
|
}
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript;
|
package org.teavm.javascript;
|
||||||
|
|
||||||
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.instructions.InvocationType;
|
import org.teavm.model.instructions.InvocationType;
|
||||||
import org.teavm.model.instructions.InvokeInstruction;
|
import org.teavm.model.instructions.InvokeInstruction;
|
||||||
|
|
57
teavm-core/src/main/java/org/teavm/model/CallLocation.java
Normal file
57
teavm-core/src/main/java/org/teavm/model/CallLocation.java
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model;
|
package org.teavm.model;
|
||||||
|
|
||||||
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Set;
|
||||||
import org.teavm.dependency.ClassDependencyInfo;
|
import org.teavm.dependency.ClassDependencyInfo;
|
||||||
import org.teavm.dependency.FieldDependencyInfo;
|
import org.teavm.dependency.FieldDependencyInfo;
|
||||||
import org.teavm.dependency.MethodDependencyInfo;
|
import org.teavm.dependency.MethodDependencyInfo;
|
||||||
|
import org.teavm.diagnostics.Problem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -32,9 +33,9 @@ public interface Violations {
|
||||||
|
|
||||||
Set<FieldDependencyInfo> getMissingFields();
|
Set<FieldDependencyInfo> getMissingFields();
|
||||||
|
|
||||||
List<DiagnosticsProblem> getDiagnosticsProblems();
|
List<Problem> getDiagnosticsProblems();
|
||||||
|
|
||||||
List<DiagnosticsProblem> getSevereDiagnosticsProblems();
|
List<Problem> getSevereDiagnosticsProblems();
|
||||||
|
|
||||||
boolean hasSevereViolations();
|
boolean hasSevereViolations();
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.jso.plugin;
|
package org.teavm.jso.plugin;
|
||||||
|
|
||||||
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.jso.plugin;
|
package org.teavm.jso.plugin;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.javascript.ni.PreserveOriginalName;
|
import org.teavm.javascript.ni.PreserveOriginalName;
|
||||||
import org.teavm.jso.*;
|
import org.teavm.jso.*;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user