From f204c8cc4aa4065b56356664a1ac3d6b421448d2 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Mon, 15 Sep 2014 21:21:25 +0400 Subject: [PATCH] Add markers against lines that contain missing elements --- .../teavm/dependency/DependencyChecker.java | 2 +- teavm-eclipse/teavm-eclipse-plugin/plugin.xml | 8 ++ .../java/org/teavm/eclipse/TeaVMBuilder.java | 102 ++++++++++++++++-- .../org/teavm/eclipse/TeaVMEclipsePlugin.java | 1 + 4 files changed, 104 insertions(+), 9 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java index ae2599d6d..290ab1553 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -235,7 +235,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { if (method != null) { tasks.add(new Runnable() { @Override public void run() { - linkMethod(method.getReference(), stack); + linkMethod(method.getReference(), stack).use(); } }); } diff --git a/teavm-eclipse/teavm-eclipse-plugin/plugin.xml b/teavm-eclipse/teavm-eclipse-plugin/plugin.xml index d32f9e4f1..71240220b 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/plugin.xml +++ b/teavm-eclipse/teavm-eclipse-plugin/plugin.xml @@ -67,4 +67,12 @@ + + + + + + + + diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMBuilder.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMBuilder.java index d4736087f..b8bcc1d0f 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMBuilder.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMBuilder.java @@ -10,9 +10,10 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.variables.VariablesPlugin; -import org.eclipse.jdt.core.IClasspathEntry; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.*; +import org.teavm.dependency.*; +import org.teavm.model.InstructionLocation; +import org.teavm.model.MethodReference; import org.teavm.tooling.RuntimeCopyOperation; import org.teavm.tooling.TeaVMTool; import org.teavm.tooling.TeaVMToolException; @@ -22,6 +23,9 @@ import org.teavm.tooling.TeaVMToolException; * @author Alexey Andreev */ public class TeaVMBuilder extends IncrementalProjectBuilder { + private URL[] classPath; + private IContainer[] sourceContainers; + @Override protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { TeaVMProjectSettings projectSettings = getProjectSettings(); @@ -39,28 +43,93 @@ public class TeaVMBuilder extends IncrementalProjectBuilder { tool.setProgressListener(new TeaVMEclipseProgressListener(monitor)); try { tool.generate(); - tool.checkForMissingItems(); + removeMarkers(); + if (tool.getDependencyViolations().hasMissingItems()) { + putMarkers(tool.getDependencyViolations()); + } } catch (TeaVMToolException e) { throw new CoreException(TeaVMEclipsePlugin.makeError(e)); } return null; } + private void removeMarkers() throws CoreException { + getProject().deleteMarkers(TeaVMEclipsePlugin.DEPENDENCY_MARKER_ID, true, IResource.DEPTH_INFINITE); + } + + private void putMarkers(DependencyViolations violations) throws CoreException { + for (ClassDependencyInfo dep : violations.getMissingClasses()) { + putMarker("Missing class " + dep.getClassName(), dep.getStack()); + } + for (FieldDependencyInfo dep : violations.getMissingFields()) { + putMarker("Missing field " + dep.getReference().toString(), dep.getStack()); + } + for (MethodDependencyInfo dep : violations.getMissingMethods()) { + putMarker("Missing method " + dep.getReference().toString(), dep.getStack()); + } + } + + private void putMarker(String message, DependencyStack stack) throws CoreException { + while (stack != DependencyStack.ROOT) { + putMarker(message, stack.getLocation(), stack.getMethod()); + stack = stack.getCause(); + } + } + + private void putMarker(String message, InstructionLocation location, MethodReference methodRef) + throws CoreException { + IResource resource = null; + if (location != null) { + String resourceName = location.getFileName(); + for (IContainer container : sourceContainers) { + resource = container.findMember(resourceName); + if (resource != null) { + break; + } + } + } + if (resource == null) { + String resourceName = methodRef.getClassName().replace('.', '/') + ".java"; + for (IContainer container : sourceContainers) { + resource = container.findMember(resourceName); + if (resource != null) { + break; + } + } + } + if (resource != null) { + IMarker marker = resource.createMarker(TeaVMEclipsePlugin.DEPENDENCY_MARKER_ID); + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + marker.setAttribute(IMarker.MESSAGE, message); + if (location != null) { + marker.setAttribute(IMarker.LINE_NUMBER, location.getLine()); + } else { + ICompilationUnit unit = (ICompilationUnit)JavaCore.create(resource); + IType type = unit.getType(methodRef.getClassName()); + // TODO: find method declaration location and put marker there + } + } + } + private TeaVMProjectSettings getProjectSettings() { return TeaVMEclipsePlugin.getDefault().getSettings(getProject()); } private ClassLoader prepareClassLoader() throws CoreException { - return new URLClassLoader(prepareClassPath(), Thread.currentThread().getContextClassLoader()); + prepareClassPath(); + return new URLClassLoader(classPath, TeaVMBuilder.class.getClassLoader()); } - private URL[] prepareClassPath() throws CoreException { + private void prepareClassPath() throws CoreException { + classPath = new URL[0]; + sourceContainers = new IContainer[0]; IProject project = getProject(); if (!project.hasNature(JavaCore.NATURE_ID)) { - return new URL[0]; + return; } IJavaProject javaProject = JavaCore.create(project); PathCollector collector = new PathCollector(); + SourcePathCollector srcCollector = new SourcePathCollector(); IWorkspaceRoot workspaceRoot = project.getWorkspace().getRoot(); try { collector.addPath(workspaceRoot.findMember(javaProject.getOutputLocation()).getLocation()); @@ -85,6 +154,7 @@ public class TeaVMBuilder extends IncrementalProjectBuilder { TeaVMEclipsePlugin.logError(e); } } + srcCollector.addContainer((IContainer)workspaceRoot.findMember(entry.getPath())); break; case IClasspathEntry.CPE_PROJECT: { IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(entry.getPath()); @@ -105,7 +175,8 @@ public class TeaVMBuilder extends IncrementalProjectBuilder { } } } - return collector.getUrls(); + classPath = collector.getUrls(); + sourceContainers = srcCollector.getContainers(); } static class PathCollector { @@ -132,4 +203,19 @@ public class TeaVMBuilder extends IncrementalProjectBuilder { return urls.toArray(new URL[urls.size()]); } } + + static class SourcePathCollector { + private Set containerSet = new HashSet<>(); + private List containers = new ArrayList<>(); + + public void addContainer(IContainer container) { + if (containerSet.add(container)) { + containers.add(container); + } + } + + public IContainer[] getContainers() { + return containers.toArray(new IContainer[containers.size()]); + } + } } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java index 784d9ed61..ed6248803 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java @@ -38,6 +38,7 @@ public class TeaVMEclipsePlugin extends AbstractUIPlugin { public static final String NATURE_ID = ID + ".nature"; public static final String BUILDER_ID = ID + ".builder"; public static final String MAIN_METHOD_DIALOG_ID = ID + ".dialogs.mainMethod"; + public static final String DEPENDENCY_MARKER_ID = ID + ".dependencyMarker"; private static TeaVMEclipsePlugin defaultInstance; private ConcurrentMap settingsMap = new ConcurrentHashMap<>();