Invalidate usages of removed classes before round
#KT-23165 fixed
This commit is contained in:
@@ -54,13 +54,16 @@ abstract class IncrementalCacheCommon<ClassName>(workingDir: File) : BasicMapsOw
|
||||
internal abstract val sourceToClassesMap: AbstractSourceToOutputMap<ClassName>
|
||||
internal abstract val dirtyOutputClassesMap: AbstractDirtyClassesMap<ClassName>
|
||||
|
||||
fun classesFqNamesBySources(files: Iterable<File>): Collection<FqName> =
|
||||
files.flatMapTo(HashSet()) { sourceToClassesMap.getFqNames(it) }
|
||||
|
||||
fun getSubtypesOf(className: FqName): Sequence<FqName> =
|
||||
subtypesMap[className].asSequence()
|
||||
|
||||
fun getSourceFileIfClass(fqName: FqName): File? =
|
||||
classFqNameToSourceMap[fqName]
|
||||
|
||||
open fun markDirty(removedAndCompiledSources: List<File>) {
|
||||
open fun markDirty(removedAndCompiledSources: Collection<File>) {
|
||||
for (sourceFile in removedAndCompiledSources) {
|
||||
val classes = sourceToClassesMap[sourceFile]
|
||||
classes.forEach {
|
||||
|
||||
@@ -60,7 +60,7 @@ open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon<FqName>(
|
||||
headerFile.writeBytes(value)
|
||||
}
|
||||
|
||||
override fun markDirty(removedAndCompiledSources: List<File>) {
|
||||
override fun markDirty(removedAndCompiledSources: Collection<File>) {
|
||||
super.markDirty(removedAndCompiledSources)
|
||||
dirtySources.addAll(removedAndCompiledSources)
|
||||
}
|
||||
|
||||
@@ -82,6 +82,9 @@ open class IncrementalJvmCache(
|
||||
fun classesBySources(sources: Iterable<File>): Iterable<JvmClassName> =
|
||||
sources.flatMap { sourceToClassesMap[it] }
|
||||
|
||||
fun sourceInCache(file: File): Boolean =
|
||||
sourceToClassesMap.contains(file)
|
||||
|
||||
fun sourcesByInternalName(internalName: String): Collection<File> =
|
||||
internalNameToSource[internalName]
|
||||
|
||||
|
||||
@@ -22,20 +22,27 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
internal interface NameTransformer<Name> {
|
||||
fun asString(name: Name): String
|
||||
fun asName(string: String): Name
|
||||
fun asFqName(string: String): FqName
|
||||
}
|
||||
|
||||
internal object FqNameTransformer : NameTransformer<FqName> {
|
||||
override fun asString(name: FqName): String =
|
||||
name.asString()
|
||||
name.asString()
|
||||
|
||||
override fun asName(string: String): FqName =
|
||||
FqName(string)
|
||||
FqName(string)
|
||||
|
||||
override fun asFqName(string: String): FqName =
|
||||
asName(string)
|
||||
}
|
||||
|
||||
internal object JvmClassNameTransformer : NameTransformer<JvmClassName> {
|
||||
override fun asString(name: JvmClassName): String =
|
||||
name.internalName
|
||||
name.internalName
|
||||
|
||||
override fun asName(string: String): JvmClassName =
|
||||
JvmClassName.byInternalName(string)
|
||||
JvmClassName.byInternalName(string)
|
||||
|
||||
override fun asFqName(string: String): FqName =
|
||||
asName(string).fqNameForClassNameWithoutDollars
|
||||
}
|
||||
@@ -42,6 +42,9 @@ internal abstract class AbstractSourceToOutputMap<Name>(
|
||||
operator fun get(sourceFile: File): Collection<Name> =
|
||||
storage[sourceFile.absolutePath].orEmpty().map(nameTransformer::asName)
|
||||
|
||||
fun getFqNames(sourceFile: File): Collection<FqName> =
|
||||
storage[sourceFile.absolutePath].orEmpty().map(nameTransformer::asFqName)
|
||||
|
||||
override fun dumpValue(value: Collection<String>) =
|
||||
value.dumpCollection()
|
||||
|
||||
|
||||
+25
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.parsing.util.classesFqNames
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
@@ -280,6 +281,30 @@ abstract class IncrementalCompilerRunner<
|
||||
return exitCode
|
||||
}
|
||||
|
||||
protected fun getRemovedClassesChanges(
|
||||
caches: IncrementalCachesManager<*>,
|
||||
changedFiles: ChangedFiles.Known
|
||||
): DirtyData {
|
||||
val removedClasses = HashSet<String>()
|
||||
val dirtyFiles = changedFiles.modified.filterTo(HashSet()) { it.isKotlinFile() }
|
||||
val removedFiles = changedFiles.removed.filterTo(HashSet()) { it.isKotlinFile() }
|
||||
|
||||
val existingClasses = classesFqNames(dirtyFiles)
|
||||
val previousClasses = caches.platformCache
|
||||
.classesFqNamesBySources(dirtyFiles + removedFiles)
|
||||
.map { it.asString() }
|
||||
|
||||
for (fqName in previousClasses) {
|
||||
if (fqName !in existingClasses) {
|
||||
removedClasses.add(fqName)
|
||||
}
|
||||
}
|
||||
|
||||
val changesCollector = ChangesCollector()
|
||||
removedClasses.forEach { changesCollector.collectSignature(FqName(it), areSubclassesAffected = true) }
|
||||
return changesCollector.getDirtyData(listOf(caches.platformCache), reporter)
|
||||
}
|
||||
|
||||
open fun runWithNoDirtyKotlinSources(caches: CacheManager): Boolean = false
|
||||
|
||||
protected open fun processChangesAfterBuild(compilationMode: CompilationMode, currentBuildInfo: BuildInfo, dirtyData: DirtyData) {
|
||||
|
||||
+24
-1
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.js.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.io.File
|
||||
|
||||
fun makeJsIncrementally(
|
||||
@@ -92,7 +93,29 @@ class IncrementalJsCompilerRunner(
|
||||
|
||||
if (changedLib != null) return CompilationMode.Rebuild { "Library has been changed: $changedLib" }
|
||||
|
||||
return CompilationMode.Incremental(getDirtyFiles(changedFiles))
|
||||
val dirtyFiles = getDirtyFiles(changedFiles)
|
||||
|
||||
// todo: unify with JVM calculateSourcesToCompile
|
||||
fun markDirtyBy(lookupSymbols: Collection<LookupSymbol>) {
|
||||
if (lookupSymbols.isEmpty()) return
|
||||
|
||||
val dirtyFilesFromLookups = mapLookupSymbolsToFiles(caches.lookupCache, lookupSymbols, reporter)
|
||||
dirtyFiles.addAll(dirtyFilesFromLookups)
|
||||
}
|
||||
|
||||
fun markDirtyBy(dirtyClassesFqNames: Collection<FqName>) {
|
||||
if (dirtyClassesFqNames.isEmpty()) return
|
||||
|
||||
val fqNamesWithSubtypes = dirtyClassesFqNames.flatMap { withSubtypes(it, listOf(caches.platformCache)) }
|
||||
val dirtyFilesFromFqNames = mapClassesFqNamesToFiles(listOf(caches.platformCache), fqNamesWithSubtypes, reporter)
|
||||
dirtyFiles.addAll(dirtyFilesFromFqNames)
|
||||
}
|
||||
|
||||
val removedClassesChanges = getRemovedClassesChanges(caches, changedFiles)
|
||||
markDirtyBy(removedClassesChanges.dirtyLookupSymbols)
|
||||
markDirtyBy(removedClassesChanges.dirtyClassesFqNames)
|
||||
|
||||
return CompilationMode.Incremental(dirtyFiles)
|
||||
}
|
||||
|
||||
override fun makeServices(
|
||||
|
||||
+8
-1
@@ -141,7 +141,11 @@ class IncrementalJvmCompilerRunner(
|
||||
else
|
||||
null
|
||||
|
||||
override fun calculateSourcesToCompile(caches: IncrementalJvmCachesManager, changedFiles: ChangedFiles.Known, args: K2JVMCompilerArguments): CompilationMode {
|
||||
override fun calculateSourcesToCompile(
|
||||
caches: IncrementalJvmCachesManager,
|
||||
changedFiles: ChangedFiles.Known,
|
||||
args: K2JVMCompilerArguments
|
||||
): CompilationMode {
|
||||
val dirtyFiles = getDirtyFiles(changedFiles)
|
||||
|
||||
fun markDirtyBy(lookupSymbols: Collection<LookupSymbol>) {
|
||||
@@ -214,10 +218,13 @@ class IncrementalJvmCompilerRunner(
|
||||
}
|
||||
|
||||
val androidLayoutChanges = processLookupSymbolsForAndroidLayouts(changedFiles)
|
||||
val removedClassesChanges = getRemovedClassesChanges(caches, changedFiles)
|
||||
|
||||
markDirtyBy(androidLayoutChanges)
|
||||
markDirtyBy(classpathChanges.lookupSymbols)
|
||||
markDirtyBy(classpathChanges.fqNames)
|
||||
markDirtyBy(removedClassesChanges.dirtyLookupSymbols)
|
||||
markDirtyBy(removedClassesChanges.dirtyClassesFqNames)
|
||||
|
||||
return CompilationMode.Incremental(dirtyFiles)
|
||||
}
|
||||
|
||||
+6
@@ -756,6 +756,12 @@ public class IncrementalJsCompilerRunnerTestGenerated extends AbstractIncrementa
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classMovedIntoOtherClass")
|
||||
public void testClassMovedIntoOtherClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/classMovedIntoOtherClass/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classRemoved")
|
||||
public void testClassRemoved() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/classRemoved/");
|
||||
|
||||
+6
@@ -756,6 +756,12 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classMovedIntoOtherClass")
|
||||
public void testClassMovedIntoOtherClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/classMovedIntoOtherClass/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classRemoved")
|
||||
public void testClassRemoved() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/classRemoved/");
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.parsing.util
|
||||
|
||||
import com.intellij.core.CoreApplicationEnvironment
|
||||
import com.intellij.core.CoreProjectEnvironment
|
||||
import com.intellij.lang.MetaLanguage
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.local.CoreLocalFileSystem
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.SingleRootFileViewProvider
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||
import org.jetbrains.kotlin.script.ScriptDefinitionProvider
|
||||
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
fun classesFqNames(files: Set<File>): Set<String> = withPsiSetup {
|
||||
val psiManager = PsiManager.getInstance(project)
|
||||
val fileManager = VirtualFileManager.getInstance()
|
||||
val localFS = fileManager.getFileSystem(StandardFileSystems.FILE_PROTOCOL) as CoreLocalFileSystem
|
||||
|
||||
classesFqNames(files, psiManager, localFS)
|
||||
}
|
||||
|
||||
private fun classesFqNames(files: Collection<File>, psiManager: PsiManager, localFS: CoreLocalFileSystem): Set<String> {
|
||||
val result = HashSet<String>()
|
||||
|
||||
for (file in files) {
|
||||
if (!file.name.endsWith(".kt", ignoreCase = true)) continue
|
||||
|
||||
val virtualFile = localFS.findFileByIoFile(file) ?: continue
|
||||
|
||||
for (psiFile in SingleRootFileViewProvider(psiManager, virtualFile).allFiles) {
|
||||
if (psiFile !is KtFile) continue
|
||||
|
||||
val classes = ArrayDeque<KtClassOrObject>()
|
||||
psiFile.declarations.filterClassesTo(classes)
|
||||
while (classes.isNotEmpty()) {
|
||||
val klass = classes.pollFirst()
|
||||
klass.fqName?.let {
|
||||
result.add(it.asString())
|
||||
}
|
||||
klass.declarations.filterClassesTo(classes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun Collection<KtDeclaration>.filterClassesTo(classes: Deque<KtClassOrObject>) {
|
||||
filterIsInstanceTo<KtClassOrObject, Deque<KtClassOrObject>>(classes)
|
||||
}
|
||||
|
||||
private data class PsiSetup(
|
||||
val applicationEnvironment: CoreApplicationEnvironment,
|
||||
val projectEnvironment: CoreProjectEnvironment,
|
||||
val project: Project,
|
||||
val disposable: Disposable
|
||||
)
|
||||
|
||||
private inline fun <T> withPsiSetup(fn: PsiSetup.() -> T): T {
|
||||
val disposable = Disposer.newDisposable()
|
||||
|
||||
return try {
|
||||
val applicationEnvironment = CoreApplicationEnvironment(disposable, false)
|
||||
val projectEnvironment = CoreProjectEnvironment(disposable, applicationEnvironment)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaLanguage.EP_NAME, MetaLanguage::class.java)
|
||||
applicationEnvironment.registerApplicationService(ScriptDefinitionProvider::class.java, NoopScriptDefinitionProvider())
|
||||
applicationEnvironment.registerFileType(KotlinFileType.INSTANCE, "kt")
|
||||
applicationEnvironment.registerParserDefinition(KotlinParserDefinition())
|
||||
|
||||
val project = projectEnvironment.project
|
||||
val setup = PsiSetup(applicationEnvironment, projectEnvironment, project, disposable)
|
||||
setup.fn()
|
||||
} finally {
|
||||
Disposer.dispose(disposable)
|
||||
}
|
||||
}
|
||||
|
||||
private class NoopScriptDefinitionProvider : ScriptDefinitionProvider {
|
||||
override fun isScript(fileName: String): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun findScriptDefinition(fileName: String): KotlinScriptDefinition? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.parsing.utils
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import org.jetbrains.kotlin.parsing.util.classesFqNames
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ClassesFqNamesTest {
|
||||
private lateinit var workingDir: File
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
workingDir = FileUtil.createTempDirectory("ClassesFqNamesTest", null)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
workingDir.deleteRecursively()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSingleClass() {
|
||||
doTest(
|
||||
setOf("test.Foo"),
|
||||
"""
|
||||
package test
|
||||
|
||||
class Foo""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMultipleClasses() {
|
||||
doTest(
|
||||
setOf("test.Fizz", "test.Buzz"),
|
||||
"""
|
||||
package test
|
||||
|
||||
class Fizz
|
||||
class Buzz""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInnerClasses() {
|
||||
doTest(
|
||||
setOf("test.Foo", "test.Foo.Fizz", "test.Foo.Buzz"),
|
||||
"""
|
||||
package test
|
||||
|
||||
class Foo {
|
||||
class Fizz
|
||||
class Buzz
|
||||
}""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testObject() {
|
||||
doTest(
|
||||
setOf("test.Foo", "test.Foo.Fizz", "test.Bar", "test.Bar.Buzz"),
|
||||
"""
|
||||
package test
|
||||
|
||||
object Foo {
|
||||
class Fizz
|
||||
}
|
||||
|
||||
class Bar {
|
||||
object Buzz
|
||||
}""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
private fun doTest(expectedClasses: Set<String>, code: String) {
|
||||
val testKt = File(workingDir, "test.kt")
|
||||
testKt.writeText(code)
|
||||
|
||||
val expected = expectedClasses.sorted().joinToString("\n")
|
||||
val actual = classesFqNames(setOf(testKt)).sorted().joinToString("\n")
|
||||
UsefulTestCase.assertEquals(expected, actual)
|
||||
}
|
||||
}
|
||||
+26
-13
@@ -425,8 +425,8 @@ abstract class AbstractIncrementalJpsTest(
|
||||
override fun doGetProjectDir(): File? = workDir
|
||||
|
||||
private class MyLogger(val rootPath: String) : ProjectBuilderLoggerBase(), BuildLogger {
|
||||
|
||||
private val dirtyFiles = ArrayList<File>()
|
||||
private val markedDirtyBeforeRound = ArrayList<File>()
|
||||
private val markedDirtyAfterRound = ArrayList<File>()
|
||||
|
||||
override fun actionsOnCacheVersionChanged(actions: List<CacheVersion.Action>) {
|
||||
if (actions.size > 1 && actions.any { it != CacheVersion.Action.DO_NOTHING }) {
|
||||
@@ -434,8 +434,12 @@ abstract class AbstractIncrementalJpsTest(
|
||||
}
|
||||
}
|
||||
|
||||
override fun markedAsDirty(files: Iterable<File>) {
|
||||
dirtyFiles.addAll(files)
|
||||
override fun markedAsDirtyBeforeRound(files: Iterable<File>) {
|
||||
markedDirtyBeforeRound.addAll(files)
|
||||
}
|
||||
|
||||
override fun markedAsDirtyAfterRound(files: Iterable<File>) {
|
||||
markedDirtyAfterRound.addAll(files)
|
||||
}
|
||||
|
||||
override fun buildStarted(context: CompileContext, chunk: ModuleChunk) {
|
||||
@@ -444,20 +448,29 @@ abstract class AbstractIncrementalJpsTest(
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildFinished(exitCode: ModuleLevelBuilder.ExitCode) {
|
||||
override fun afterBuildStarted(context: CompileContext, chunk: ModuleChunk) {
|
||||
logDirtyFiles(markedDirtyBeforeRound)
|
||||
}
|
||||
|
||||
if (dirtyFiles.isNotEmpty()) {
|
||||
logLine("Marked as dirty by Kotlin:")
|
||||
dirtyFiles
|
||||
.map { FileUtil.toSystemIndependentName(it.path) }
|
||||
.sorted()
|
||||
.forEach { logLine(it) }
|
||||
dirtyFiles.clear()
|
||||
}
|
||||
override fun buildFinished(exitCode: ModuleLevelBuilder.ExitCode) {
|
||||
logDirtyFiles(markedDirtyAfterRound)
|
||||
logLine("Exit code: $exitCode")
|
||||
logLine("------------------------------------------")
|
||||
}
|
||||
|
||||
private fun logDirtyFiles(files: MutableList<File>) {
|
||||
if (files.isEmpty()) return
|
||||
|
||||
logLine("Marked as dirty by Kotlin:")
|
||||
files.apply {
|
||||
map { FileUtil.toSystemIndependentName(it.path) }
|
||||
.sorted()
|
||||
.forEach { logLine(it) }
|
||||
|
||||
clear()
|
||||
}
|
||||
}
|
||||
|
||||
private val logBuf = StringBuilder()
|
||||
val log: String
|
||||
get() = logBuf.toString()
|
||||
|
||||
+6
@@ -1494,6 +1494,12 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classMovedIntoOtherClass")
|
||||
public void testClassMovedIntoOtherClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/classMovedIntoOtherClass/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classRemoved")
|
||||
public void testClassRemoved() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/classRemoved/");
|
||||
|
||||
@@ -956,16 +956,18 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
||||
|
||||
val actual = StringBuilder()
|
||||
buildCustom(CanceledStatus.NULL, TestProjectBuilderLogger(), BuildResult()) {
|
||||
project.setTestingContext(TestingContext(LookupTracker.DO_NOTHING, object: BuildLogger {
|
||||
project.setTestingContext(TestingContext(LookupTracker.DO_NOTHING, object : BuildLogger {
|
||||
override fun buildStarted(context: CompileContext, chunk: ModuleChunk) {
|
||||
actual.append("Targets dependent on ${chunk.targets.joinToString() }:\n")
|
||||
actual.append(getDependentTargets(chunk, context).map { it.toString() }.sorted().joinToString("\n"))
|
||||
actual.append("\n---------\n")
|
||||
}
|
||||
|
||||
override fun afterBuildStarted(context: CompileContext, chunk: ModuleChunk) {}
|
||||
override fun actionsOnCacheVersionChanged(actions: List<CacheVersion.Action>) {}
|
||||
override fun buildFinished(exitCode: ModuleLevelBuilder.ExitCode) {}
|
||||
override fun markedAsDirty(files: Iterable<File>) {}
|
||||
override fun markedAsDirtyBeforeRound(files: Iterable<File>) {}
|
||||
override fun markedAsDirtyAfterRound(files: Iterable<File>) {}
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,9 @@ import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
import java.lang.ref.SoftReference
|
||||
import java.util.ArrayList
|
||||
import java.util.Arrays
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
object CompilerRunnerUtil {
|
||||
private var ourClassLoaderRef = SoftReference<ClassLoader>(null)
|
||||
@@ -90,21 +89,7 @@ object CompilerRunnerUtil {
|
||||
arguments: Array<String>,
|
||||
environment: JpsCompilerEnvironment,
|
||||
out: PrintStream
|
||||
): Any? {
|
||||
val libPath = getLibPath(environment.kotlinPaths, environment.messageCollector) ?: return null
|
||||
|
||||
val paths = ArrayList<File>()
|
||||
paths.add(File(libPath, "kotlin-compiler.jar"))
|
||||
|
||||
if (Arrays.asList(*arguments).contains("-Xuse-javac")) {
|
||||
val toolsJar = jdkToolsJar
|
||||
if (toolsJar != null) {
|
||||
paths.add(toolsJar)
|
||||
}
|
||||
}
|
||||
|
||||
val classLoader = getOrCreateClassLoader(environment, paths)
|
||||
|
||||
): Any? = withCompilerClassloader(environment) { classLoader ->
|
||||
val kompiler = Class.forName(compilerClassName, true, classLoader)
|
||||
val exec = kompiler.getMethod(
|
||||
"execAndOutputXml",
|
||||
@@ -112,7 +97,30 @@ object CompilerRunnerUtil {
|
||||
Class.forName("org.jetbrains.kotlin.config.Services", true, classLoader),
|
||||
Array<String>::class.java
|
||||
)
|
||||
exec.invoke(kompiler.newInstance(), out, environment.services, arguments)
|
||||
}
|
||||
|
||||
return exec.invoke(kompiler.newInstance(), out, environment.services, arguments)
|
||||
fun invokeClassesFqNames(
|
||||
files: Set<File>,
|
||||
environment: JpsCompilerEnvironment
|
||||
): Set<String> = withCompilerClassloader(environment) { classLoader ->
|
||||
val klass = Class.forName("org.jetbrains.kotlin.parsing.util.ParseFileUtilsKt", true, classLoader)
|
||||
val method = klass.getMethod("classesFqNames", Set::class.java)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
method.invoke(klass, files) as? Set<String>
|
||||
} ?: emptySet()
|
||||
|
||||
private fun <T> withCompilerClassloader(
|
||||
environment: JpsCompilerEnvironment,
|
||||
fn: (ClassLoader) -> T
|
||||
): T? {
|
||||
val paths = SmartList<File>()
|
||||
|
||||
val libPath = getLibPath(environment.kotlinPaths, environment.messageCollector) ?: return null
|
||||
paths.add(File(libPath, "kotlin-compiler.jar"))
|
||||
jdkToolsJar?.let { paths.add(it) }
|
||||
|
||||
val classLoader = getOrCreateClassLoader(environment, paths)
|
||||
return fn(classLoader)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import java.io.File
|
||||
interface BuildLogger {
|
||||
fun actionsOnCacheVersionChanged(actions: List<CacheVersion.Action>)
|
||||
fun buildStarted(context: CompileContext, chunk: ModuleChunk)
|
||||
fun afterBuildStarted(context: CompileContext, chunk: ModuleChunk)
|
||||
fun buildFinished(exitCode: ModuleLevelBuilder.ExitCode)
|
||||
fun markedAsDirty(files: Iterable<File>)
|
||||
fun markedAsDirtyBeforeRound(files: Iterable<File>)
|
||||
fun markedAsDirtyAfterRound(files: Iterable<File>)
|
||||
}
|
||||
|
||||
@@ -58,26 +58,39 @@ class FSOperationsHelper(
|
||||
}
|
||||
}
|
||||
|
||||
fun markFilesBeforeInitialRound(files: Iterable<File>) {
|
||||
markFilesImpl(files, beforeRound = true) { it.exists() && moduleBasedFilter.accept(it) }
|
||||
}
|
||||
|
||||
fun markFiles(files: Iterable<File>) {
|
||||
markFilesImpl(files) { it.exists() }
|
||||
markFilesImpl(files, beforeRound = false) { it.exists() }
|
||||
}
|
||||
|
||||
fun markInChunkOrDependents(files: Iterable<File>, excludeFiles: Set<File>) {
|
||||
markFilesImpl(files) { it !in excludeFiles && it.exists() && moduleBasedFilter.accept(it) }
|
||||
markFilesImpl(files, beforeRound = false) { it !in excludeFiles && it.exists() && moduleBasedFilter.accept(it) }
|
||||
}
|
||||
|
||||
private inline fun markFilesImpl(files: Iterable<File>, shouldMark: (File) -> Boolean) {
|
||||
private inline fun markFilesImpl(
|
||||
files: Iterable<File>,
|
||||
beforeRound: Boolean,
|
||||
shouldMark: (File) -> Boolean
|
||||
) {
|
||||
val filesToMark = files.filterTo(HashSet(), shouldMark)
|
||||
|
||||
if (filesToMark.isEmpty()) return
|
||||
|
||||
for (fileToMark in filesToMark) {
|
||||
FSOperations.markDirty(compileContext, CompilationRound.NEXT, fileToMark)
|
||||
val compilationRound = if (beforeRound) {
|
||||
buildLogger?.markedAsDirtyBeforeRound(filesToMark)
|
||||
CompilationRound.CURRENT
|
||||
} else {
|
||||
buildLogger?.markedAsDirtyAfterRound(filesToMark)
|
||||
hasMarkedDirty = true
|
||||
CompilationRound.NEXT
|
||||
}
|
||||
|
||||
log.debug("Mark dirty: $filesToMark")
|
||||
buildLogger?.markedAsDirty(filesToMark)
|
||||
hasMarkedDirty = true
|
||||
for (fileToMark in filesToMark) {
|
||||
FSOperations.markDirty(compileContext, compilationRound, fileToMark)
|
||||
}
|
||||
log.debug("Mark dirty: $filesToMark ($compilationRound)")
|
||||
}
|
||||
|
||||
// Based on `JavaBuilderUtil#ModulesBasedFileFilter` from Intellij
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
@@ -25,10 +26,14 @@ import gnu.trove.THashSet
|
||||
import org.jetbrains.jps.ModuleChunk
|
||||
import org.jetbrains.jps.builders.BuildTarget
|
||||
import org.jetbrains.jps.builders.DirtyFilesHolder
|
||||
import org.jetbrains.jps.builders.FileProcessor
|
||||
import org.jetbrains.jps.builders.impl.DirtyFilesHolderBase
|
||||
import org.jetbrains.jps.builders.java.JavaBuilderUtil
|
||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
|
||||
import org.jetbrains.jps.incremental.*
|
||||
import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.*
|
||||
import org.jetbrains.jps.incremental.Utils.*
|
||||
import org.jetbrains.jps.incremental.fs.CompilationRound
|
||||
import org.jetbrains.jps.incremental.java.JavaBuilder
|
||||
import org.jetbrains.jps.incremental.messages.BuildMessage
|
||||
import org.jetbrains.jps.incremental.messages.CompilerMessage
|
||||
@@ -60,10 +65,12 @@ import org.jetbrains.kotlin.jps.testOutputFilePath
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.preloading.ClassCondition
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledException
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.utils.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
@@ -120,7 +127,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
|
||||
if (chunk.isDummy(context)) return
|
||||
|
||||
context.testingContext?.buildLogger?.buildStarted(context, chunk)
|
||||
val buildLogger = context.testingContext?.buildLogger
|
||||
buildLogger?.buildStarted(context, chunk)
|
||||
|
||||
if (JavaBuilderUtil.isForcedRecompilationAllJavaModules(context)) return
|
||||
|
||||
@@ -151,7 +159,52 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
// todo: report to Intellij when IDEA-187115 is implemented
|
||||
LOG.info(e)
|
||||
markAllKotlinForRebuild(context, fsOperations, "Lookup storage is corrupted")
|
||||
return
|
||||
}
|
||||
|
||||
markAdditionalFilesForInitialRound(chunk, context, fsOperations)
|
||||
buildLogger?.afterBuildStarted(context, chunk)
|
||||
}
|
||||
|
||||
private fun markAdditionalFilesForInitialRound(
|
||||
chunk: ModuleChunk,
|
||||
context: CompileContext,
|
||||
fsOperations: FSOperationsHelper
|
||||
) {
|
||||
val dirtyFilesHolder = object : DirtyFilesHolderBase<JavaSourceRootDescriptor, ModuleBuildTarget>(context) {
|
||||
override fun processDirtyFiles(processor: FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>) {
|
||||
FSOperations.processFilesToRecompile(context, chunk, processor)
|
||||
}
|
||||
}
|
||||
val chunkDirtyFiles = KotlinSourceFileCollector.getDirtySourceFiles(dirtyFilesHolder)
|
||||
val chunkRemovedFiles = chunk.targets.keysToMap { KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, it) }
|
||||
|
||||
val incrementalCaches = getIncrementalCaches(chunk, context)
|
||||
val messageCollector = MessageCollectorAdapter(context)
|
||||
val environment = createCompileEnvironment(incrementalCaches, LookupTracker.DO_NOTHING, context, messageCollector)
|
||||
if (environment == null) return
|
||||
|
||||
val removedClasses = HashSet<String>()
|
||||
for (target in chunk.targets) {
|
||||
val cache = incrementalCaches[target]!!
|
||||
val dirtyFiles = chunkDirtyFiles[target]
|
||||
val removedFiles = chunkRemovedFiles[target] ?: emptyList()
|
||||
|
||||
val existingClasses = CompilerRunnerUtil.invokeClassesFqNames(dirtyFiles.toHashSet(), environment)
|
||||
val previousClasses = cache.classesBySources(dirtyFiles + removedFiles)
|
||||
for (jvmClassName in previousClasses) {
|
||||
val fqName = jvmClassName.fqNameForClassNameWithoutDollars.asString()
|
||||
if (fqName !in existingClasses) {
|
||||
removedClasses.add(fqName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val changesCollector = ChangesCollector()
|
||||
removedClasses.forEach { changesCollector.collectSignature(FqName(it), areSubclassesAffected = true) }
|
||||
val affectedByRemovedClasses = changesCollector.getDirtyFiles(incrementalCaches.values, context.projectDescriptor.dataManager)
|
||||
|
||||
fsOperations.markFilesBeforeInitialRound(affectedByRemovedClasses)
|
||||
}
|
||||
|
||||
private fun checkCachesVersions(
|
||||
@@ -873,16 +926,24 @@ private fun ChangesCollector.processChangesUsingLookups(
|
||||
|
||||
reporter.report { "Start processing changes" }
|
||||
|
||||
val (dirtyLookupSymbols, dirtyClassFqNames) = getDirtyData(allCaches, reporter)
|
||||
val dirtyFilesFromLookups = dataManager.withLookupStorage {
|
||||
mapLookupSymbolsToFiles(it, dirtyLookupSymbols, reporter)
|
||||
}
|
||||
val dirtyFiles = dirtyFilesFromLookups + mapClassesFqNamesToFiles(allCaches, dirtyClassFqNames, reporter)
|
||||
val dirtyFiles = getDirtyFiles(allCaches, dataManager)
|
||||
fsOperations.markInChunkOrDependents(dirtyFiles.asIterable(), excludeFiles = compiledFiles)
|
||||
|
||||
reporter.report { "End of processing changes" }
|
||||
}
|
||||
|
||||
private fun ChangesCollector.getDirtyFiles(
|
||||
caches: Iterable<IncrementalCacheCommon<*>>,
|
||||
dataManager: BuildDataManager
|
||||
): Set<File> {
|
||||
val reporter = JpsICReporter()
|
||||
val (dirtyLookupSymbols, dirtyClassFqNames) = getDirtyData(caches, reporter)
|
||||
val dirtyFilesFromLookups = dataManager.withLookupStorage {
|
||||
mapLookupSymbolsToFiles(it, dirtyLookupSymbols, reporter)
|
||||
}
|
||||
return dirtyFilesFromLookups + mapClassesFqNamesToFiles(caches, dirtyClassFqNames, reporter)
|
||||
}
|
||||
|
||||
private fun getLookupTracker(project: JpsProject): LookupTracker {
|
||||
val testLookupTracker = project.testingContext?.lookupTracker ?: LookupTracker.DO_NOTHING
|
||||
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
open class A {
|
||||
}
|
||||
|
||||
open class X {
|
||||
open fun f() {}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
open class A {
|
||||
open class X {
|
||||
open fun g() {}
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
open class B : A() {
|
||||
open inner class Y : X()
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
open class C : B() {
|
||||
open inner class Z : Y() {
|
||||
override fun f() {}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
open class C : B() {
|
||||
open inner class Z : Y() {
|
||||
override fun g() {}
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
================ Step #1 =================
|
||||
|
||||
Marked as dirty by Kotlin:
|
||||
src/A.kt
|
||||
src/B.kt
|
||||
src/C.kt
|
||||
Cleaning output files:
|
||||
out/production/module/A.class
|
||||
out/production/module/B$Y.class
|
||||
out/production/module/B.class
|
||||
out/production/module/C$Z.class
|
||||
out/production/module/C.class
|
||||
out/production/module/X.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.kt
|
||||
src/B.kt
|
||||
src/C.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
------------------------------------------
|
||||
+22
-21
@@ -3,16 +3,35 @@
|
||||
Cleaning output files:
|
||||
out/production/module/foo/A.class
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/B.kt
|
||||
src/C.kt
|
||||
src/createA.kt
|
||||
src/createB.kt
|
||||
src/createC.kt
|
||||
src/useAfoo.kt
|
||||
src/useBbar.kt
|
||||
src/useCbaz.kt
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/foo/B.class
|
||||
out/production/module/foo/C.class
|
||||
out/production/module/use/CreateAKt.class
|
||||
out/production/module/use/CreateBKt.class
|
||||
out/production/module/use/CreateCKt.class
|
||||
out/production/module/use/UseAfooKt.class
|
||||
out/production/module/use/UseBbarKt.class
|
||||
out/production/module/use/UseCbazKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/B.kt
|
||||
src/C.kt
|
||||
src/createA.kt
|
||||
src/createB.kt
|
||||
src/createC.kt
|
||||
src/useAfoo.kt
|
||||
src/useBbar.kt
|
||||
src/useCbaz.kt
|
||||
End of files
|
||||
Exit code: ABORT
|
||||
------------------------------------------
|
||||
@@ -24,30 +43,12 @@ Unresolved reference: A
|
||||
|
||||
Compiling files:
|
||||
src/B.kt
|
||||
src/C.kt
|
||||
src/createA.kt
|
||||
src/createB.kt
|
||||
src/createC.kt
|
||||
src/funA.kt
|
||||
src/useAfoo.kt
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/C.kt
|
||||
src/createB.kt
|
||||
src/createC.kt
|
||||
src/useBbar.kt
|
||||
src/useCbaz.kt
|
||||
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||
------------------------------------------
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/foo/C.class
|
||||
out/production/module/use/CreateBKt.class
|
||||
out/production/module/use/CreateCKt.class
|
||||
out/production/module/use/UseBbarKt.class
|
||||
out/production/module/use/UseCbazKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/C.kt
|
||||
src/createB.kt
|
||||
src/createC.kt
|
||||
src/useBbar.kt
|
||||
src/useCbaz.kt
|
||||
End of files
|
||||
|
||||
+12
@@ -3,16 +3,26 @@
|
||||
Cleaning output files:
|
||||
out/production/module/foo/A.class
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/B.kt
|
||||
src/createA.kt
|
||||
src/createB.kt
|
||||
src/useAfoo.kt
|
||||
src/useBbar.kt
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/foo/B.class
|
||||
out/production/module/use/CreateAKt.class
|
||||
out/production/module/use/CreateBKt.class
|
||||
out/production/module/use/UseAfooKt.class
|
||||
out/production/module/use/UseBbarKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/B.kt
|
||||
src/createA.kt
|
||||
src/createB.kt
|
||||
src/useAfoo.kt
|
||||
src/useBbar.kt
|
||||
End of files
|
||||
Exit code: ABORT
|
||||
------------------------------------------
|
||||
@@ -26,7 +36,9 @@ Compiling files:
|
||||
src/A.kt
|
||||
src/B.kt
|
||||
src/createA.kt
|
||||
src/createB.kt
|
||||
src/useAfoo.kt
|
||||
src/useBbar.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
------------------------------------------
|
||||
|
||||
Vendored
+13
-16
@@ -1,28 +1,19 @@
|
||||
================ Step #1 =================
|
||||
|
||||
Cleaning output files:
|
||||
out/production/module/A$Companion.class
|
||||
out/production/module/A.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.kt
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/companionExtension.kt
|
||||
src/companionReferenceExplicit.kt
|
||||
src/companionReferenceImplicit.kt
|
||||
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||
------------------------------------------
|
||||
Cleaning output files:
|
||||
out/production/module/A$Companion.class
|
||||
out/production/module/A.class
|
||||
out/production/module/CompanionExtensionKt.class
|
||||
out/production/module/CompanionReferenceExplicitKt.class
|
||||
out/production/module/CompanionReferenceImplicitKt.class
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.kt
|
||||
src/companionExtension.kt
|
||||
src/companionReferenceExplicit.kt
|
||||
src/companionReferenceImplicit.kt
|
||||
End of files
|
||||
Exit code: ABORT
|
||||
------------------------------------------
|
||||
@@ -32,14 +23,20 @@ Unresolved reference: Companion
|
||||
|
||||
================ Step #2 =================
|
||||
|
||||
Cleaning output files:
|
||||
out/production/module/A$AA.class
|
||||
out/production/module/A.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.kt
|
||||
src/companionExtension.kt
|
||||
src/companionReferenceExplicit.kt
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/companionReferenceImplicit.kt
|
||||
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||
------------------------------------------
|
||||
Cleaning output files:
|
||||
out/production/module/CompanionReferenceImplicitKt.class
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
End of files
|
||||
Compiling files:
|
||||
src/companionReferenceImplicit.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
|
||||
Vendored
-22
@@ -1,22 +0,0 @@
|
||||
================ Step #1 =================
|
||||
|
||||
Compiling files:
|
||||
src/A.kt
|
||||
src/companionExtension.kt
|
||||
src/companionReferenceExplicit.kt
|
||||
src/companionReferenceImplicit.kt
|
||||
End of files
|
||||
Exit code: ABORT
|
||||
------------------------------------------
|
||||
COMPILATION FAILED
|
||||
Unresolved reference: Companion
|
||||
Unresolved reference: Companion
|
||||
|
||||
================ Step #2 =================
|
||||
|
||||
Compiling files:
|
||||
src/companionExtension.kt
|
||||
src/companionReferenceExplicit.kt
|
||||
src/companionReferenceImplicit.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
================ Step #1 =================
|
||||
|
||||
Compiling files:
|
||||
src/Enum.kt
|
||||
src/use.kt
|
||||
End of files
|
||||
Exit code: ABORT
|
||||
------------------------------------------
|
||||
COMPILATION FAILED
|
||||
Unresolved reference: C
|
||||
|
||||
================ Step #2 =================
|
||||
|
||||
Compiling files:
|
||||
src/Enum.kt
|
||||
src/getRandomEnumEntry.kt
|
||||
src/use.kt
|
||||
src/useEnumImplicitly.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
@@ -7,16 +7,26 @@ Cleaning output files:
|
||||
out/production/module2/foo/A.class
|
||||
End of files
|
||||
Building module2
|
||||
Marked as dirty by Kotlin:
|
||||
module2/src/B.kt
|
||||
module2/src/createA.kt
|
||||
module2/src/createB.kt
|
||||
module2/src/useAfoo.kt
|
||||
module2/src/useBbar.kt
|
||||
Cleaning output files:
|
||||
out/production/module2/META-INF/module2.kotlin_module
|
||||
out/production/module2/foo/B.class
|
||||
out/production/module2/use/CreateAKt.class
|
||||
out/production/module2/use/CreateBKt.class
|
||||
out/production/module2/use/UseAfooKt.class
|
||||
out/production/module2/use/UseBbarKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
module2/src/B.kt
|
||||
module2/src/createA.kt
|
||||
module2/src/createB.kt
|
||||
module2/src/useAfoo.kt
|
||||
module2/src/useBbar.kt
|
||||
End of files
|
||||
Exit code: ABORT
|
||||
------------------------------------------
|
||||
@@ -32,20 +42,8 @@ Building module2
|
||||
Compiling files:
|
||||
module2/src/B.kt
|
||||
module2/src/createA.kt
|
||||
module2/src/createB.kt
|
||||
module2/src/useAfoo.kt
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
module2/src/createB.kt
|
||||
module2/src/useBbar.kt
|
||||
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||
------------------------------------------
|
||||
Cleaning output files:
|
||||
out/production/module2/META-INF/module2.kotlin_module
|
||||
out/production/module2/use/CreateBKt.class
|
||||
out/production/module2/use/UseBbarKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
module2/src/createB.kt
|
||||
module2/src/useBbar.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
|
||||
@@ -17,6 +17,8 @@ Cleaning output files:
|
||||
out/production/module2/b/BKt.class
|
||||
End of files
|
||||
Building module2
|
||||
Marked as dirty by Kotlin:
|
||||
module2/src/useClassB.kt
|
||||
Cleaning output files:
|
||||
out/production/module2/usage/UseClassBKt.class
|
||||
out/production/module2/usage/UseFunBKt.class
|
||||
|
||||
Vendored
+2
@@ -1,6 +1,8 @@
|
||||
================ Step #1 =================
|
||||
|
||||
Building module1
|
||||
Marked as dirty by Kotlin:
|
||||
module1/src/a.kt
|
||||
Cleaning output files:
|
||||
out/production/module1/META-INF/module1.kotlin_module
|
||||
out/production/module1/a/A.class
|
||||
|
||||
Vendored
+3
@@ -1,5 +1,8 @@
|
||||
================ Step #1 =================
|
||||
|
||||
Marked as dirty by Kotlin:
|
||||
src/other.kt
|
||||
src/usage.kt
|
||||
Cleaning output files:
|
||||
out/production/module/B.class
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
|
||||
+2
@@ -5,6 +5,8 @@ Cleaning output files:
|
||||
out/production/module/foo/AKt.class
|
||||
out/production/module/foo/Foo.class
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/useClass.kt
|
||||
Cleaning output files:
|
||||
out/production/module/baz/UseClassKt.class
|
||||
out/production/module/baz/UseFunKt.class
|
||||
|
||||
Vendored
+3
-12
@@ -1,12 +1,5 @@
|
||||
================ Step #1 =================
|
||||
|
||||
Cleaning output files:
|
||||
out/production/module/foo/A$Companion.class
|
||||
out/production/module/foo/A.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.kt
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/getACompanion.kt
|
||||
src/getACompanionShort.kt
|
||||
@@ -14,10 +7,10 @@ Marked as dirty by Kotlin:
|
||||
src/useACompanionShortImplicitly.kt
|
||||
src/useAbarWithImplicitReceiver.kt
|
||||
src/useAfooWithImplicitReceiver.kt
|
||||
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||
------------------------------------------
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/foo/A$Companion.class
|
||||
out/production/module/foo/A.class
|
||||
out/production/module/use/GetACompanionKt.class
|
||||
out/production/module/use/GetACompanionShortKt.class
|
||||
out/production/module/use/UseACompanionImplicitlyKt.class
|
||||
@@ -26,6 +19,7 @@ Cleaning output files:
|
||||
out/production/module/use/UseAfooWithImplicitReceiverKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.kt
|
||||
src/getACompanion.kt
|
||||
src/getACompanionShort.kt
|
||||
src/useACompanionImplicitly.kt
|
||||
@@ -41,9 +35,6 @@ Classifier 'A' does not have a companion object, and thus must be initialized he
|
||||
|
||||
================ Step #2 =================
|
||||
|
||||
Cleaning output files:
|
||||
out/production/module/foo/A.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.kt
|
||||
src/getACompanion.kt
|
||||
|
||||
@@ -3,23 +3,17 @@
|
||||
Cleaning output files:
|
||||
out/production/module/foo/A.class
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/use/UseAKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/useA.kt
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/funA.kt
|
||||
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||
------------------------------------------
|
||||
src/useA.kt
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/foo/FunAKt.class
|
||||
out/production/module/use/UseAKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/funA.kt
|
||||
src/useA.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
------------------------------------------
|
||||
|
||||
+5
-11
@@ -3,23 +3,17 @@
|
||||
Cleaning output files:
|
||||
out/production/module/A.class
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/funA.kt
|
||||
src/useA.kt
|
||||
Cleaning output files:
|
||||
out/production/module/FunAKt.class
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/UseAKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/funA.kt
|
||||
src/useA.kt
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/funA.kt
|
||||
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||
------------------------------------------
|
||||
Cleaning output files:
|
||||
out/production/module/FunAKt.class
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
End of files
|
||||
Compiling files:
|
||||
src/funA.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
------------------------------------------
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
================ Step #1 =================
|
||||
|
||||
Marked as dirty by Kotlin:
|
||||
src/A.kt
|
||||
src/funs.kt
|
||||
src/useA.kt
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/foo/A.class
|
||||
out/production/module/foo/FunsKt.class
|
||||
out/production/module/use/UseAKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.kt
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/funs.kt
|
||||
src/useA.kt
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/useB.kt
|
||||
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||
------------------------------------------
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/foo/FunsKt.class
|
||||
out/production/module/use/UseAKt.class
|
||||
out/production/module/use/UseBKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/funs.kt
|
||||
src/useA.kt
|
||||
src/useB.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
|
||||
Vendored
+2
@@ -19,6 +19,8 @@ Exit code: OK
|
||||
Cleaning output files:
|
||||
out/production/module/Foo.class
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/usage.kt
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/UsageKt.class
|
||||
|
||||
Vendored
+2
@@ -3,6 +3,8 @@
|
||||
Cleaning output files:
|
||||
out/production/module/TheClass.class
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/usageInKotlin.kt
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/Usage.class
|
||||
|
||||
+13
-13
@@ -4,22 +4,34 @@ Cleaning output files:
|
||||
out/production/module/A$Companion.class
|
||||
out/production/module/A.class
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/AChild.kt
|
||||
src/getA.kt
|
||||
src/getAChild.kt
|
||||
src/useF.kt
|
||||
src/useG.kt
|
||||
src/useH.kt
|
||||
src/useJ.kt
|
||||
Cleaning output files:
|
||||
out/production/module/AChild.class
|
||||
out/production/module/GetAChildKt.class
|
||||
out/production/module/GetAKt.class
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/UseFKt.class
|
||||
out/production/module/UseGKt.class
|
||||
out/production/module/UseHKt.class
|
||||
out/production/module/UseJKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/AChild.kt
|
||||
src/APartF.kt
|
||||
src/APartG.kt
|
||||
src/getA.kt
|
||||
src/getAChild.kt
|
||||
src/useF.kt
|
||||
src/useG.kt
|
||||
src/useH.kt
|
||||
src/useJ.kt
|
||||
End of files
|
||||
Exit code: ABORT
|
||||
------------------------------------------
|
||||
@@ -35,21 +47,9 @@ Compiling files:
|
||||
src/AChild.kt
|
||||
src/APartF.kt
|
||||
src/APartG.kt
|
||||
src/getAChild.kt
|
||||
src/useF.kt
|
||||
src/useG.kt
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/getAChild.kt
|
||||
src/useJ.kt
|
||||
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||
------------------------------------------
|
||||
Cleaning output files:
|
||||
out/production/module/GetAChildKt.class
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/UseJKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/getAChild.kt
|
||||
src/useJ.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
================ Step #1 =================
|
||||
|
||||
Compiling files:
|
||||
src/AChild.kt
|
||||
src/APartF.kt
|
||||
src/APartG.kt
|
||||
src/getA.kt
|
||||
src/getAChild.kt
|
||||
src/useF.kt
|
||||
src/useG.kt
|
||||
src/useH.kt
|
||||
src/useJ.kt
|
||||
End of files
|
||||
Exit code: ABORT
|
||||
------------------------------------------
|
||||
COMPILATION FAILED
|
||||
Unresolved reference: A
|
||||
Unresolved reference: A
|
||||
Unresolved reference: A
|
||||
Unresolved reference: A
|
||||
|
||||
================ Step #2 =================
|
||||
|
||||
Compiling files:
|
||||
src/AChild.kt
|
||||
src/getAChild.kt
|
||||
src/useF.kt
|
||||
src/useG.kt
|
||||
src/useJ.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
|
||||
Reference in New Issue
Block a user