@@ -3,6 +3,7 @@ package xsbt
3
3
4
4
import xsbti .compile .{CompileProgress , SingleOutput }
5
5
import java .io .File
6
+ import java .nio .file .Path
6
7
import xsbti ._
7
8
import sbt .io .IO
8
9
import xsbti .api .{ ClassLike , Def , DependencyContext }
@@ -15,6 +16,8 @@ import dotty.tools.xsbt.CompilerBridge
15
16
import TestCallback .ExtractedClassDependencies
16
17
import ScalaCompilerForUnitTesting .Callbacks
17
18
19
+ case class CompileOutput (srcFiles : Seq [VirtualFileRef ], classesOutput : Path , analysis : TestCallback , progress : TestCompileProgress )
20
+
18
21
object ScalaCompilerForUnitTesting :
19
22
case class Callbacks (analysis : TestCallback , progress : TestCompileProgress )
20
23
@@ -25,38 +28,33 @@ object ScalaCompilerForUnitTesting:
25
28
class ScalaCompilerForUnitTesting {
26
29
27
30
def extractEnteredPhases (srcs : String * ): Seq [List [String ]] = {
28
- val (tempSrcFiles, Callbacks (_, testProgress)) = compileSrcs(srcs* )
29
- val run = testProgress .runs.head
30
- tempSrcFiles .map(src => run.unitPhases(src.id))
31
+ val output = compileSrcs(srcs* )
32
+ val run = output.progress .runs.head
33
+ output.srcFiles .map(src => run.unitPhases(src.id))
31
34
}
32
35
33
- def extractTotal (srcs : String * )(extraSourcePath : String * ): Int = {
34
- val (tempSrcFiles, Callbacks (_, testProgress)) = compileSrcs(List (srcs.toList), extraSourcePath.toList)
35
- val run = testProgress.runs.head
36
- run.total
37
- }
36
+ def extractTotal (srcs : String * )(extraSourcePath : String * ): Int =
37
+ compileSrcs(List (srcs.toList), extraSourcePath.toList).progress.runs.head.total
38
38
39
- def extractProgressPhases (srcs : String * ): List [String ] = {
40
- val (_, Callbacks (_, testProgress)) = compileSrcs(srcs* )
41
- testProgress.runs.head.phases
42
- }
39
+ def extractProgressPhases (srcs : String * ): List [String ] =
40
+ compileSrcs(srcs* ).progress.runs.head.phases
43
41
44
42
/**
45
43
* Compiles given source code using Scala compiler and returns API representation
46
44
* extracted by ExtractAPI class.
47
45
*/
48
46
def extractApiFromSrc (src : String ): Seq [ClassLike ] = {
49
- val ( Seq (tempSrcFile), Callbacks (analysisCallback, _)) = compileSrcs(src)
50
- analysisCallback. apis(tempSrcFile )
47
+ val output = compileSrcs(src)
48
+ output.analysis. apis(output.srcFiles.head )
51
49
}
52
50
53
51
/**
54
52
* Compiles given source code using Scala compiler and returns API representation
55
53
* extracted by ExtractAPI class.
56
54
*/
57
55
def extractApisFromSrcs (srcs : List [String ]* ): Seq [Seq [ClassLike ]] = {
58
- val (tempSrcFiles, Callbacks (analysisCallback, _)) = compileSrcs(srcs.toList)
59
- tempSrcFiles. map(analysisCallback .apis)
56
+ val output = compileSrcs(srcs.toList)
57
+ output.srcFiles. map(output.analysis .apis)
60
58
}
61
59
62
60
/**
@@ -73,15 +71,16 @@ class ScalaCompilerForUnitTesting {
73
71
assertDefaultScope : Boolean = true
74
72
): Map [String , Set [String ]] = {
75
73
// we drop temp src file corresponding to the definition src file
76
- val (Seq (_, tempSrcFile), Callbacks (analysisCallback, _)) = compileSrcs(definitionSrc, actualSrc)
74
+ val output = compileSrcs(definitionSrc, actualSrc)
75
+ val analysis = output.analysis
77
76
78
77
if (assertDefaultScope) for {
79
- (className, used) <- analysisCallback .usedNamesAndScopes
80
- analysisCallback .TestUsedName (name, scopes) <- used
78
+ (className, used) <- analysis .usedNamesAndScopes
79
+ analysis .TestUsedName (name, scopes) <- used
81
80
} assert(scopes.size() == 1 && scopes.contains(UseScope .Default ), s " $className uses $name in $scopes" )
82
81
83
- val classesInActualSrc = analysisCallback .classNames(tempSrcFile ).map(_._1)
84
- classesInActualSrc.map(className => className -> analysisCallback .usedNames(className)).toMap
82
+ val classesInActualSrc = analysis .classNames(output.srcFiles.head ).map(_._1)
83
+ classesInActualSrc.map(className => className -> analysis .usedNames(className)).toMap
85
84
}
86
85
87
86
/**
@@ -91,11 +90,11 @@ class ScalaCompilerForUnitTesting {
91
90
* Only the names used in the last src file are returned.
92
91
*/
93
92
def extractUsedNamesFromSrc (sources : String * ): Map [String , Set [String ]] = {
94
- val (srcFiles, Callbacks (analysisCallback, _)) = compileSrcs(sources* )
95
- srcFiles
93
+ val output = compileSrcs(sources* )
94
+ output. srcFiles
96
95
.map { srcFile =>
97
- val classesInSrc = analysisCallback .classNames(srcFile).map(_._1)
98
- classesInSrc.map(className => className -> analysisCallback .usedNames(className)).toMap
96
+ val classesInSrc = output.analysis .classNames(srcFile).map(_._1)
97
+ classesInSrc.map(className => className -> output.analysis .usedNames(className)).toMap
99
98
}
100
99
.reduce(_ ++ _)
101
100
}
@@ -113,15 +112,15 @@ class ScalaCompilerForUnitTesting {
113
112
* file system-independent way of testing dependencies between source code "files".
114
113
*/
115
114
def extractDependenciesFromSrcs (srcs : List [List [String ]]): ExtractedClassDependencies = {
116
- val (_, Callbacks (testCallback, _)) = compileSrcs(srcs)
115
+ val analysis = compileSrcs(srcs).analysis
117
116
118
- val memberRefDeps = testCallback .classDependencies collect {
117
+ val memberRefDeps = analysis .classDependencies collect {
119
118
case (target, src, DependencyByMemberRef ) => (src, target)
120
119
}
121
- val inheritanceDeps = testCallback .classDependencies collect {
120
+ val inheritanceDeps = analysis .classDependencies collect {
122
121
case (target, src, DependencyByInheritance ) => (src, target)
123
122
}
124
- val localInheritanceDeps = testCallback .classDependencies collect {
123
+ val localInheritanceDeps = analysis .classDependencies collect {
125
124
case (target, src, LocalDependencyByInheritance ) => (src, target)
126
125
}
127
126
ExtractedClassDependencies .fromPairs(memberRefDeps, inheritanceDeps, localInheritanceDeps)
@@ -142,12 +141,24 @@ class ScalaCompilerForUnitTesting {
142
141
* The sequence of temporary files corresponding to passed snippets and analysis
143
142
* callback is returned as a result.
144
143
*/
145
- def compileSrcs (groupedSrcs : List [List [String ]], sourcePath : List [String ] = Nil ) : ( Seq [ VirtualFile ], Callbacks ) = {
144
+ def compileSrcs (groupedSrcs : List [List [String ]], sourcePath : List [String ] = Nil , compileToJar : Boolean = false , incEnabled : Boolean = true ) : CompileOutput = {
146
145
val temp = IO .createTemporaryDirectory
147
- val analysisCallback = new TestCallback
146
+ val (forceSbtArgs, analysisCallback) =
147
+ if (incEnabled)
148
+ (Seq (" -Yforce-sbt-phases" ), new TestCallback )
149
+ else
150
+ (Seq .empty, new TestCallbackNoInc )
148
151
val testProgress = new TestCompileProgress
149
- val classesDir = new File (temp, " classes" )
150
- classesDir.mkdir()
152
+ val classesOutput =
153
+ if (compileToJar) {
154
+ val jar = new File (temp, " classes.jar" )
155
+ jar.createNewFile()
156
+ jar
157
+ } else {
158
+ val dir = new File (temp, " classes" )
159
+ dir.mkdir()
160
+ dir
161
+ }
151
162
152
163
val bridge = new CompilerBridge
153
164
@@ -164,16 +175,16 @@ class ScalaCompilerForUnitTesting {
164
175
}
165
176
166
177
val virtualSrcFiles = srcFiles.toArray
167
- val classesDirPath = classesDir .getAbsolutePath.toString
178
+ val classesOutputPath = classesOutput .getAbsolutePath()
168
179
val output = new SingleOutput :
169
- def getOutputDirectory () = classesDir
180
+ def getOutputDirectory () = classesOutput
170
181
171
182
val maybeSourcePath = if extraFiles.isEmpty then Nil else List (" -sourcepath" , temp.getAbsolutePath.toString)
172
183
173
184
bridge.run(
174
185
virtualSrcFiles,
175
186
new TestDependencyChanges ,
176
- Array (" -Yforce-sbt-phases " , " - classpath" , classesDirPath , " -usejavacp" , " -d" , classesDirPath ) ++ maybeSourcePath,
187
+ (forceSbtArgs ++: Array (" -classpath" , classesOutputPath , " -usejavacp" , " -d" , classesOutputPath) ) ++ maybeSourcePath,
177
188
output,
178
189
analysisCallback,
179
190
new TestReporter ,
@@ -185,17 +196,23 @@ class ScalaCompilerForUnitTesting {
185
196
186
197
srcFiles
187
198
}
188
- (files.flatten.toSeq, Callbacks ( analysisCallback, testProgress) )
199
+ CompileOutput (files.flatten.toSeq, classesOutput.toPath, analysisCallback, testProgress)
189
200
}
190
201
191
- def compileSrcs (srcs : String * ): ( Seq [ VirtualFile ], Callbacks ) = {
202
+ def compileSrcs (srcs : String * ): CompileOutput = {
192
203
compileSrcs(List (srcs.toList))
193
204
}
194
205
206
+ def compileSrcsNoInc (srcs : String * ): CompileOutput = {
207
+ compileSrcs(List (srcs.toList), incEnabled = false )
208
+ }
209
+
210
+ def compileSrcsToJar (srcs : String * ): CompileOutput =
211
+ compileSrcs(List (srcs.toList), compileToJar = true )
212
+
195
213
private def prepareSrcFile (baseDir : File , fileName : String , src : String ): VirtualFile = {
196
214
val srcFile = new File (baseDir, fileName)
197
215
IO .write(srcFile, src)
198
216
new TestVirtualFile (srcFile.toPath)
199
217
}
200
218
}
201
-
0 commit comments