mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Further work on diagnostics API
This commit is contained in:
parent
30781bb16e
commit
0945c27f16
|
@ -15,9 +15,8 @@
|
|||
*/
|
||||
package org.teavm.dependency;
|
||||
|
||||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.InstructionLocation;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -48,9 +47,9 @@ public class ClassDependency implements ClassDependencyInfo {
|
|||
return classReader;
|
||||
}
|
||||
|
||||
public void initClass(MethodReference caller, InstructionLocation location) {
|
||||
public void initClass(CallLocation callLocation) {
|
||||
if (!isMissing()) {
|
||||
checker.initClass(this, caller, location);
|
||||
checker.initClass(this, callLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,11 +32,11 @@ public interface DependencyAgent extends DependencyInfo, ServiceRepository {
|
|||
|
||||
void submitClass(ClassHolder cls);
|
||||
|
||||
MethodDependency linkMethod(MethodReference methodRef, MethodReference caller, InstructionLocation location);
|
||||
MethodDependency linkMethod(MethodReference methodRef, CallLocation callLocation);
|
||||
|
||||
ClassDependency linkClass(String className, MethodReference caller, InstructionLocation location);
|
||||
ClassDependency linkClass(String className, CallLocation callLocation);
|
||||
|
||||
FieldDependency linkField(FieldReference fieldRef, MethodReference caller, InstructionLocation location);
|
||||
FieldDependency linkField(FieldReference fieldRef, CallLocation callLocation);
|
||||
|
||||
Diagnostics getDiagnostics();
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
|||
Set<FieldDependency> missingFields = new HashSet<>();
|
||||
List<DependencyType> types = new ArrayList<>();
|
||||
Map<String, DependencyType> typeMap = new HashMap<>();
|
||||
private DependencyViolations dependencyViolations;
|
||||
private DependencyCheckerInterruptor interruptor;
|
||||
private boolean interrupted;
|
||||
private Diagnostics diagnostics;
|
||||
|
@ -188,7 +187,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, null, null);
|
||||
MethodDependency method = linkMethod(methodRef, null);
|
||||
method.use();
|
||||
DependencyNode[] varNodes = method.getVariables();
|
||||
varNodes[0].propagate(getType(methodRef.getClassName()));
|
||||
|
@ -216,11 +215,11 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ClassDependency linkClass(String className, DependencyStack stack) {
|
||||
public ClassDependency linkClass(String className, CallLocation callLocation) {
|
||||
return classCache.map(className);
|
||||
}
|
||||
|
||||
private ClassDependency createClassDependency(String className, DependencyStack stack) {
|
||||
private ClassDependency createClassDependency(String className, CallLocation callLocation) {
|
||||
ClassReader cls = classSource.get(className);
|
||||
ClassDependency dependency = new ClassDependency(this, className, stack, cls);
|
||||
if (dependency.isMissing()) {
|
||||
|
@ -237,26 +236,25 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
|||
}
|
||||
|
||||
@Override
|
||||
public MethodDependency linkMethod(MethodReference methodRef, MethodReference caller,
|
||||
InstructionLocation location) {
|
||||
public MethodDependency linkMethod(MethodReference methodRef, CallLocation callLocation) {
|
||||
if (methodRef == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
callGraph.addNode(methodRef);
|
||||
if (caller != null) {
|
||||
callGraph.getNode(methodRef);
|
||||
if (callLocation != null) {
|
||||
callGraph.addNode(caller);
|
||||
callGraph.getNode(caller).addCallSite(methodRef, location);
|
||||
}
|
||||
return methodCache.map(methodRef);
|
||||
}
|
||||
|
||||
void initClass(ClassDependency cls, final MethodReference caller, final InstructionLocation location) {
|
||||
void initClass(ClassDependency cls, final CallLocation callLocation) {
|
||||
ClassReader reader = cls.getClassReader();
|
||||
final MethodReader method = reader.getMethod(new MethodDescriptor("<clinit>", void.class));
|
||||
if (method != null) {
|
||||
tasks.add(new Runnable() {
|
||||
@Override public void run() {
|
||||
linkMethod(method.getReference(), caller, location).use();
|
||||
linkMethod(method.getReference(), callLocation).use();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -17,38 +17,27 @@ package org.teavm.diagnostics;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.teavm.model.InstructionLocation;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.CallLocation;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
class DependencyDiagnostics implements Diagnostics {
|
||||
public class AccumulationDiagnostics implements Diagnostics {
|
||||
private List<Problem> problems = new ArrayList<>();
|
||||
private List<Problem> severeProblems = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
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);
|
||||
public void error(CallLocation location, String error, Object... params) {
|
||||
Problem problem = new Problem(ProblemSeverity.ERROR, location, error, params);
|
||||
problems.add(problem);
|
||||
severeProblems.add(problem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String error) {
|
||||
error(null, error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warning(InstructionLocation location, String error) {
|
||||
Problem violation = new Problem(ProblemSeverity.WARNING, location, error);
|
||||
problems.add(violation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warning(String error) {
|
||||
warning(null, error);
|
||||
public void warning(CallLocation location, String error, Object... params) {
|
||||
Problem problem = new Problem(ProblemSeverity.ERROR, location, error, params);
|
||||
problems.add(problem);
|
||||
}
|
||||
|
||||
public List<Problem> getProblems() {
|
|
@ -46,4 +46,8 @@ public class Problem {
|
|||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public Object[] getParams() {
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.teavm.cache.DiskRegularMethodNodeCache;
|
|||
import org.teavm.cache.FileSymbolTable;
|
||||
import org.teavm.debugging.information.DebugInformation;
|
||||
import org.teavm.debugging.information.DebugInformationBuilder;
|
||||
import org.teavm.dependency.DependencyViolations;
|
||||
import org.teavm.javascript.RenderingContext;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.parsing.ClasspathClassHolderSource;
|
||||
|
@ -345,10 +344,6 @@ public class TeaVMTool {
|
|||
}
|
||||
}
|
||||
|
||||
public DependencyViolations getViolations() {
|
||||
return vm.getViolations();
|
||||
}
|
||||
|
||||
public void checkForMissingItems() {
|
||||
vm.checkForViolations();
|
||||
}
|
||||
|
@ -366,7 +361,6 @@ public class TeaVMTool {
|
|||
private AbstractRendererListener runtimeInjector = new AbstractRendererListener() {
|
||||
@Override
|
||||
public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException {
|
||||
@SuppressWarnings("resource")
|
||||
StringWriter writer = new StringWriter();
|
||||
resourceToWriter("org/teavm/javascript/runtime.js", writer);
|
||||
writer.close();
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.teavm.common.ServiceRepository;
|
|||
import org.teavm.debugging.information.DebugInformationEmitter;
|
||||
import org.teavm.debugging.information.SourceLocation;
|
||||
import org.teavm.dependency.*;
|
||||
import org.teavm.diagnostics.AccumulationDiagnostics;
|
||||
import org.teavm.javascript.*;
|
||||
import org.teavm.javascript.ast.ClassNode;
|
||||
import org.teavm.javascript.ni.Generator;
|
||||
|
@ -68,6 +69,7 @@ import org.teavm.vm.spi.TeaVMPlugin;
|
|||
public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||
private ClassReaderSource classSource;
|
||||
private DependencyChecker dependencyChecker;
|
||||
private AccumulationDiagnostics diagnostics = new AccumulationDiagnostics();
|
||||
private ClassLoader classLoader;
|
||||
private boolean minifying = true;
|
||||
private boolean bytecodeLogging;
|
||||
|
@ -90,7 +92,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
TeaVM(ClassReaderSource classSource, ClassLoader classLoader) {
|
||||
this.classSource = classSource;
|
||||
this.classLoader = classLoader;
|
||||
dependencyChecker = new DependencyChecker(this.classSource, classLoader, this);
|
||||
dependencyChecker = new DependencyChecker(this.classSource, classLoader, this, diagnostics);
|
||||
progressListener = new TeaVMProgressListener() {
|
||||
@Override public TeaVMProgressFeedback progressReached(int progress) {
|
||||
return TeaVMProgressFeedback.CONTINUE;
|
||||
|
@ -232,9 +234,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
"for method " + ref);
|
||||
}
|
||||
}
|
||||
TeaVMEntryPoint entryPoint = new TeaVMEntryPoint(name, ref,
|
||||
dependencyChecker.linkMethod(ref, DependencyStack.ROOT));
|
||||
dependencyChecker.linkClass(ref.getClassName(), DependencyStack.ROOT).initClass(DependencyStack.ROOT);
|
||||
TeaVMEntryPoint entryPoint = new TeaVMEntryPoint(name, ref, dependencyChecker.linkMethod(ref, null));
|
||||
dependencyChecker.linkClass(ref.getClassName(), null).initClass(null);
|
||||
if (name != null) {
|
||||
entryPoints.put(name, entryPoint);
|
||||
}
|
||||
|
@ -258,9 +259,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
}
|
||||
|
||||
public TeaVMEntryPoint linkMethod(MethodReference ref) {
|
||||
TeaVMEntryPoint entryPoint = new TeaVMEntryPoint("", ref,
|
||||
dependencyChecker.linkMethod(ref, DependencyStack.ROOT));
|
||||
dependencyChecker.linkClass(ref.getClassName(), DependencyStack.ROOT).initClass(DependencyStack.ROOT);
|
||||
TeaVMEntryPoint entryPoint = new TeaVMEntryPoint("", ref, dependencyChecker.linkMethod(ref, null));
|
||||
dependencyChecker.linkClass(ref.getClassName(), null).initClass(null);
|
||||
return entryPoint;
|
||||
}
|
||||
|
||||
|
@ -269,12 +269,12 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
throw new IllegalArgumentException("Class with public name `" + name + "' already defined for class " +
|
||||
className);
|
||||
}
|
||||
dependencyChecker.linkClass(className, DependencyStack.ROOT).initClass(DependencyStack.ROOT);
|
||||
dependencyChecker.linkClass(className, null).initClass(null);
|
||||
exportedClasses.put(name, className);
|
||||
}
|
||||
|
||||
public void linkType(String className) {
|
||||
dependencyChecker.linkClass(className, DependencyStack.ROOT).initClass(DependencyStack.ROOT);
|
||||
dependencyChecker.linkClass(className, null).initClass(null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -285,30 +285,6 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
return classSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>After building indicates whether build has failed due to some missing items (classes, methods and fields)
|
||||
* in the classpath. This can happen when you forgot some items in class path or when your code uses unimplemented
|
||||
* Java class library methods. The behavior of this method before building is not specified.</p>
|
||||
*/
|
||||
public boolean hasMissingItems() {
|
||||
return dependencyChecker.hasViolations();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>After building allows to build report on all items (classes, methods, fields) that are missing.
|
||||
* This can happen when you forgot some items in class path or when your code uses unimplemented
|
||||
* Java class library methods. The behavior of this method before building is not specified.</p>
|
||||
*
|
||||
* @param target where to append all dependency diagnostics errors.
|
||||
*/
|
||||
public void showMissingItems(Appendable target) throws IOException {
|
||||
dependencyChecker.showViolations(target);
|
||||
}
|
||||
|
||||
public DependencyViolations getViolations() {
|
||||
return dependencyChecker.getViolations();
|
||||
}
|
||||
|
||||
public Collection<String> getClasses() {
|
||||
return dependencyChecker.getAchievableClasses();
|
||||
}
|
||||
|
@ -321,16 +297,6 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
return writtenClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>After building checks whether the build has failed due to some missing items (classes, methods and fields).
|
||||
* If it has failed, throws exception, containing report on all missing items.
|
||||
* This can happen when you forgot some items in class path or when your code uses unimplemented
|
||||
* Java class library methods. The behavior of this method before building is not specified.</p>
|
||||
*/
|
||||
public void checkForViolations() {
|
||||
dependencyChecker.checkForViolations();
|
||||
}
|
||||
|
||||
public DebugInformationEmitter getDebugEmitter() {
|
||||
return debugEmitter;
|
||||
}
|
||||
|
@ -362,22 +328,19 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
return progressListener.progressReached(0) == TeaVMProgressFeedback.CONTINUE;
|
||||
}
|
||||
});
|
||||
dependencyChecker.linkMethod(new MethodReference(Class.class, "createNew", Class.class),
|
||||
DependencyStack.ROOT).use();
|
||||
dependencyChecker.linkMethod(new MethodReference(Class.class, "createNew", Class.class), null).use();
|
||||
dependencyChecker.linkMethod(new MethodReference(String.class, "<init>", char[].class, void.class),
|
||||
DependencyStack.ROOT).use();
|
||||
null).use();
|
||||
dependencyChecker.linkMethod(new MethodReference(String.class, "getChars", int.class, int.class, char[].class,
|
||||
int.class, void.class), DependencyStack.ROOT).use();
|
||||
int.class, void.class), null).use();
|
||||
MethodDependency internDep = dependencyChecker.linkMethod(new MethodReference(String.class, "intern",
|
||||
String.class), DependencyStack.ROOT);
|
||||
String.class), null);
|
||||
internDep.getVariable(0).propagate(dependencyChecker.getType("java.lang.String"));
|
||||
internDep.use();
|
||||
dependencyChecker.linkMethod(new MethodReference(String.class, "length", int.class),
|
||||
DependencyStack.ROOT).use();
|
||||
dependencyChecker.linkMethod(new MethodReference(Object.class, "clone", Object.class),
|
||||
DependencyStack.ROOT).use();
|
||||
dependencyChecker.linkMethod(new MethodReference(String.class, "length", int.class), null).use();
|
||||
dependencyChecker.linkMethod(new MethodReference(Object.class, "clone", Object.class), null).use();
|
||||
dependencyChecker.processDependencies();
|
||||
if (wasCancelled() || hasMissingItems()) {
|
||||
if (wasCancelled() || !diagnostics.getSevereProblems().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user