Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix #1001394 Ignore source classpath entries that don't exist physica…

…lly in the workspace.

m2e routinely adds optional CPEs for src/main/java, src/test/java even when
the directories are missing. SBT builder is not aware that they are optional
and aborts compilation.
  • Loading branch information...
commit 0d7872a744cc89814d5db1b5c2f0b6c26bd15b48 1 parent eb61d7f
@rkrzewski rkrzewski authored
View
62 org.scala-ide.sdt.core.tests/src/scala/tools/eclipse/sbtbuilder/OutputFoldersTest.scala
@@ -2,8 +2,11 @@ package scala.tools.eclipse.sbtbuilder
import org.junit.Test
import scala.tools.eclipse.EclipseUserSimulator
import org.junit.Assert
+import org.eclipse.core.resources.IFolder
+import org.eclipse.core.resources.IContainer
import org.eclipse.core.runtime.Path
import org.eclipse.jdt.core.JavaCore
+import org.eclipse.jdt.core.IClasspathEntry
import org.eclipse.core.runtime.IPath
import scala.tools.eclipse.ScalaProject
import scala.tools.eclipse.testsetup.SDTTestUtils
@@ -55,19 +58,72 @@ class OutputFoldersTest {
}
+ @Test def missingSourceDirectory() {
+ val projectName = "missingSources"
+ val srcMain = new Path("/" +projectName + "/src/main/scala")
+ val targetMain = new Path("/" +projectName + "/target/classes")
+ val srcTest = new Path("/" +projectName + "/src/test/scala")
+ val targetTest = new Path("/" +projectName + "/target/test-classes")
+
+ val project = makeDefaultLayoutProject(projectName)
+
+ project.underlying.getWorkspace().getRoot().getFolder(srcTest).delete(true, null)
+
+ // both source directories are defined in Eclipse classpath ...
+ val cpes = project.javaProject.getResolvedClasspath(true)
+ val srcEntryPaths = cpes.filter(_.getEntryKind == IClasspathEntry.CPE_SOURCE).map(_.getPath)
+
+ Assert.assertEquals("Source CPEs", Seq(srcMain, srcTest), srcEntryPaths.toSeq)
+
+ // ... but only the one that exists in the workspace is passed to Scala compiler classpath
+ val sourcesOutputs = project.sourceOutputFolders
+
+ val sources = sourcesOutputs.map(_._1.getFullPath())
+ val outputs = sourcesOutputs.map(_._2.getFullPath())
+
+ Assert.assertEquals("Sources", Seq(srcMain), sources)
+ Assert.assertEquals("Outputs", Seq(targetMain), outputs)
+ }
+
+
/** Create a project with the specified source folders, inclusion and exclusion patterns */
private def makeProject(name: String, sourceFolders: (IPath, Array[IPath], Array[IPath], IPath)*): ScalaProject = {
val project = simulator.createProjectInWorkspace(name, sourceFolders.isEmpty)
- val srcEntries =
- for ((dirPath, inclPats, exclPats, binPath) <- sourceFolders)
- yield JavaCore.newSourceEntry(dirPath, inclPats, exclPats, binPath)
+ val srcEntries =
+ for ((dirPath, inclPats, exclPats, binPath) <- sourceFolders) yield {
+ for (path <- Seq(Some(dirPath), Option(binPath)))
+ path match {
+ case Some(path) => ensureFolderExists(project.underlying, path)
+ case None =>
+ }
+
+ JavaCore.newSourceEntry(dirPath, inclPats, exclPats, binPath)
+ }
project.javaProject.setRawClasspath((project.javaProject.getRawClasspath() ++ srcEntries).toArray, null);
project
}
+
+ /** Ensure that given folder exists in Eclipse workspace */
+ private def ensureFolderExists(top: IContainer, path: IPath) {
+ def ensureFolderExists(container: IContainer, segments: List[String]): IFolder = {
+ val folder = segments match {
+ case segment :: Nil =>
+ container.getFolder(segment)
+ case segment :: rest =>
+ ensureFolderExists(container, rest).getFolder(segment)
+ }
+ if (!folder.exists())
+ folder.create(false, true, null)
+ folder
+ }
+ if(path.segmentCount > 1)
+ ensureFolderExists(top, path.segments.toList.drop(1).reverse)
+ }
+
/** Create a project with src/main/scala and src/test/scala, without any source filters. */
private def makeDefaultLayoutProject(projectName: String) = {
View
14 org.scala-ide.sdt.core/src/scala/tools/eclipse/ScalaProject.scala
@@ -231,7 +231,7 @@ class ScalaProject private (val underlying: IProject) extends ClasspathManagemen
def sourceFolders: Seq[IPath] = {
for {
cpe <- javaProject.getResolvedClasspath(true) if cpe.getEntryKind == IClasspathEntry.CPE_SOURCE
- resource <- Option(plugin.workspaceRoot.findMember(cpe.getPath))
+ resource <- Option(plugin.workspaceRoot.findMember(cpe.getPath)) if resource.exists
} yield resource.getLocation
}
@@ -255,19 +255,17 @@ class ScalaProject private (val underlying: IProject) extends ClasspathManagemen
def sourceOutputFolders: Seq[(IContainer, IContainer)] = {
val cpes = javaProject.getResolvedClasspath(true)
- for (cpe <- cpes if cpe.getEntryKind == IClasspathEntry.CPE_SOURCE) yield {
+ for {
+ cpe <- cpes if cpe.getEntryKind == IClasspathEntry.CPE_SOURCE
+ source <- Option(plugin.workspaceRoot.findMember(cpe.getPath)) if source.exists
+ } yield {
val cpeOutput = cpe.getOutputLocation
val outputLocation = if (cpeOutput != null) cpeOutput else javaProject.getOutputLocation
val wsroot = plugin.workspaceRoot
val binPath = wsroot.getFolder(outputLocation) // may not exist
- val srcContainer = Option(wsroot.findMember(cpe.getPath()).asInstanceOf[IContainer]) getOrElse {
- // may be null if source folder does not exist
- logger.debug("Could not retrieve source folder %s for project %s".format(cpe.getPath(), underlying))
- wsroot.getFolder(cpe.getPath())
- }
- (srcContainer, binPath)
+ (source.asInstanceOf[IContainer], binPath)
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.