Move IC tests to compiler

Fixing IC after moving it from Gradle to the compiler in commit f40a3eff20
This commit is contained in:
Alexey Tsvetkov
2016-11-28 15:09:00 +03:00
parent cbe680d876
commit c1812d7d92
20 changed files with 235 additions and 44 deletions
@@ -4,6 +4,8 @@
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/testData" type="java-test-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
@@ -15,5 +17,6 @@
<orderEntry type="module" module-name="frontend" />
<orderEntry type="module" module-name="frontend.java" />
<orderEntry type="module" module-name="util" />
<orderEntry type="library" name="junit-4.12" level="project" />
</component>
</module>
@@ -499,10 +499,10 @@ class IncrementalJvmCompilerRunner(
}
}
internal var K2JVMCompilerArguments.destinationAsFile: File
var K2JVMCompilerArguments.destinationAsFile: File
get() = File(destination)
set(value) { destination = value.path }
internal var K2JVMCompilerArguments.classpathAsList: List<File>
var K2JVMCompilerArguments.classpathAsList: List<File>
get() = classpath.split(File.pathSeparator).map(::File)
set(value) { classpath = value.joinToString(separator = File.pathSeparator, transform = { it.path }) }
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.incremental.snapshots
import java.io.File
import java.util.*
internal class FileSnapshot(
class FileSnapshot(
val file: File,
val length: Long,
val hash: ByteArray
@@ -21,7 +21,7 @@ import java.io.DataInput
import java.io.DataOutput
import java.io.File
internal object FileSnapshotExternalizer : DataExternalizer<FileSnapshot> {
object FileSnapshotExternalizer : DataExternalizer<FileSnapshot> {
override fun save(out: DataOutput, value: FileSnapshot) {
out.writeUTF(value.file.canonicalPath)
out.writeLong(value.length)
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.incremental.storage.PathStringDescriptor
import java.io.File
import java.util.*
internal class FileSnapshotMap(storageFile: File) : BasicStringMap<FileSnapshot>(storageFile, PathStringDescriptor, FileSnapshotExternalizer) {
class FileSnapshotMap(storageFile: File) : BasicStringMap<FileSnapshot>(storageFile, PathStringDescriptor, FileSnapshotExternalizer) {
override fun dumpValue(value: FileSnapshot): String =
value.toString()
@@ -18,11 +18,11 @@ package org.jetbrains.kotlin.incremental.snapshots
import java.io.File
internal interface FileSnapshotProvider {
interface FileSnapshotProvider {
operator fun get(file: File): FileSnapshot
}
internal class SimpleFileSnapshotProviderImpl : FileSnapshotProvider {
class SimpleFileSnapshotProviderImpl : FileSnapshotProvider {
override fun get(file: File): FileSnapshot {
val length = file.length()
val hash = file.md5
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin
import com.intellij.openapi.util.io.FileUtil
import org.junit.After
import org.junit.Before
import java.io.File
import kotlin.properties.Delegates
abstract class TestWithWorkingDir {
protected var workingDir: File by Delegates.notNull()
private set
@Before
open fun setUp() {
workingDir = FileUtil.createTempDirectory(this.javaClass.simpleName, null)
}
@After
open fun tearDown() {
workingDir.deleteRecursively()
}
}
@@ -0,0 +1,69 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import java.io.File
@RunWith(Parameterized::class)
class BuildLogParserParametrizedTest {
@Parameterized.Parameter
@JvmField
var testDirName: String = ""
@Test
fun testParser() {
val testDir = File(TEST_ROOT, testDirName)
val logFile = File(testDir, LOG_FILE_NAME)
assert(logFile.isFile) { "Log file: $logFile does not exist" }
val actualNormalized = dumpBuildLog(parseTestBuildLog(logFile)).replace("\r\n", "\n").trim()
val expectedFile = File(testDir, EXPECTED_PARSED_LOG_FILE_NAME)
if (!expectedFile.isFile) {
expectedFile.createNewFile()
expectedFile.writeText(actualNormalized)
throw AssertionError("Expected file log did not exist, created: $expectedFile")
}
val expectedNormalized = expectedFile.readText().replace("\r\n", "\n").trim()
Assert.assertEquals("Parsed content was unexpected: ", expectedNormalized, actualNormalized)
// parse expected, dump again and compare (to check that dumped log can be parsed again)
val reparsedActualNormalized = dumpBuildLog(parseTestBuildLog(expectedFile)).trim()
Assert.assertEquals("Reparsed content was unexpected: ", expectedNormalized, reparsedActualNormalized)
}
companion object {
private val TEST_ROOT = File("compiler/incremental-compilation-impl/testData/buildLogsParserData")
private val LOG_FILE_NAME = "build.log"
private val EXPECTED_PARSED_LOG_FILE_NAME = "expected.txt"
@Suppress("unused")
@Parameterized.Parameters(name = "{index}: {0}")
@JvmStatic
fun data(): List<Array<String>> {
val directories = TEST_ROOT.listFiles().filter { it.isDirectory }
return directories.map { arrayOf(it.name) }.toList()
}
}
}
@@ -0,0 +1,222 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.TestWithWorkingDir
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import com.intellij.util.containers.HashMap
import org.junit.Assert.assertEquals
import org.jetbrains.kotlin.incremental.testingUtils.*
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import java.io.File
import java.util.*
@RunWith(Parameterized::class)
class KotlinStandaloneIncrementalCompilationTest : TestWithWorkingDir() {
@Parameterized.Parameter
lateinit var testDir: File
@Suppress("unused")
@Parameterized.Parameter(value = 1)
lateinit var readableName: String
@Test
fun testFromJps() {
fun Iterable<File>.relativePaths() =
map { it.relativeTo(workingDir).path.replace('\\', '/') }
val srcDir = File(workingDir, "src").apply { mkdirs() }
val cacheDir = File(workingDir, "incremental-data").apply { mkdirs() }
val outDir = File(workingDir, "out").apply { mkdirs() }
val mapWorkingToOriginalFile = HashMap(copyTestSources(testDir, srcDir, filePrefix = ""))
val sourceRoots = listOf(srcDir)
val args = K2JVMCompilerArguments()
args.destination = outDir.path
args.moduleName = testDir.name
args.classpath = compileClasspath()
// initial build
make(cacheDir, sourceRoots, args)
// modifications
val buildLogFile = buildLogFinder.findBuildLog(testDir) ?: throw IllegalStateException("build log file not found in $workingDir")
val buildLogSteps = parseTestBuildLog(buildLogFile)
val modifications = getModificationsToPerform(testDir,
moduleNames = null,
allowNoFilesWithSuffixInTestData = false,
touchPolicy = TouchPolicy.CHECKSUM)
assert(modifications.size == buildLogSteps.size) {
"Modifications count (${modifications.size}) != expected build log steps count (${buildLogSteps.size})"
}
// Sometimes error messages differ.
// This needs to be fixed, but it does not really matter much (e.g extra lines),
// The workaround is to compare logs without errors, then logs with errors.
// (if logs without errors differ then either compiled files differ or exit codes differ)
val expectedSB = StringBuilder()
val actualSB = StringBuilder()
val expectedSBWithoutErrors = StringBuilder()
val actualSBWithoutErrors = StringBuilder()
var step = 1
for ((modificationStep, buildLogStep) in modifications.zip(buildLogSteps)) {
modificationStep.forEach { it.perform(workingDir, mapWorkingToOriginalFile) }
val (exitCode, compiledSources, compileErrors) = make(cacheDir, sourceRoots, args)
expectedSB.appendLine(stepLogAsString(step, buildLogStep.compiledKotlinFiles, buildLogStep.compileErrors))
expectedSBWithoutErrors.appendLine(stepLogAsString(step, buildLogStep.compiledKotlinFiles, buildLogStep.compileErrors, includeErrors = false))
actualSB.appendLine(stepLogAsString(step, compiledSources.relativePaths(), compileErrors))
actualSBWithoutErrors.appendLine(stepLogAsString(step, compiledSources.relativePaths(), compileErrors, includeErrors = false))
step++
}
if (expectedSBWithoutErrors.toString() != actualSBWithoutErrors.toString()) {
assertEquals(expectedSB.toString(), actualSB.toString())
}
// todo: also compare caches
run rebuildAndCompareOutput@ {
val rebuildOutDir = File(workingDir, "rebuild-out").apply { mkdirs() }
val rebuildCacheDir = File(workingDir, "rebuild-cache").apply { mkdirs() }
args.destination = rebuildOutDir.path
val rebuildResult = make(rebuildCacheDir, sourceRoots, args)
val rebuildExpectedToSucceed = buildLogSteps.last().compileSucceeded
val rebuildSucceeded = rebuildResult.exitCode == ExitCode.OK
assertEquals("Rebuild exit code differs from incremental exit code", rebuildExpectedToSucceed, rebuildSucceeded)
if (rebuildSucceeded) {
assertEqualDirectories(outDir, rebuildOutDir, forgiveExtraFiles = rebuildSucceeded)
}
}
}
private fun compileClasspath(): String {
val currentClasspath = System.getProperty("java.class.path").split(File.pathSeparator)
val stdlib = currentClasspath.find { it.contains("kotlin-stdlib") }
val runtime = currentClasspath.find { it.contains("kotlin-runtime") }
return listOf(stdlib, runtime).joinToString(File.pathSeparator)
}
data class CompilationResult(val exitCode: ExitCode, val compiledSources: Iterable<File>, val compileErrors: Collection<String>)
private fun make(cacheDir: File, sourceRoots: Iterable<File>, args: K2JVMCompilerArguments): CompilationResult {
val compiledSources = arrayListOf<File>()
var resultExitCode = ExitCode.OK
val reporter = object : ICReporter() {
override fun report(message: ()->String) {
}
override fun reportCompileIteration(sourceFiles: Iterable<File>, exitCode: ExitCode) {
compiledSources.addAll(sourceFiles)
resultExitCode = exitCode
}
}
val messageCollector = ErrorMessageCollector()
makeIncrementally(cacheDir, sourceRoots, args, reporter = reporter, messageCollector = messageCollector)
return CompilationResult(resultExitCode, compiledSources, messageCollector.errors)
}
private fun stepLogAsString(step: Int, ktSources: Iterable<String>, errors: Collection<String>, includeErrors: Boolean = true): String {
val sb = StringBuilder()
sb.appendLine("<======= STEP $step =======>")
sb.appendLine()
sb.appendLine("Compiled kotlin sources:")
ktSources.toSet().toTypedArray().sortedArray().forEach { sb.appendLine(it) }
sb.appendLine()
if (errors.isEmpty()) {
sb.appendLine("SUCCESS")
}
else {
sb.appendLine("FAILURE")
if (includeErrors) {
errors.filter(String::isNotEmpty).forEach { sb.appendLine(it) }
}
}
return sb.toString()
}
private fun StringBuilder.appendLine(line: String = "") {
append(line)
append('\n')
}
private class ErrorMessageCollector : MessageCollector {
val errors = ArrayList<String>()
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) {
if (severity.isError) {
errors.add(message)
}
}
override fun clear() {
errors.clear()
}
override fun hasErrors(): Boolean =
errors.isNotEmpty()
}
companion object {
private val jpsResourcesPath = File("jps-plugin/testData/incremental")
private val ignoredDirs = setOf(File(jpsResourcesPath, "cacheVersionChanged"),
File(jpsResourcesPath, "changeIncrementalOption"),
File(jpsResourcesPath, "custom"),
File(jpsResourcesPath, "lookupTracker"))
private val buildLogFinder = BuildLogFinder(isExperimentalEnabled = true, isGradleEnabled = true)
@Suppress("unused")
@Parameterized.Parameters(name = "{1}")
@JvmStatic
fun data(): List<Array<*>> {
fun File.isValidTestDir(): Boolean {
if (!isDirectory) return false
// multi-module tests
val files = list()
if ("dependencies.txt" in files) return false
val logFile = buildLogFinder.findBuildLog(this) ?: return false
val parsedLog = parseTestBuildLog(logFile)
// tests with java may be expected to fail in javac
return files.none { it.endsWith(".java") } && parsedLog.all { it.compiledJavaFiles.isEmpty() }
}
fun File.relativeToGrandfather() =
relativeTo(parentFile.parentFile).path
return jpsResourcesPath.walk()
.onEnter { it !in ignoredDirs }
.filter(File::isValidTestDir)
.map { arrayOf(it, it.relativeToGrandfather()) }
.toList()
}
}
}
@@ -0,0 +1,66 @@
package org.jetbrains.kotlin.incremental.snapshots
import org.jetbrains.kotlin.TestWithWorkingDir
import org.junit.After
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import java.io.File
import kotlin.properties.Delegates
class FileSnapshotMapTest : TestWithWorkingDir() {
private var snapshotMap: FileSnapshotMap by Delegates.notNull()
@Before
override fun setUp() {
super.setUp()
val caches = File(workingDir, "caches").apply { mkdirs() }
val snapshotMapFile = File(caches, "snapshots.tab")
snapshotMap = FileSnapshotMap(snapshotMapFile)
}
@After
override fun tearDown() {
snapshotMap.flush(false)
snapshotMap.close()
super.tearDown()
}
@Test
fun testSnapshotMap() {
val src = File(workingDir, "src").apply { mkdirs() }
val foo = File(src, "foo").apply { mkdirs() }
val removedTxt = File(foo, "removed.txt").apply { writeText("removed") }
val unchangedTxt = File(foo, "unchanged.txt").apply { writeText("unchanged") }
val changedTxt = File(foo, "changed.txt").apply { writeText("changed") }
val diff1 = snapshotMap.compareAndUpdate(src.filesWithExt("txt"))
assertArrayEquals("diff1.removed",
diff1.removed.toSortedPaths(),
emptyArray<String>())
assertArrayEquals("diff1.newOrModified",
diff1.modified.toSortedPaths(),
listOf(removedTxt, unchangedTxt, changedTxt).toSortedPaths())
removedTxt.delete()
unchangedTxt.writeText("unchanged")
changedTxt.writeText("degnahc")
val newTxt = File(foo, "new.txt").apply { writeText("new") }
val diff2 = snapshotMap.compareAndUpdate(src.filesWithExt("txt"))
assertArrayEquals("diff2.removed",
diff2.removed.toSortedPaths(),
listOf(removedTxt).toSortedPaths())
assertArrayEquals("diff2.newOrModified",
diff2.modified.toSortedPaths(),
listOf(newTxt, changedTxt).toSortedPaths())
}
private fun Iterable<File>.toSortedPaths(): Array<String> =
map { it.canonicalPath }.sorted().toTypedArray()
private fun File.filesWithExt(ext: String): Iterable<File> =
walk().filter { it.isFile && it.extension.equals(ext, ignoreCase = true) }.toList()
}
@@ -0,0 +1,76 @@
package org.jetbrains.kotlin.incremental.snapshots
import org.jetbrains.kotlin.TestWithWorkingDir
import org.junit.Assert.*
import org.junit.Test
import java.io.*
class FileSnapshotTest : TestWithWorkingDir() {
private val fileSnapshotProvider: FileSnapshotProvider
get() = SimpleFileSnapshotProviderImpl()
@Test
fun testExternalizer() {
val file = File(workingDir, "1.txt")
file.writeText("test")
val snapshot = fileSnapshotProvider[file]
val deserializedSnapshot = saveAndReadBack(snapshot)
assertEquals(snapshot, deserializedSnapshot)
}
@Test
fun testEqualityNoChanges() {
val file = File(workingDir, "1.txt").apply { writeText("file") }
val oldSnapshot = fileSnapshotProvider[file]
val newSnapshot = fileSnapshotProvider[file]
assertEquals(oldSnapshot, newSnapshot)
}
@Test
fun testEqualityDifferentFile() {
val file1 = File(workingDir, "1.txt").apply { writeText("file1") }
val file2 = File(workingDir, "2.txt").apply {
writeText(file1.readText())
setLastModified(file1.lastModified())
}
val oldSnapshot = fileSnapshotProvider[file1]
val newSnapshot = fileSnapshotProvider[file2]
assertNotEquals(oldSnapshot, newSnapshot)
}
@Test
fun testEqualityDifferentTimestamp() {
val text = "file"
val file = File(workingDir, "1.txt").apply { writeText(text) }
val oldSnapshot = fileSnapshotProvider[file]
Thread.sleep(1000)
file.writeText(text)
val newSnapshot = fileSnapshotProvider[file]
assertEquals(oldSnapshot, newSnapshot)
}
@Test
fun testEqualityDifferentSize() {
val file = File(workingDir, "1.txt").apply { writeText("file") }
val oldSnapshot = fileSnapshotProvider[file]
file.writeText("file modified")
val newSnapshot = fileSnapshotProvider[file]
assertNotEquals(oldSnapshot, newSnapshot)
}
@Test
fun testEqualityDifferentHash() {
val file = File(workingDir, "1.txt").apply { writeText("file") }
val oldSnapshot = fileSnapshotProvider[file]
file.writeText("main")
val newSnapshot = fileSnapshotProvider[file]
assertNotEquals(oldSnapshot, newSnapshot)
}
private fun saveAndReadBack(snapshot: FileSnapshot): FileSnapshot {
val byteOut = ByteArrayOutputStream()
DataOutputStream(byteOut).use { FileSnapshotExternalizer.save(it, snapshot) }
val byteIn = ByteArrayInputStream(byteOut.toByteArray())
return DataInputStream(byteIn).use { FileSnapshotExternalizer.read(it) }
}
}
@@ -0,0 +1,127 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental
import com.intellij.openapi.util.io.FileUtil
import java.io.File
private const val BEGIN_COMPILED_FILES = "Compiling files:"
private const val END_COMPILED_FILES = "End of files"
private const val BEGIN_ERRORS = "COMPILATION FAILED"
class BuildStep(
val compiledKotlinFiles: MutableSet<String> = hashSetOf(),
val compiledJavaFiles: MutableSet<String> = hashSetOf(),
val compileErrors: MutableList<String> = arrayListOf()
) {
val compileSucceeded: Boolean
get() = compileErrors.isEmpty()
}
fun parseTestBuildLog(file: File): List<BuildStep> {
fun splitSteps(lines: List<String>): List<List<String>> {
val stepsLines = mutableListOf<MutableList<String>>()
for (line in lines) {
when {
line.matches("=+ Step #\\d+ =+".toRegex()) -> {
stepsLines.add(mutableListOf())
}
else -> {
stepsLines.lastOrNull()?.add(line)
}
}
}
return stepsLines
}
fun BuildStep.parseStepCompiledFiles(stepLines: List<String>) {
var readFiles = false
for (line in stepLines) {
if (line.startsWith(BEGIN_COMPILED_FILES)) {
readFiles = true
continue
}
if (readFiles && line.startsWith(END_COMPILED_FILES)) {
readFiles = false
continue
}
if (readFiles) {
val path = FileUtil.normalize(line.trim())
if (path.endsWith(".kt")) {
compiledKotlinFiles.add(path)
}
else if (path.endsWith(".java")) {
compiledJavaFiles.add(path)
}
else {
throw IllegalStateException("Expected .kt or .java file, got: $path")
}
}
}
}
fun BuildStep.parseErrors(stepLines: List<String>) {
val startIndex = stepLines.indexOfLast { it.startsWith(BEGIN_ERRORS) }
if (startIndex > 0) {
compileErrors.addAll(stepLines.subList(startIndex + 1, stepLines.size))
}
}
val stepsLines = splitSteps(file.readLines())
return stepsLines.map { stepLines ->
val buildStep = BuildStep()
buildStep.parseStepCompiledFiles(stepLines)
buildStep.parseErrors(stepLines)
buildStep
}
}
// used in gradle integration tests
@Suppress("unused")
fun dumpBuildLog(buildSteps: Iterable<BuildStep>): String {
val sb = StringBuilder()
for ((i, step) in buildSteps.withIndex()) {
if (i > 0) {
sb.appendln()
}
sb.appendln("================ Step #${i+1} =================")
sb.appendln()
sb.appendln(BEGIN_COMPILED_FILES)
step.compiledKotlinFiles.sorted().forEach { sb.appendln(it) }
step.compiledJavaFiles.sorted().forEach { sb.appendln(it) }
sb.appendln(END_COMPILED_FILES)
sb.appendln("------------------------------------------")
if (!step.compileSucceeded) {
sb.appendln(BEGIN_ERRORS)
step.compileErrors.forEach { sb.appendln(it) }
}
}
return sb.toString()
}
@@ -0,0 +1,50 @@
================ Step #1 =================
Cleaning output files:
out/production/module/META-INF/module.kotlin_module
out/production/module/inline/InlineGetKt.class
End of files
Compiling files:
src/inlineGet.kt
End of files
Marked as dirty by Kotlin:
src/UsageVal.kt
src/UsageVar.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/module/usage/UsageVal.class
out/production/module/usage/UsageVar.class
End of files
Compiling files:
src/UsageVal.kt
src/UsageVar.kt
End of files
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
================ Step #2 =================
Cleaning output files:
out/production/module/META-INF/module.kotlin_module
out/production/module/inline/InlineSetKt.class
End of files
Compiling files:
src/inlineSet.kt
End of files
Marked as dirty by Kotlin:
src/UsageVar.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/module/usage/UsageVar.class
End of files
Compiling files:
src/UsageVar.kt
End of files
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,16 @@
================ Step #1 =================
Compiling files:
src/UsageVal.kt
src/UsageVar.kt
src/inlineGet.kt
End of files
------------------------------------------
================ Step #2 =================
Compiling files:
src/UsageVar.kt
src/inlineSet.kt
End of files
------------------------------------------
@@ -0,0 +1,37 @@
================ Step #1 =================
Cleaning output files:
out/production/module1/META-INF/module1.kotlin_module
out/production/module1/a/A.class
out/production/module1/a/ClassAnnotation.class
out/production/module1/a/FileAnnotation.class
out/production/module1/a/Module1_aKt.class
End of files
Compiling files:
module1/src/module1_a.kt
End of files
Marked as dirty by Kotlin:
module2/src/module2_b.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/module2/META-INF/module2.kotlin_module
out/production/module2/b/B.class
out/production/module2/b/Module2_bKt.class
End of files
Compiling files:
module2/src/module2_b.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
Cannot access 'FileAnnotation': it is internal in 'a'
Cannot access 'A': it is internal in 'a'
Cannot access 'FileAnnotation': it is internal in 'a'
Cannot access 'ClassAnnotation': it is internal in 'a'
Cannot access 'ClassAnnotation': it is internal in 'a'
Function effective visibility 'public' should be the same or less permissive than its parameter type effective visibility 'internal'
Cannot access 'A': it is internal in 'a'
Cannot access 'a': it is internal in 'a'
@@ -0,0 +1,16 @@
================ Step #1 =================
Compiling files:
module1/src/module1_a.kt
module2/src/module2_b.kt
End of files
------------------------------------------
COMPILATION FAILED
Cannot access 'FileAnnotation': it is internal in 'a'
Cannot access 'A': it is internal in 'a'
Cannot access 'FileAnnotation': it is internal in 'a'
Cannot access 'ClassAnnotation': it is internal in 'a'
Cannot access 'ClassAnnotation': it is internal in 'a'
Function effective visibility 'public' should be the same or less permissive than its parameter type effective visibility 'internal'
Cannot access 'A': it is internal in 'a'
Cannot access 'a': it is internal in 'a'
@@ -0,0 +1,17 @@
================ Step #1 =================
Cleaning output files:
out/production/module/JavaClass.class
out/production/module/META-INF/module.kotlin_module
out/production/module/UsageKt.class
End of files
Compiling files:
src/usage.kt
End of files
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Compiling files:
src/JavaClass.java
End of files
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,7 @@
================ Step #1 =================
Compiling files:
src/usage.kt
src/JavaClass.java
End of files
------------------------------------------