Skip to content

Commit d31c64e

Browse files
committed
Use java.io.File everywhere and accept existing source files
1 parent e49547a commit d31c64e

File tree

5 files changed

+106
-77
lines changed

5 files changed

+106
-77
lines changed

src/main/kotlin/SynchronizedToolProvider.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.facebook.buck.jvm.java.javax
1818

1919
import com.tschuchort.compiletesting.isJdk9OrLater
20-
import org.jetbrains.kotlin.com.intellij.util.lang.JavaVersion
2120

2221
import java.lang.reflect.InvocationTargetException
2322
import java.lang.reflect.Method
@@ -29,7 +28,7 @@ import javax.tools.ToolProvider
2928
* ToolProvider has no synchronization internally, so if we don't synchronize from the outside we
3029
* could wind up loading the compiler classes multiple times from different class loaders.
3130
*/
32-
object SynchronizedToolProvider {
31+
internal object SynchronizedToolProvider {
3332
private var getPlatformClassLoaderMethod: Method? = null
3433

3534
val systemJavaCompiler: JavaCompiler

src/main/kotlin/com/tschuchort/compiletesting/KotlinCompilation.kt

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ package com.tschuchort.compiletesting
1919
import com.facebook.buck.jvm.java.javax.SynchronizedToolProvider
2020
import io.github.classgraph.ClassGraph
2121
import okio.Buffer
22-
import okio.buffer
23-
import okio.sink
2422
import org.jetbrains.kotlin.base.kapt3.AptMode
2523
import org.jetbrains.kotlin.base.kapt3.KaptFlag
2624
import org.jetbrains.kotlin.base.kapt3.KaptOptions
@@ -33,7 +31,6 @@ import org.jetbrains.kotlin.config.JVMAssertionsMode
3331
import org.jetbrains.kotlin.config.JvmDefaultMode
3432
import org.jetbrains.kotlin.config.JvmTarget
3533
import org.jetbrains.kotlin.config.Services
36-
import org.jetbrains.kotlin.incremental.isJavaFile
3734
import java.io.*
3835
import java.lang.RuntimeException
3936
import java.net.URLClassLoader
@@ -63,7 +60,7 @@ class KotlinCompilation {
6360
var classpaths: List<File> = emptyList()
6461

6562
/** Source files to be compiled */
66-
var sources: List<KotlinCompilation.SourceFile> = emptyList()
63+
var sources: List<SourceFile> = emptyList()
6764

6865
/** Annotation processors to be passed to kapt */
6966
var annotationProcessors: List<Processor> = emptyList()
@@ -129,7 +126,7 @@ class KotlinCompilation {
129126
* Root modules to resolve in addition to the initial modules,
130127
* or all modules on the module path if <module> is ALL-MODULE-PATH
131128
*/
132-
var additionalJavaModules: MutableList<Path> = mutableListOf()
129+
var additionalJavaModules: MutableList<File> = mutableListOf()
133130

134131
/** Don't generate not-null assertions for arguments of platform types */
135132
var noCallAssertions: Boolean = false
@@ -158,7 +155,7 @@ class KotlinCompilation {
158155
var assertionsMode: String? = JVMAssertionsMode.DEFAULT.description
159156

160157
/** Path to the .xml build file to compile */
161-
var buildFile: Path? = null
158+
var buildFile: File? = null
162159

163160
/** Compile multifile classes as a hierarchy of parts and facade */
164161
var inheritMultifileParts: Boolean = false
@@ -170,7 +167,7 @@ class KotlinCompilation {
170167
var skipRuntimeVersionCheck: Boolean = false
171168

172169
/** Path to JSON file to dump Java to Kotlin declaration mappings */
173-
var declarationsOutputPath: Path? = null
170+
var declarationsOutputPath: File? = null
174171

175172
/** Combine modules for source files and binary dependencies into a single module */
176173
var singleModule: Boolean = false
@@ -212,7 +209,7 @@ class KotlinCompilation {
212209
var sanitizeParentheses: Boolean = false
213210

214211
/** Paths to output directories for friend modules (whose internals should be visible) */
215-
var friendPaths: MutableList<Path> = mutableListOf()
212+
var friendPaths: MutableList<File> = mutableListOf()
216213

217214
/**
218215
* Path to the kotlin-stdlib.jar
@@ -275,17 +272,17 @@ class KotlinCompilation {
275272
}
276273

277274
// Directory for input source files
278-
private val sourcesDir get() = File(workingDir, "sources")
275+
private val sourcesDir get() = workingDir.resolve("sources")
279276

280277
// *.class files, Jars and resources (non-temporary) that are created by the
281278
// compilation will land here
282-
val classesDir get() = File(workingDir, "classes")
279+
val classesDir get() = workingDir.resolve("classes")
283280

284281
// Base directory for kapt stuff
285-
private val kaptBaseDir get() = File(workingDir, "kapt")
282+
private val kaptBaseDir get() = workingDir.resolve("kapt")
286283

287284
// Java annotation processors that are compile by kapt will put their generated files here
288-
val kaptSourceDir get() = File(kaptBaseDir, "sources")
285+
val kaptSourceDir get() = kaptBaseDir.resolve("sources")
289286

290287
// Output directory for Kotlin source files generated by kapt
291288
val kaptKotlinGeneratedDir get() = kaptArgs[OPTION_KAPT_KOTLIN_GENERATED]
@@ -295,23 +292,8 @@ class KotlinCompilation {
295292
}
296293
?: File(kaptBaseDir, "kotlinGenerated")
297294

298-
val kaptStubsDir get() = File(kaptBaseDir, "stubs")
299-
val kaptIncrementalDataDir get() = File(kaptBaseDir, "incrementalData")
300-
301-
/** A Kotlin source file to be compiled */
302-
data class SourceFile(val name: String, val contents: String) {
303-
/**
304-
* Writes the source file to the location and returns the
305-
* corresponding [File] object
306-
*/
307-
fun writeTo(dir: File): File =
308-
File(dir, name).apply {
309-
parentFile.mkdirs()
310-
sink().buffer().use {
311-
it.writeUtf8(contents)
312-
}
313-
}
314-
}
295+
val kaptStubsDir get() = kaptBaseDir.resolve("stubs")
296+
val kaptIncrementalDataDir get() = kaptBaseDir.resolve("incrementalData")
315297

316298
/** ExitCode of the entire Kotlin compilation process */
317299
enum class ExitCode {
@@ -364,7 +346,7 @@ class KotlinCompilation {
364346
if(javaModulePath != null)
365347
it.javaModulePath = javaModulePath!!.toString()
366348

367-
it.additionalJavaModules = additionalJavaModules.map(Path::toString).toTypedArray()
349+
it.additionalJavaModules = additionalJavaModules.map(File::getAbsolutePath).toTypedArray()
368350
it.noCallAssertions = noCallAssertions
369351
it.noParamAssertions = noParamAssertions
370352
it.noReceiverAssertions = noReceiverAssertions
@@ -399,7 +381,7 @@ class KotlinCompilation {
399381
it.sanitizeParentheses = sanitizeParentheses
400382

401383
if(friendPaths.isNotEmpty())
402-
it.friendPaths = friendPaths.map(Path::toString).toTypedArray()
384+
it.friendPaths = friendPaths.map(File::getAbsolutePath).toTypedArray()
403385

404386
if(scriptResolverEnvironment.isNotEmpty())
405387
it.scriptResolverEnvironment = scriptResolverEnvironment.map { (key, value) -> "$key=\"$value\"" }.toTypedArray()
@@ -445,7 +427,7 @@ class KotlinCompilation {
445427
KaptComponentRegistrar.Parameters(annotationProcessors, kaptOptions)
446428
)
447429

448-
val kotlinSources = sourcesDir.listFilesRecursively().filter(File::isKotlinFile)
430+
val kotlinSources = sourcesDir.listFilesRecursively().filter<File>(File::isKotlinFile)
449431
val javaSources = sourcesDir.listFilesRecursively().filter(File::isJavaFile)
450432

451433
val sourcePaths = mutableListOf<File>().apply {
@@ -463,7 +445,7 @@ class KotlinCompilation {
463445
Java files might generate Kotlin files which then need to be compiled in the
464446
compileKotlin step before the compileJava step). So instead we trick K2JVMCompiler
465447
by just including an empty .kt-File. */
466-
add(SourceFile("emptyKotlinFile.kt", "").writeTo(kaptBaseDir))
448+
add(SourceFile.new("emptyKotlinFile.kt", "").writeIfNeeded(kaptBaseDir))
467449
}
468450
}.map(File::getAbsolutePath).distinct()
469451

@@ -658,7 +640,7 @@ class KotlinCompilation {
658640
kaptKotlinGeneratedDir.mkdirs()
659641

660642
// write given sources to working directory
661-
sources.forEach { it.writeTo(sourcesDir) }
643+
sources.forEach { it.writeIfNeeded(sourcesDir) }
662644

663645
/*
664646
There are 4 steps to the compilation process:
@@ -738,13 +720,11 @@ class KotlinCompilation {
738720
//TODO("check that jar file actually contains the right classes")
739721
}
740722

741-
742723
if (jarFile == null)
743724
log("Searched host classpaths for $simpleName and found no match")
744725
else
745726
log("Searched host classpaths for $simpleName and found ${jarFile.path}")
746727

747-
748728
return jarFile
749729
}
750730

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.tschuchort.compiletesting
2+
3+
import okio.buffer
4+
import okio.sink
5+
import java.io.File
6+
7+
/**
8+
* A source file for the [KotlinCompilation]
9+
*/
10+
abstract class SourceFile {
11+
internal abstract fun writeIfNeeded(dir: File): File
12+
13+
companion object {
14+
/**
15+
* Create a new source file for the compilation when the compilation is run
16+
*/
17+
fun new(name: String, contents: String) = object : SourceFile() {
18+
override fun writeIfNeeded(dir: File): File {
19+
val file = dir.resolve(name)
20+
file.createNewFile()
21+
22+
file.sink().buffer().use {
23+
it.writeUtf8(contents)
24+
}
25+
26+
return file
27+
}
28+
}
29+
30+
/**
31+
* Compile an existing source file
32+
*/
33+
fun fromPath(path: File) = object : SourceFile() {
34+
init {
35+
require(path.isFile)
36+
}
37+
38+
override fun writeIfNeeded(dir: File): File = path
39+
}
40+
}
41+
}

src/main/kotlin/com/tschuchort/compiletesting/Utils.kt

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package com.tschuchort.compiletesting
22

33
import java.io.File
4+
import java.io.IOException
45
import java.net.URL
56
import java.net.URLClassLoader
7+
import java.nio.file.*
8+
import java.nio.file.attribute.BasicFileAttributes
69
import javax.lang.model.SourceVersion
710

811
internal fun <E> MutableCollection<E>.addAll(vararg elems: E) = addAll(elems)
@@ -34,11 +37,25 @@ internal fun File.listFilesRecursively(): List<File> {
3437
}
3538
}
3639

37-
internal fun File.isKotlinFile()
38-
= listOf("kt", "kts").any{ it.equals(extension, ignoreCase = true) }
40+
internal fun Path.listFilesRecursively(): List<Path> {
41+
val files = mutableListOf<Path>()
3942

40-
internal fun File.isJavaFile()
41-
= listOf("java").any{ it.equals(extension, ignoreCase = true) }
43+
Files.walkFileTree(this, object : SimpleFileVisitor<Path>() {
44+
override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
45+
files.add(file)
46+
return FileVisitResult.CONTINUE
47+
}
48+
})
49+
50+
return files
51+
}
52+
53+
internal fun File.isKotlinFile() = hasFileExtension(listOf("kt", "kts"))
54+
55+
internal fun File.isJavaFile() = hasFileExtension(listOf("java"))
56+
57+
internal fun File.hasFileExtension(extensions: List<String>)
58+
= extensions.any{ it.equals(extension, ignoreCase = true) }
4259

4360
internal fun URLClassLoader.addUrl(url: URL) {
4461
val addUrlMethod = URLClassLoader::class.java.getDeclaredMethod("addURL", URL::class.java)

0 commit comments

Comments
 (0)