blob: fa7a5f94aef411686e1032fe170b33becc939a8a (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
package scala.tools.nsc
package dependencies;
import util.SourceFile;
import io.AbstractFile
trait DependencyAnalysis extends SubComponent with Files {
import global._
val phaseName = "dependencyAnalysis";
def off = settings.make.value == "all"
def newPhase(prev : Phase) = new AnalysisPhase(prev)
lazy val maxDepth = settings.make.value match {
case "changed" => 0
case "transitive" => Int.MaxValue
case "immediate" => 1
}
def nameToFile(src: AbstractFile, name : String) =
settings.outputDirs.outputDirFor(src)
.lookupPathUnchecked(name.toString.replace(".", java.io.File.separator) + ".class", false)
private var depFile: Option[AbstractFile] = None
def dependenciesFile_=(file: AbstractFile) {
assert(file ne null)
depFile = Some(file)
}
def dependenciesFile: Option[AbstractFile] = depFile
def classpath = settings.classpath.value
def newDeps = new FileDependencies(classpath);
var dependencies = newDeps
/** Write dependencies to the current file. */
def saveDependencies() =
if(dependenciesFile.isDefined)
dependencies.writeTo(dependenciesFile.get)
/** Load dependencies from the given file and save the file reference for
* future saves.
*/
def loadFrom(f: AbstractFile) {
dependenciesFile = f
val fd = FileDependencies.readFrom(f);
dependencies = if (fd.classpath != classpath) {
if(settings.debug.value){
println("Classpath has changed. Nuking dependencies");
}
newDeps
} else fd
}
def filter(files : List[SourceFile]) : List[SourceFile] =
if (off) files
else if (dependencies.isEmpty){
if(settings.debug.value){
println("No known dependencies. Compiling everything");
}
files
}
else {
val (direct, indirect) = dependencies.invalidatedFiles(maxDepth);
val filtered = files.filter(x => {
val f = x.path.absolute;
direct(f) || indirect(f) || !dependencies.containsFile(f);
})
filtered match {
case Nil => println("No changes to recompile");
case x => println("Recompiling " + (
if(settings.debug.value) x.mkString(", ")
else x.length + " files")
)
}
filtered
}
class AnalysisPhase(prev : Phase) extends StdPhase(prev){
def apply(unit : global.CompilationUnit) {
val f = unit.source.file.file;
// When we're passed strings by the interpreter
// they have no source file. We simply ignore this case
// as irrelevant to dependency analysis.
if (f != null){
val source: AbstractFile = unit.source.file;
for (d <- unit.icode){
dependencies.emits(source, nameToFile(unit.source.file, d.toString))
}
for (d <- unit.depends; if (d.sourceFile != null)){
dependencies.depends(source, d.sourceFile);
}
}
}
}
}
|