summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Plociniczak <hubert.plociniczak@epfl.ch>2009-10-30 19:59:34 +0000
committerHubert Plociniczak <hubert.plociniczak@epfl.ch>2009-10-30 19:59:34 +0000
commita6d876fbddedaaa8fae091602819b45c21f44e80 (patch)
tree194c029c285989b7bed8b77a28661a9907584541
parent95b6ced60a72556bf5a0c385fdc53b7cf4304361 (diff)
downloadscala-a6d876fbddedaaa8fae091602819b45c21f44e80.tar.gz
scala-a6d876fbddedaaa8fae091602819b45c21f44e80.tar.bz2
scala-a6d876fbddedaaa8fae091602819b45c21f44e80.zip
Proper fix for #2280
-rw-r--r--src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala158
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala1
3 files changed, 85 insertions, 76 deletions
diff --git a/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala b/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala
index 4b19238b7e..c5ac031406 100644
--- a/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala
@@ -141,7 +141,7 @@ trait DependencyAnalysis extends SubComponent with Files {
references += file -> (references(file) + tree.symbol.fullNameString)
}
tree match {
- case cdef: ClassDef if !cdef.symbol.isModuleClass && !cdef.symbol.hasFlag(Flags.PACKAGE) =>
+ case cdef: ClassDef if !cdef.symbol.hasFlag(Flags.PACKAGE) =>
buf += cdef.symbol
super.traverse(tree)
diff --git a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala
index 10e57df076..769c3b9250 100644
--- a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala
@@ -83,36 +83,54 @@ class RefinedBuildManager(val settings: Settings) extends Changes with BuildMana
/** The given files have been modified by the user. Recompile
* them and all files that depend on them. Only files that
* have been previously added as source files are recompiled.
+ * Files that were already compiled are taken out from the result
+ * of the dependency analysis.
*/
- private def update(files: Set[AbstractFile]): Unit = if (!files.isEmpty) {
- deleteClassfiles(files)
+ private def update(files: Set[AbstractFile]) = {
+ def update0(files: Set[AbstractFile], updated: Set[AbstractFile]): Unit = if (!files.isEmpty) {
+ deleteClassfiles(files)
+ val run = compiler.newRun()
+ compiler.inform("compiling " + files)
+ buildingFiles(files)
+
+ run.compileFiles(files.toList)
+ if (compiler.reporter.hasErrors) {
+ compiler.reporter.reset
+ return
+ }
- val run = compiler.newRun()
- compiler.inform("compiling " + files)
- buildingFiles(files)
+ val changesOf = new mutable.HashMap[Symbol, List[Change]]
+ val additionalDefs: mutable.HashSet[AbstractFile] = mutable.HashSet.empty
+
+ val defs = compiler.dependencyAnalysis.definitions
+ for (src <- files) {
+ if (definitions(src).isEmpty)
+ additionalDefs ++= compiler.dependencyAnalysis.
+ dependencies.dependentFiles(1, mutable.Set(src))
+ else {
+ val syms = defs(src)
+ for (sym <- syms) {
+ definitions(src).find(_.fullNameString == sym.fullNameString) match {
+ case Some(oldSym) =>
+ changesOf(oldSym) = changeSet(oldSym, sym)
+ case _ =>
+ // a new top level definition, no need to process
+ }
+ }
+ }
+ }
- run.compileFiles(files.toList)
- if (compiler.reporter.hasErrors) {
- compiler.reporter.reset
- return
+ println("Changes: " + changesOf)
+ updateDefinitions(files)
+ val compiled = updated ++ files
+ additionalDefs -- compiled
+ update0(invalidated(files, changesOf) ++ additionalDefs, compiled)
}
- val changesOf = new mutable.HashMap[Symbol, List[Change]]
-
- val defs = compiler.dependencyAnalysis.definitions
- for (src <- files; val syms = defs(src); sym <- syms) {
- definitions(src).find(_.fullNameString == sym.fullNameString) match {
- case Some(oldSym) =>
- changesOf(oldSym) = changeSet(oldSym, sym)
- case _ =>
- // a new top level definition, no need to process
- }
- }
- println("Changes: " + changesOf)
- updateDefinitions(files)
- update(invalidated(files, changesOf))
+ update0(files, immutable.Set())
}
+
/** Return the set of source files that are invalidated by the given changes. */
def invalidated(files: Set[AbstractFile], changesOf: collection.Map[Symbol, List[Change]]): Set[AbstractFile] = {
val buf = new mutable.HashSet[AbstractFile]
@@ -127,71 +145,63 @@ class RefinedBuildManager(val settings: Settings) extends Changes with BuildMana
break
}
- // changesOf will be empty just after initialization with a saved
- // dependencies file.
- if (changesOf.isEmpty)
- buf ++= directDeps
- else {
- for ((oldSym, changes) <- changesOf; change <- changes) {
-
- def checkParents(cls: Symbol, file: AbstractFile) {
- val parentChange = cls.info.parents.exists(_.typeSymbol.fullNameString == oldSym.fullNameString)
+ for ((oldSym, changes) <- changesOf; change <- changes) {
+ def checkParents(cls: Symbol, file: AbstractFile) {
+ val parentChange = cls.info.parents.exists(_.typeSymbol.fullNameString == oldSym.fullNameString)
// println("checkParents " + cls + " oldSym: " + oldSym + " parentChange: " + parentChange + " " + cls.info.parents)
- change match {
- case Changed(Class(_)) if parentChange =>
- invalidate(file, "parents have changed", change)
+ change match {
+ case Changed(Class(_)) if parentChange =>
+ invalidate(file, "parents have changed", change)
- case Added(Definition(_)) if parentChange =>
- invalidate(file, "inherited new method", change)
+ case Added(Definition(_)) if parentChange =>
+ invalidate(file, "inherited new method", change)
- case Removed(Definition(_)) if parentChange =>
- invalidate(file, "inherited method removed", change)
+ case Removed(Definition(_)) if parentChange =>
+ invalidate(file, "inherited method removed", change)
- case _ => ()
- }
+ case _ => ()
}
+ }
- def checkInterface(cls: Symbol, file: AbstractFile) {
- change match {
- case Added(Definition(name)) =>
- if (cls.info.decls.iterator.exists(_.fullNameString == name))
- invalidate(file, "of new method with existing name", change)
- case Changed(Class(name)) =>
- if (cls.info.typeSymbol.fullNameString == name)
- invalidate(file, "self type changed", change)
- case _ =>
- ()
- }
+ def checkInterface(cls: Symbol, file: AbstractFile) {
+ change match {
+ case Added(Definition(name)) =>
+ if (cls.info.decls.iterator.exists(_.fullNameString == name))
+ invalidate(file, "of new method with existing name", change)
+ case Changed(Class(name)) =>
+ if (cls.info.typeSymbol.fullNameString == name)
+ invalidate(file, "self type changed", change)
+ case _ =>
+ ()
}
+ }
- def checkReferences(file: AbstractFile) {
-// println(file + ":" + references(file))
- val refs = references(file)
- if (refs.isEmpty)
- invalidate(file, "it is a direct dependency and we don't yet have finer-grained dependency information", change)
- else {
- change match {
- case Removed(Definition(name)) if refs(name) =>
- invalidate(file, "it references deleted definition", change)
- case Removed(Class(name)) if (refs(name)) =>
- invalidate(file, "it references deleted class", change)
- case Changed(Definition(name)) if (refs(name)) =>
- invalidate(file, "it references changed definition", change)
- case _ => ()
- }
+ def checkReferences(file: AbstractFile) {
+// println(file + ":" + references(file))
+ val refs = references(file)
+ if (refs.isEmpty)
+ invalidate(file, "it is a direct dependency and we don't yet have finer-grained dependency information", change)
+ else {
+ change match {
+ case Removed(Definition(name)) if refs(name) =>
+ invalidate(file, "it references deleted definition", change)
+ case Removed(Class(name)) if (refs(name)) =>
+ invalidate(file, "it references deleted class", change)
+ case Changed(Definition(name)) if (refs(name)) =>
+ invalidate(file, "it references changed definition", change)
+ case _ => ()
}
}
+ }
- breakable {
- for (file <- directDeps) {
- for (cls <- definitions(file)) checkParents(cls, file)
- for (cls <- definitions(file)) checkInterface(cls, file)
- checkReferences(file)
- }
+ breakable {
+ for (file <- directDeps) {
+ for (cls <- definitions(file)) checkParents(cls, file)
+ for (cls <- definitions(file)) checkInterface(cls, file)
+ checkReferences(file)
}
}
}
-
buf
}
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 9f31795c14..9293ab4c3f 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -1888,7 +1888,6 @@ trait Symbols {
}
override def cloneSymbolImpl(owner: Symbol): Symbol = {
- assert(!isModuleClass)
val clone = new ClassSymbol(owner, pos, name)
if (thisSym != this) {
clone.typeOfThis = typeOfThis