From 3b4a8067ae3c6d4abb860789ce9f42c395c20c80 Mon Sep 17 00:00:00 2001 From: Miles Sabin Date: Mon, 5 Oct 2009 16:45:40 +0000 Subject: BuildManagers weren't deleting invalidated clas... BuildManagers weren't deleting invalidated classfiles; dependency tracker was only recording the dependency of Foo$.class on the source of object Foo ... Foo.class is now also recorded; the Eclipse Java builder could copy modified Scala sources to the output folder during incremental builds. Fixes #2428. --- .../tools/nsc/dependencies/DependencyAnalysis.scala | 10 ++++++---- .../scala/tools/nsc/interactive/BuildManager.scala | 7 +++++++ .../tools/nsc/interactive/RefinedBuildManager.scala | 4 ++++ .../scala/tools/nsc/interactive/SimpleBuildManager.scala | 16 ++++++++++++++-- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala b/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala index ec1bacfd59..4b19238b7e 100644 --- a/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala +++ b/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala @@ -110,11 +110,13 @@ trait DependencyAnalysis extends SubComponent with Files { if (f != null){ val source: AbstractFile = unit.source.file; for (d <- unit.icode){ - val name = d.symbol match { - case _ : ModuleClassSymbol => d.toString+"$" - case _ => d.toString - } + val name = d.toString dependencies.emits(source, nameToFile(unit.source.file, name)) + d.symbol match { + case _ : ModuleClassSymbol => + dependencies.emits(source, nameToFile(unit.source.file, name + "$")) + case _ => + } } for (d <- unit.depends; if (d.sourceFile != null)){ diff --git a/src/compiler/scala/tools/nsc/interactive/BuildManager.scala b/src/compiler/scala/tools/nsc/interactive/BuildManager.scala index 4ecd13b01d..c269c0eace 100644 --- a/src/compiler/scala/tools/nsc/interactive/BuildManager.scala +++ b/src/compiler/scala/tools/nsc/interactive/BuildManager.scala @@ -32,6 +32,13 @@ trait BuildManager { def saveTo(file: AbstractFile, fromFile: AbstractFile => String) def compiler: scala.tools.nsc.Global + + /** Delete classfiles derived from the supplied set of sources */ + def deleteClassfiles(sources : Set[AbstractFile]) { + val targets = compiler.dependencyAnalysis.dependencies.targets + for(source <- sources; cf <- targets(source)) + cf.delete + } } diff --git a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala index cce0dc7634..9097fc02f5 100644 --- a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala +++ b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala @@ -58,6 +58,7 @@ class RefinedBuildManager(val settings: Settings) extends Changes with BuildMana /** Remove the given files from the managed build process. */ def removeFiles(files: Set[AbstractFile]) { sources --= files + deleteClassfiles(files) update(invalidatedByRemove(files)) } @@ -72,6 +73,7 @@ class RefinedBuildManager(val settings: Settings) extends Changes with BuildMana def update(added: Set[AbstractFile], removed: Set[AbstractFile]) { sources --= removed + deleteClassfiles(removed) update(added ++ invalidatedByRemove(removed)) } @@ -80,6 +82,8 @@ class RefinedBuildManager(val settings: Settings) extends Changes with BuildMana * have been previously added as source files are recompiled. */ private def update(files: Set[AbstractFile]): Unit = if (!files.isEmpty) { + deleteClassfiles(files) + val run = compiler.newRun() compiler.inform("compiling " + files) buildingFiles(files) diff --git a/src/compiler/scala/tools/nsc/interactive/SimpleBuildManager.scala b/src/compiler/scala/tools/nsc/interactive/SimpleBuildManager.scala index 9ecf51ae42..f5bd254c72 100644 --- a/src/compiler/scala/tools/nsc/interactive/SimpleBuildManager.scala +++ b/src/compiler/scala/tools/nsc/interactive/SimpleBuildManager.scala @@ -38,11 +38,21 @@ class SimpleBuildManager(val settings: Settings) extends BuildManager { /** Remove the given files from the managed build process. */ def removeFiles(files: Set[AbstractFile]) { sources --= files + deleteClassfiles(files) + update(invalidatedByRemove(files)) + } + + + /** Return the set of invalidated files caused by removing the given files. */ + private def invalidatedByRemove(files: Set[AbstractFile]): Set[AbstractFile] = { + val deps = compiler.dependencyAnalysis.dependencies + deps.dependentFiles(Int.MaxValue, files) } def update(added: Set[AbstractFile], removed: Set[AbstractFile]) { - removeFiles(removed) - update(added) + sources --= removed + deleteClassfiles(removed) + update(added ++ invalidatedByRemove(removed)) } /** The given files have been modified by the user. Recompile @@ -50,6 +60,8 @@ class SimpleBuildManager(val settings: Settings) extends BuildManager { * have been previously added as source files are recompiled. */ def update(files: Set[AbstractFile]) { + deleteClassfiles(files) + val deps = compiler.dependencyAnalysis.dependencies val run = compiler.newRun() compiler.inform("compiling " + files) -- cgit v1.2.3