From 7632c0910ad79f5dfef0dbfc73691d535c44d62a Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 10 Oct 2011 20:53:57 -0400 Subject: [PATCH] fixes #220. properly record source dependencies from separate compilation runs in the same step. --- compile/inc/Compile.scala | 44 +++++++++++++------ .../source-dependencies/java-mixed/JJ.java | 5 +++ .../source-dependencies/java-mixed/build.sbt | 1 + .../java-mixed/changes/S1.scala | 3 ++ .../java-mixed/changes/S2.scala | 3 ++ .../java-mixed/changes/build.sbt | 1 + .../source-dependencies/java-mixed/test | 13 ++++++ 7 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 sbt/src/sbt-test/source-dependencies/java-mixed/JJ.java create mode 100644 sbt/src/sbt-test/source-dependencies/java-mixed/build.sbt create mode 100644 sbt/src/sbt-test/source-dependencies/java-mixed/changes/S1.scala create mode 100644 sbt/src/sbt-test/source-dependencies/java-mixed/changes/S2.scala create mode 100644 sbt/src/sbt-test/source-dependencies/java-mixed/changes/build.sbt create mode 100644 sbt/src/sbt-test/source-dependencies/java-mixed/test diff --git a/compile/inc/Compile.scala b/compile/inc/Compile.scala index 59861c758..02bf7ddc3 100644 --- a/compile/inc/Compile.scala +++ b/compile/inc/Compile.scala @@ -43,12 +43,15 @@ private final class AnalysisCallback(internalMap: File => Option[File], external import collection.mutable.{HashMap, HashSet, ListBuffer, Map, Set} - private val apis = new HashMap[File, (Int, SourceAPI)] - private val binaryDeps = new HashMap[File, Set[File]] - private val classes = new HashMap[File, Set[(File, String)]] - private val sourceDeps = new HashMap[File, Set[File]] - private val extSrcDeps = new ListBuffer[(File, String, Source)] - private val binaryClassName = new HashMap[File, String] + private[this] val apis = new HashMap[File, (Int, SourceAPI)] + private[this] val binaryDeps = new HashMap[File, Set[File]] + // source file to set of generated (class file, class name) + private[this] val classes = new HashMap[File, Set[(File, String)]] + // generated class file to its source file + private[this] val classToSource = new HashMap[File, File] + private[this] val sourceDeps = new HashMap[File, Set[File]] + private[this] val extSrcDeps = new ListBuffer[(File, String, Source)] + private[this] val binaryClassName = new HashMap[File, String] private def add[A,B](map: Map[A,Set[B]], a: A, b: B): Unit = map.getOrElseUpdate(a, new HashSet[B]) += b @@ -68,18 +71,33 @@ private final class AnalysisCallback(internalMap: File => Option[File], external // dependency is a product of a source not included in this compilation sourceDependency(dependsOn, source) case None => - externalAPI(classFile, name) match + classToSource.get(classFile) match { - case Some(api) => - // dependency is a product of a source in another project - externalSourceDependency( (source, name, api) ) + case Some(dependsOn) => + // dependency is a product of a source in this compilation step, + // but not in the same compiler run (as in javac v. scalac) + sourceDependency(dependsOn, source) case None => - // dependency is some other binary on the classpath - externalBinaryDependency(classFile, name, source) + externalDependency(classFile, name, source) } } + + private[this] def externalDependency(classFile: File, name: String, source: File): Unit = + externalAPI(classFile, name) match + { + case Some(api) => + // dependency is a product of a source in another project + externalSourceDependency( (source, name, api) ) + case None => + // dependency is some other binary on the classpath + externalBinaryDependency(classFile, name, source) + } - def generatedClass(source: File, module: File, name: String) = add(classes, source, (module, name)) + def generatedClass(source: File, module: File, name: String) = + { + add(classes, source, (module, name)) + classToSource.put(module, source) + } def api(sourceFile: File, source: SourceAPI) { apis(sourceFile) = (xsbt.api.HashAPI(source), xsbt.api.APIUtil.minimize(source)) } def endSource(sourcePath: File): Unit = diff --git a/sbt/src/sbt-test/source-dependencies/java-mixed/JJ.java b/sbt/src/sbt-test/source-dependencies/java-mixed/JJ.java new file mode 100644 index 000000000..18d52ae30 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/java-mixed/JJ.java @@ -0,0 +1,5 @@ +public class JJ { + public static void main(String[] args) { + new S().foo("ahoy"); + } +} diff --git a/sbt/src/sbt-test/source-dependencies/java-mixed/build.sbt b/sbt/src/sbt-test/source-dependencies/java-mixed/build.sbt new file mode 100644 index 000000000..522224a38 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/java-mixed/build.sbt @@ -0,0 +1 @@ +compileOrder := CompileOrder.Mixed \ No newline at end of file diff --git a/sbt/src/sbt-test/source-dependencies/java-mixed/changes/S1.scala b/sbt/src/sbt-test/source-dependencies/java-mixed/changes/S1.scala new file mode 100644 index 000000000..42beb8cd6 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/java-mixed/changes/S1.scala @@ -0,0 +1,3 @@ +class S { + def foo(s:String) { println("I am foo") } +} diff --git a/sbt/src/sbt-test/source-dependencies/java-mixed/changes/S2.scala b/sbt/src/sbt-test/source-dependencies/java-mixed/changes/S2.scala new file mode 100644 index 000000000..88fd161b7 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/java-mixed/changes/S2.scala @@ -0,0 +1,3 @@ +class S { + def foo2(s:String) { println("I am foo") } +} diff --git a/sbt/src/sbt-test/source-dependencies/java-mixed/changes/build.sbt b/sbt/src/sbt-test/source-dependencies/java-mixed/changes/build.sbt new file mode 100644 index 000000000..f4f9b5bf7 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/java-mixed/changes/build.sbt @@ -0,0 +1 @@ +compileOrder := CompileOrder.ScalaThenJava \ No newline at end of file diff --git a/sbt/src/sbt-test/source-dependencies/java-mixed/test b/sbt/src/sbt-test/source-dependencies/java-mixed/test new file mode 100644 index 000000000..60402f1e6 --- /dev/null +++ b/sbt/src/sbt-test/source-dependencies/java-mixed/test @@ -0,0 +1,13 @@ +$ copy-file changes/S1.scala S.scala +> compile +$ copy-file changes/S2.scala S.scala +-> compile + +> clean +$ copy-file changes/build.sbt build.sbt +> reload + +$ copy-file changes/S1.scala S.scala +> compile +$ copy-file changes/S2.scala S.scala +-> compile