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