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 c3ff7e859..3e184f914 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/ClassDependency.java +++ b/teavm-core/src/main/java/org/teavm/dependency/ClassDependency.java @@ -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); } } } 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 4862610b8..439c6697f 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java @@ -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(); } 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 1e43dad3a..2eec87d73 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -47,7 +47,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { Set missingFields = new HashSet<>(); List types = new ArrayList<>(); Map 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("", void.class)); if (method != null) { tasks.add(new Runnable() { @Override public void run() { - linkMethod(method.getReference(), caller, location).use(); + linkMethod(method.getReference(), callLocation).use(); } }); } diff --git a/teavm-core/src/main/java/org/teavm/diagnostics/DependencyDiagnostics.java b/teavm-core/src/main/java/org/teavm/diagnostics/AccumulationDiagnostics.java similarity index 58% rename from teavm-core/src/main/java/org/teavm/diagnostics/DependencyDiagnostics.java rename to teavm-core/src/main/java/org/teavm/diagnostics/AccumulationDiagnostics.java index 08d666ddc..414bdf326 100644 --- a/teavm-core/src/main/java/org/teavm/diagnostics/DependencyDiagnostics.java +++ b/teavm-core/src/main/java/org/teavm/diagnostics/AccumulationDiagnostics.java @@ -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 */ -class DependencyDiagnostics implements Diagnostics { +public class AccumulationDiagnostics implements Diagnostics { private List problems = new ArrayList<>(); private List 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 getProblems() { diff --git a/teavm-core/src/main/java/org/teavm/diagnostics/Problem.java b/teavm-core/src/main/java/org/teavm/diagnostics/Problem.java index b7d0eeec4..1bab7cfd0 100644 --- a/teavm-core/src/main/java/org/teavm/diagnostics/Problem.java +++ b/teavm-core/src/main/java/org/teavm/diagnostics/Problem.java @@ -46,4 +46,8 @@ public class Problem { public String getText() { return text; } + + public Object[] getParams() { + return params; + } } diff --git a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java index 979346193..8f60bcde2 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java +++ b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java @@ -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(); diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java index a2479e3a4..e065820ca 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java @@ -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; } - /** - *

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.

- */ - public boolean hasMissingItems() { - return dependencyChecker.hasViolations(); - } - - /** - *

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.

- * - * @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 getClasses() { return dependencyChecker.getAchievableClasses(); } @@ -321,16 +297,6 @@ public class TeaVM implements TeaVMHost, ServiceRepository { return writtenClasses; } - /** - *

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.

- */ - 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, "", 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; }