Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

One step closer. Eclipse compiler to follow sbt requests.

Added code to update on the fly the delta used by the Eclipse Java compiler, so it compiles
the file requested by sbt.

It works fine for RE #1000607 on my system.
For RE #1000388, it is only part of the solution. It mostly works but sometimes sbt doesn't request the recompilation of the
dependent Java class.
(cherry picked from commit fbfffa2)
  • Loading branch information...
commit 3cbb568e77bbb36f6dd3d25330b0941eb5b10140 1 parent 11101f8
@skyluc skyluc authored
View
1  org.scala-ide.sdt.aspects/META-INF/MANIFEST.MF
@@ -24,6 +24,7 @@ Require-Bundle:
org.eclipse.jdt.debug.ui,
org.aspectj.runtime
Eclipse-SupplementBundle:
+ org.eclipse.core.resources,
org.eclipse.debug.core,
org.eclipse.jdt.core,
org.eclipse.jdt.debug.ui,
View
1  org.scala-ide.sdt.aspects/META-INF/aop.xml
@@ -16,6 +16,7 @@
<aspect name="scala.tools.eclipse.contribution.weaving.jdt.hierarchy.HierarchyAspect"/>
<aspect name="scala.tools.eclipse.contribution.weaving.jdt.indexerprovider.IndexerProviderAspect"/>
<aspect name="scala.tools.eclipse.contribution.weaving.jdt.jcompiler.MethodVerifierAspect"/>
+<aspect name="scala.tools.eclipse.contribution.weaving.jdt.jcompiler.BuildManagerAspect"/>
<aspect name="scala.tools.eclipse.contribution.weaving.jdt.launching.JavaLaunchableTesterAspect"/>
<aspect name="scala.tools.eclipse.contribution.weaving.jdt.search.SearchAspect"/>
<aspect name="scala.tools.eclipse.contribution.weaving.jdt.ui.ScalaOverrideLabelAspect"/>
View
21 org.scala-ide.sdt.aspects/src/scala/tools/eclipse/contribution/weaving/jdt/jcompiler/BuildManagerAspect.aj
@@ -0,0 +1,21 @@
+package scala.tools.eclipse.contribution.weaving.jdt.jcompiler;
+
+import org.eclipse.core.internal.events.BuildManager;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResourceDelta;
+
+@SuppressWarnings("restriction")
+public aspect BuildManagerAspect {
+
+ pointcut getDelta(BuildManager bm, IProject project):
+ execution(IResourceDelta BuildManager+.getDelta(IProject)) &&
+ args(project) &&
+ this(bm);
+
+ IResourceDelta around(BuildManager bm, IProject project):
+ getDelta(bm, project) {
+ System.out.println("[luc] getDelta() for " + project.getName());
+ return BuildManagerStore.INSTANCE.appendJavaSourceFilesToCompile(proceed(bm, project), project);
+ }
+
+}
View
54 org.scala-ide.sdt.aspects/src/scala/tools/eclipse/contribution/weaving/jdt/jcompiler/BuildManagerStore.java
@@ -0,0 +1,54 @@
+package scala.tools.eclipse.contribution.weaving.jdt.jcompiler;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+
+public class BuildManagerStore {
+
+ public static final BuildManagerStore INSTANCE= new BuildManagerStore();
+
+ private Map<IProject, File[]> projectToJavaSourceFiles= new HashMap<IProject, File[]>();
+
+ private BuildManagerStore() {
+ }
+
+ public IResourceDelta appendJavaSourceFilesToCompile(IResourceDelta delta, IProject project) {
+ if (delta == null) {
+ return delta;
+ }
+
+ File[] files= projectToJavaSourceFiles.get(project);
+ if (files == null) {
+ return delta;
+ }
+
+ // create a new delta
+ ExtendedResourceDelta newDelta= ExtendedResourceDelta.duplicate(delta);
+
+ // add the additional files
+ IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+ for (File file: files) {
+ for (IFile resource: workspaceRoot.findFilesForLocationURI(file.toURI())) {
+ newDelta.addChangedResource(resource);
+ }
+ }
+
+ return newDelta;
+ }
+
+ public void setJavaSourceFilesToCompile(File[] files, IProject project) {
+ if (files == null) {
+ projectToJavaSourceFiles.remove(project);
+ } else {
+ projectToJavaSourceFiles.put(project, files);
+ }
+ }
+
+}
View
183 ...la-ide.sdt.aspects/src/scala/tools/eclipse/contribution/weaving/jdt/jcompiler/ExtendedResourceDelta.java
@@ -0,0 +1,183 @@
+package scala.tools.eclipse.contribution.weaving.jdt.jcompiler;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.PlatformObject;
+
+public class ExtendedResourceDelta extends PlatformObject implements IResourceDelta {
+
+ private IResourceDelta wrapped;
+
+ private List<ExtendedResourceDelta> children= new ArrayList<ExtendedResourceDelta>();
+
+ private IResource resource;
+
+ private ExtendedResourceDelta(IResourceDelta resourceDelta) {
+ wrapped= resourceDelta;
+ }
+
+ private ExtendedResourceDelta(IResource resource) {
+ this.resource= resource;
+ }
+
+ @Override
+ public void accept(IResourceDeltaVisitor visitor) throws CoreException {
+ accept(visitor, IResource.NONE);
+ }
+
+ @Override
+ public void accept(IResourceDeltaVisitor visitor, boolean includePhantoms)
+ throws CoreException {
+ accept(visitor, includePhantoms ? IContainer.INCLUDE_PHANTOMS : IResource.NONE);
+ }
+
+ @Override
+ public void accept(IResourceDeltaVisitor visitor, int memberFlags)
+ throws CoreException {
+ for (IResourceDelta child: getAffectedChildren(ADDED | REMOVED | CHANGED, memberFlags)) {
+ visitor.visit(child);
+ }
+ }
+
+ @Override
+ public IResourceDelta findMember(IPath path) {
+ if (path.segmentCount() == 0)
+ return this;
+
+ // look for a child with the first segment of the path.
+ IPath fullPath= getFullPath().append(path.segment(0));
+ int nbSegments= fullPath.segmentCount();
+ for (IResourceDelta child: children) {
+ if (child.getFullPath().matchingFirstSegments(fullPath) == nbSegments) {
+ // and search in this child
+ return child.findMember(path.removeFirstSegments(1));
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public IResourceDelta[] getAffectedChildren() {
+ return getAffectedChildren(ADDED | REMOVED | CHANGED, IResource.NONE);
+ }
+
+ @Override
+ public IResourceDelta[] getAffectedChildren(int kindMask) {
+ return getAffectedChildren(kindMask, IResource.NONE);
+ }
+
+ @Override
+ public IResourceDelta[] getAffectedChildren(int kindMask, int memberFlags) {
+ List<IResourceDelta> affectedChildren= new ArrayList<IResourceDelta>();
+ if ((memberFlags & IContainer.INCLUDE_PHANTOMS) != 0) {
+ kindMask |= ADDED_PHANTOM | REMOVED_PHANTOM;
+ }
+ boolean includeHidden = (memberFlags & IContainer.INCLUDE_HIDDEN) != 0;
+ boolean includeTeamPrivateMember = (memberFlags & IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS) == 0;
+
+ for (IResourceDelta child: children) {
+ if ((kindMask & child.getKind()) != 0 && (includeHidden || !child.getResource().isHidden()) && (includeTeamPrivateMember || !child.getResource().isTeamPrivateMember())) {
+ affectedChildren.add(child);
+ }
+ }
+
+ return affectedChildren.toArray(new IResourceDelta[affectedChildren.size()]);
+ }
+
+ @Override
+ public int getFlags() {
+ if (wrapped != null)
+ return wrapped.getFlags();
+ return IResourceDelta.CONTENT;
+ }
+
+ @Override
+ public IPath getFullPath() {
+ if (wrapped != null)
+ return wrapped.getFullPath();
+ return resource.getFullPath();
+ }
+
+ @Override
+ public int getKind() {
+ if (wrapped != null)
+ return wrapped.getKind();
+ return IResourceDelta.CHANGED;
+ }
+
+ @Override
+ public IMarkerDelta[] getMarkerDeltas() {
+ if (wrapped != null)
+ return wrapped.getMarkerDeltas();
+ return new IMarkerDelta[0];
+ }
+
+ @Override
+ public IPath getMovedFromPath() {
+ if (wrapped != null)
+ return wrapped.getMovedFromPath();
+ return null;
+ }
+
+ @Override
+ public IPath getMovedToPath() {
+ if (wrapped != null)
+ return wrapped.getMovedToPath();
+ return null;
+ }
+
+ @Override
+ public IPath getProjectRelativePath() {
+ if (wrapped != null)
+ return wrapped.getProjectRelativePath();
+ return resource.getFullPath().makeRelativeTo(resource.getProject().getFullPath());
+ }
+
+ @Override
+ public IResource getResource() {
+ if (wrapped != null)
+ return wrapped.getResource();
+ return resource;
+ }
+
+ public void addChangedResource(IResource changedResource) {
+ getOrAddResource(changedResource);
+ }
+
+ private ExtendedResourceDelta getOrAddResource(IResource newResource) {
+ if (getResource().equals(newResource)) {
+ return this;
+ }
+ ExtendedResourceDelta parentResourceDelta= getOrAddResource(newResource.getParent());
+ for (ExtendedResourceDelta childResourceDelta: parentResourceDelta.children) {
+ if (childResourceDelta.getResource().equals(newResource)) {
+ return childResourceDelta;
+ }
+ }
+ ExtendedResourceDelta newResourceDelta= new ExtendedResourceDelta(newResource);
+ parentResourceDelta.children.add(newResourceDelta);
+ return newResourceDelta;
+ }
+
+ public static ExtendedResourceDelta duplicate(IResourceDelta original) {
+ ExtendedResourceDelta newDelta = new ExtendedResourceDelta(original);
+ for (IResourceDelta child: original.getAffectedChildren(ALL_WITH_PHANTOMS, IContainer.INCLUDE_HIDDEN | IContainer.INCLUDE_PHANTOMS | IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS)) {
+ newDelta.children.add(duplicate(child));
+ }
+ return newDelta;
+ }
+
+
+ @Override
+ public String toString() {
+ return "ExtendedResourceDelta(" + getFullPath() + ")";
+ }
+}
View
6 org.scala-ide.sdt.core/src/scala/tools/eclipse/buildmanager/sbtintegration/AnalysisCompile.scala
@@ -23,6 +23,7 @@ import java.io.File
import org.eclipse.jdt.launching.JavaRuntime
import org.eclipse.jdt.core.{ JavaCore, IJavaProject }
import scala.tools.eclipse.util.HasLogger
+import scala.tools.eclipse.contribution.weaving.jdt.jcompiler.BuildManagerStore
class AnalysisCompile (conf: BasicConfiguration, bm: EclipseSbtBuildManager, contr: Controller) extends HasLogger {
import AnalysisFormats._
@@ -130,7 +131,6 @@ class AnalysisCompile (conf: BasicConfiguration, bm: EclipseSbtBuildManager, con
if(!javaSrcs.isEmpty) {
import sbt.Path._
val loader = ClasspathUtilities.toLoader(conf.classpath, scalac.scalaInstance.loader)
-
def handleError(e: Throwable) {
logger.debug("Error running the SBT builder on Java sources:\n " + e)
logger.debug("Running a full Java build")
@@ -141,10 +141,14 @@ class AnalysisCompile (conf: BasicConfiguration, bm: EclipseSbtBuildManager, con
try {
def readAPI(source: File, classes: Seq[Class[_]]) { callback.api(source, sbt.ClassToAPI(classes)) }
+ BuildManagerStore.INSTANCE.setJavaSourceFilesToCompile(javaSrcs.toArray, conf.project.underlying)
+
sbt.classfile.Analyze(conf.outputDirectories, javaSrcs, log)(callback, loader, readAPI) {
javac.build(org.eclipse.core.resources.IncrementalProjectBuilder.INCREMENTAL_BUILD)
log.flush()
}
+
+ BuildManagerStore.INSTANCE.setJavaSourceFilesToCompile(null, conf.project.underlying)
} catch {
case e: Throwable =>
handleError(e)
Please sign in to comment.
Something went wrong with that request. Please try again.