Refine dirty files computation in case of Java source changes
#KT-17621 In Progress
This commit is contained in:
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
|||||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
||||||
@@ -54,6 +55,7 @@ open class IncrementalJvmCache(
|
|||||||
private val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
|
private val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
|
||||||
private val INLINE_FUNCTIONS = "inline-functions"
|
private val INLINE_FUNCTIONS = "inline-functions"
|
||||||
private val INTERNAL_NAME_TO_SOURCE = "internal-name-to-source"
|
private val INTERNAL_NAME_TO_SOURCE = "internal-name-to-source"
|
||||||
|
private val JAVA_SOURCES_PROTO_MAP = "java-sources-proto-map"
|
||||||
|
|
||||||
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
|
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
|
||||||
}
|
}
|
||||||
@@ -68,6 +70,7 @@ open class IncrementalJvmCache(
|
|||||||
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
|
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
|
||||||
// todo: try to use internal names only?
|
// todo: try to use internal names only?
|
||||||
private val internalNameToSource = registerMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile))
|
private val internalNameToSource = registerMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile))
|
||||||
|
private val javaSourcesProtoMap = registerMap(JavaSourcesProtoMap(JAVA_SOURCES_PROTO_MAP.storageFile))
|
||||||
|
|
||||||
private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(targetOutputDir) { "Target is expected to have output directory" } }
|
private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(targetOutputDir) { "Target is expected to have output directory" } }
|
||||||
|
|
||||||
@@ -169,6 +172,28 @@ open class IncrementalJvmCache(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun saveJavaClassProto(source: File, serializedJavaClass: SerializedJavaClass, collector: ChangesCollector) {
|
||||||
|
val jvmClassName = JvmClassName.byClassId(serializedJavaClass.classId)
|
||||||
|
javaSourcesProtoMap.process(jvmClassName, serializedJavaClass, collector)
|
||||||
|
sourceToClassesMap.add(source, jvmClassName)
|
||||||
|
val (proto, nameResolver) = serializedJavaClass.toProtoData()
|
||||||
|
addToClassStorage(proto, nameResolver, source)
|
||||||
|
|
||||||
|
dirtyOutputClassesMap.notDirty(jvmClassName.internalName)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getObsoleteJavaClasses(): Collection<ClassId> =
|
||||||
|
dirtyOutputClassesMap.getDirtyOutputClasses()
|
||||||
|
.mapNotNull {
|
||||||
|
javaSourcesProtoMap[it]?.classId
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isJavaClassToTrack(classId: ClassId): Boolean {
|
||||||
|
val jvmClassName = JvmClassName.byClassId(classId)
|
||||||
|
return dirtyOutputClassesMap.isDirty(jvmClassName.internalName) ||
|
||||||
|
javaSourcesProtoMap[jvmClassName.internalName] == null
|
||||||
|
}
|
||||||
|
|
||||||
fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) {
|
fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) {
|
||||||
val dirtyClasses = dirtyOutputClassesMap
|
val dirtyClasses = dirtyOutputClassesMap
|
||||||
.getDirtyOutputClasses()
|
.getDirtyOutputClasses()
|
||||||
@@ -203,6 +228,7 @@ open class IncrementalJvmCache(
|
|||||||
constantsMap.remove(it)
|
constantsMap.remove(it)
|
||||||
inlineFunctionsMap.remove(it)
|
inlineFunctionsMap.remove(it)
|
||||||
internalNameToSource.remove(it.internalName)
|
internalNameToSource.remove(it.internalName)
|
||||||
|
javaSourcesProtoMap.remove(it, changesCollector)
|
||||||
}
|
}
|
||||||
|
|
||||||
removeAllFromClassStorage(dirtyClasses.map { it.fqNameForClassNameWithoutDollars })
|
removeAllFromClassStorage(dirtyClasses.map { it.fqNameForClassNameWithoutDollars })
|
||||||
@@ -298,6 +324,29 @@ open class IncrementalJvmCache(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inner class JavaSourcesProtoMap(storageFile: File) : BasicStringMap<SerializedJavaClass>(storageFile, JavaClassProtoMapValueExternalizer) {
|
||||||
|
fun process(jvmClassName: JvmClassName, newData: SerializedJavaClass, changesCollector: ChangesCollector) {
|
||||||
|
val key = jvmClassName.internalName
|
||||||
|
val oldData = storage[key]
|
||||||
|
storage[key] = newData
|
||||||
|
|
||||||
|
changesCollector.collectProtoChanges(oldData?.toProtoData(), newData.toProtoData())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remove(className: JvmClassName, changesCollector: ChangesCollector) {
|
||||||
|
val key = className.internalName
|
||||||
|
val oldValue = storage[key] ?: return
|
||||||
|
storage.remove(key)
|
||||||
|
|
||||||
|
changesCollector.collectProtoChanges(oldValue.toProtoData(), newData = null)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun get(internalName: String) = storage[internalName]
|
||||||
|
|
||||||
|
override fun dumpValue(value: SerializedJavaClass): String =
|
||||||
|
java.lang.Long.toHexString(value.proto.toByteArray().md5())
|
||||||
|
}
|
||||||
|
|
||||||
// todo: reuse code with InlineFunctionsMap?
|
// todo: reuse code with InlineFunctionsMap?
|
||||||
private inner class ConstantsMap(storageFile: File) : BasicStringMap<Map<String, Any>>(storageFile, ConstantsMapExternalizer) {
|
private inner class ConstantsMap(storageFile: File) : BasicStringMap<Map<String, Any>>(storageFile, ConstantsMapExternalizer) {
|
||||||
private fun getConstantsMap(bytes: ByteArray): Map<String, Any> {
|
private fun getConstantsMap(bytes: ByteArray): Map<String, Any> {
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 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.psi.PsiJavaFile
|
||||||
|
import com.intellij.util.io.DataExternalizer
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
||||||
|
import org.jetbrains.kotlin.load.java.JavaClassesTracker
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
|
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||||
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
|
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||||
|
import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl
|
||||||
|
import org.jetbrains.kotlin.serialization.java.JavaClassProtoBuf
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
import org.jetbrains.kotlin.utils.sure
|
||||||
|
import java.io.DataInput
|
||||||
|
import java.io.DataOutput
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class JavaClassesTrackerImpl(private val cache: IncrementalJvmCache) : JavaClassesTracker {
|
||||||
|
private val classToSourceSerialized: MutableMap<ClassId, SerializedJavaClassWithSource> = hashMapOf()
|
||||||
|
|
||||||
|
val javaClassesUpdates: Collection<SerializedJavaClassWithSource>
|
||||||
|
get() = classToSourceSerialized.values
|
||||||
|
|
||||||
|
private val classDescriptors: MutableList<JavaClassDescriptor> = mutableListOf()
|
||||||
|
|
||||||
|
override fun reportClass(classDescriptor: JavaClassDescriptor) {
|
||||||
|
val classId = classDescriptor.classId!!
|
||||||
|
if (!cache.isJavaClassToTrack(classId) || classDescriptor.javaSourceFile == null) return
|
||||||
|
|
||||||
|
classDescriptors.add(classDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCompletedAnalysis(module: ModuleDescriptor) {
|
||||||
|
for (classId in cache.getObsoleteJavaClasses()) {
|
||||||
|
// Just force the loading obsolete classes
|
||||||
|
// We assume here that whenever an LazyJavaClassDescriptor instances is created
|
||||||
|
// it's being passed to JavaClassesTracker::reportClass
|
||||||
|
module.findClassAcrossModuleDependencies(classId)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (classDescriptor in classDescriptors.toList()) {
|
||||||
|
classToSourceSerialized[classDescriptor.classId!!] =
|
||||||
|
classDescriptor.convertToProto()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val JavaClassDescriptor.javaSourceFile: File?
|
||||||
|
get() = source.safeAs<PsiSourceElement>()
|
||||||
|
?.psi?.containingFile?.takeIf { it is PsiJavaFile }
|
||||||
|
?.virtualFile?.path?.let(::File)
|
||||||
|
|
||||||
|
fun JavaClassDescriptor.convertToProto(): SerializedJavaClassWithSource {
|
||||||
|
val file = javaSourceFile.sure { "convertToProto should only be called for source based classes" }
|
||||||
|
|
||||||
|
val extension = JavaClassesSerializerExtension()
|
||||||
|
val serializer = DescriptorSerializer.createTopLevel(extension)
|
||||||
|
val classProto = serializer.classProto(this).build()
|
||||||
|
|
||||||
|
val (stringTable, qualifiedNameTable) = extension.stringTable.buildProto()
|
||||||
|
|
||||||
|
return SerializedJavaClassWithSource(file, SerializedJavaClass(classProto, stringTable, qualifiedNameTable))
|
||||||
|
}
|
||||||
|
|
||||||
|
class SerializedJavaClass(
|
||||||
|
val proto: ProtoBuf.Class,
|
||||||
|
val stringTable: ProtoBuf.StringTable,
|
||||||
|
val qualifiedNameTable: ProtoBuf.QualifiedNameTable
|
||||||
|
) {
|
||||||
|
val classId: ClassId
|
||||||
|
get() = NameResolverImpl(stringTable, qualifiedNameTable).getClassId(proto.fqName)
|
||||||
|
}
|
||||||
|
|
||||||
|
data class SerializedJavaClassWithSource(
|
||||||
|
val source: File,
|
||||||
|
val proto: SerializedJavaClass
|
||||||
|
)
|
||||||
|
|
||||||
|
fun SerializedJavaClass.toProtoData() = ClassProtoData(proto, NameResolverImpl(stringTable, qualifiedNameTable))
|
||||||
|
|
||||||
|
val JAVA_CLASS_PROTOBUF_REGISTRY =
|
||||||
|
ExtensionRegistryLite.newInstance()
|
||||||
|
.also(JavaClassProtoBuf::registerAllExtensions)
|
||||||
|
// Built-ins extensions are used for annotations' serialization
|
||||||
|
.also(BuiltInsProtoBuf::registerAllExtensions)
|
||||||
|
|
||||||
|
object JavaClassProtoMapValueExternalizer : DataExternalizer<SerializedJavaClass> {
|
||||||
|
override fun save(output: DataOutput, value: SerializedJavaClass) {
|
||||||
|
output.writeBytesWithSize(value.proto.toByteArray())
|
||||||
|
output.writeBytesWithSize(value.stringTable.toByteArray())
|
||||||
|
output.writeBytesWithSize(value.qualifiedNameTable.toByteArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun DataOutput.writeBytesWithSize(bytes: ByteArray) {
|
||||||
|
writeInt(bytes.size)
|
||||||
|
write(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun DataInput.readBytesWithSize(): ByteArray {
|
||||||
|
val bytesLength = readInt()
|
||||||
|
return ByteArray(bytesLength).also {
|
||||||
|
readFully(it, 0, bytesLength)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun read(input: DataInput): SerializedJavaClass {
|
||||||
|
val proto = ProtoBuf.Class.parseFrom(input.readBytesWithSize(), JAVA_CLASS_PROTOBUF_REGISTRY)
|
||||||
|
val stringTable = ProtoBuf.StringTable.parseFrom(input.readBytesWithSize(), JAVA_CLASS_PROTOBUF_REGISTRY)
|
||||||
|
val qualifiedNameTable = ProtoBuf.QualifiedNameTable.parseFrom(input.readBytesWithSize(), JAVA_CLASS_PROTOBUF_REGISTRY)
|
||||||
|
|
||||||
|
return SerializedJavaClass(proto, stringTable, qualifiedNameTable)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -79,7 +79,8 @@ fun makeCompileServices(
|
|||||||
fun updateIncrementalCache(
|
fun updateIncrementalCache(
|
||||||
generatedFiles: Iterable<GeneratedFile>,
|
generatedFiles: Iterable<GeneratedFile>,
|
||||||
cache: IncrementalJvmCache,
|
cache: IncrementalJvmCache,
|
||||||
changesCollector: ChangesCollector
|
changesCollector: ChangesCollector,
|
||||||
|
javaChangesTracker: JavaClassesTrackerImpl?
|
||||||
) {
|
) {
|
||||||
for (generatedFile in generatedFiles) {
|
for (generatedFile in generatedFiles) {
|
||||||
when {
|
when {
|
||||||
@@ -88,6 +89,11 @@ fun updateIncrementalCache(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
javaChangesTracker?.javaClassesUpdates?.forEach {
|
||||||
|
(source, serializedJavaClass) ->
|
||||||
|
cache.saveJavaClassProto(source, serializedJavaClass, changesCollector)
|
||||||
|
}
|
||||||
|
|
||||||
cache.clearCacheForRemovedClasses(changesCollector)
|
cache.clearCacheForRemovedClasses(changesCollector)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +179,7 @@ fun mapClassesFqNamesToFiles(
|
|||||||
for (cache in caches) {
|
for (cache in caches) {
|
||||||
for (dirtyClassFqName in classesFqNames) {
|
for (dirtyClassFqName in classesFqNames) {
|
||||||
val srcFile = cache.getSourceFileIfClass(dirtyClassFqName)
|
val srcFile = cache.getSourceFileIfClass(dirtyClassFqName)
|
||||||
if (srcFile == null || srcFile in excludes) continue
|
if (srcFile == null || srcFile in excludes || srcFile.isJavaFile()) continue
|
||||||
|
|
||||||
reporter.report { ("Class $dirtyClassFqName caused recompilation of: ${reporter.pathsAsString(srcFile)}") }
|
reporter.report { ("Class $dirtyClassFqName caused recompilation of: ${reporter.pathsAsString(srcFile)}") }
|
||||||
dirtyFiles.add(srcFile)
|
dirtyFiles.add(srcFile)
|
||||||
|
|||||||
-81
@@ -1,81 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.cli.jvm.compiler.EnvironmentConfigFiles
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|
||||||
import com.intellij.lang.java.JavaLanguage
|
|
||||||
import com.intellij.openapi.util.Disposer
|
|
||||||
import com.intellij.psi.PsiClass
|
|
||||||
import com.intellij.psi.PsiFile
|
|
||||||
import com.intellij.psi.PsiFileFactory
|
|
||||||
import com.intellij.psi.PsiJavaFile
|
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
|
||||||
import java.io.File
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
internal class ChangedJavaFilesProcessor(private val reporter: ICReporter) {
|
|
||||||
private val allSymbols = HashSet<LookupSymbol>()
|
|
||||||
private val javaLang = JavaLanguage.INSTANCE
|
|
||||||
private val psiFileFactory: PsiFileFactory by lazy {
|
|
||||||
val rootDisposable = Disposer.newDisposable()
|
|
||||||
val configuration = CompilerConfiguration()
|
|
||||||
val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
|
||||||
val project = environment.project
|
|
||||||
PsiFileFactory.getInstance(project)
|
|
||||||
}
|
|
||||||
|
|
||||||
val allChangedSymbols: Collection<LookupSymbol>
|
|
||||||
get() = allSymbols
|
|
||||||
|
|
||||||
fun process(filesDiff: ChangedFiles.Known): ChangesEither {
|
|
||||||
val modifiedJava = filesDiff.modified.filter(File::isJavaFile)
|
|
||||||
val removedJava = filesDiff.removed.filter(File::isJavaFile)
|
|
||||||
|
|
||||||
if (removedJava.any()) {
|
|
||||||
reporter.report { "Some java files are removed: [${removedJava.joinToString()}]" }
|
|
||||||
return ChangesEither.Unknown()
|
|
||||||
}
|
|
||||||
|
|
||||||
val symbols = HashSet<LookupSymbol>()
|
|
||||||
for (javaFile in modifiedJava) {
|
|
||||||
assert(javaFile.extension.equals("java", ignoreCase = true))
|
|
||||||
|
|
||||||
val psiFile = javaFile.psiFile()
|
|
||||||
if (psiFile !is PsiJavaFile) {
|
|
||||||
reporter.report { "Expected PsiJavaFile, got ${psiFile?.javaClass}" }
|
|
||||||
return ChangesEither.Unknown()
|
|
||||||
}
|
|
||||||
|
|
||||||
psiFile.classes.forEach { it.addLookupSymbols(symbols) }
|
|
||||||
}
|
|
||||||
allSymbols.addAll(symbols)
|
|
||||||
return ChangesEither.Known(lookupSymbols = symbols)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun PsiClass.addLookupSymbols(symbols: MutableSet<LookupSymbol>) {
|
|
||||||
val fqn = qualifiedName.orEmpty()
|
|
||||||
|
|
||||||
symbols.add(LookupSymbol(name.orEmpty(), if (fqn == name) "" else fqn.removeSuffix("." + name!!)))
|
|
||||||
methods.forEach { symbols.add(LookupSymbol(it.name, fqn)) }
|
|
||||||
fields.forEach { symbols.add(LookupSymbol(it.name.orEmpty(), fqn)) }
|
|
||||||
innerClasses.forEach { it.addLookupSymbols(symbols) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun File.psiFile(): PsiFile? =
|
|
||||||
psiFileFactory.createFileFromText(nameWithoutExtension, javaLang, readText())
|
|
||||||
}
|
|
||||||
+5
-9
@@ -31,8 +31,7 @@ import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.ArrayList
|
import java.util.*
|
||||||
import java.util.HashSet
|
|
||||||
|
|
||||||
abstract class IncrementalCompilerRunner<
|
abstract class IncrementalCompilerRunner<
|
||||||
Args : CommonCompilerArguments,
|
Args : CommonCompilerArguments,
|
||||||
@@ -143,8 +142,6 @@ abstract class IncrementalCompilerRunner<
|
|||||||
protected open fun postCompilationHook(exitCode: ExitCode) {}
|
protected open fun postCompilationHook(exitCode: ExitCode) {}
|
||||||
protected open fun additionalDirtyFiles(caches: CacheManager, generatedFiles: List<GeneratedFile>): Iterable<File> =
|
protected open fun additionalDirtyFiles(caches: CacheManager, generatedFiles: List<GeneratedFile>): Iterable<File> =
|
||||||
emptyList()
|
emptyList()
|
||||||
protected open fun additionalDirtyLookupSymbols(): Iterable<LookupSymbol> =
|
|
||||||
emptyList()
|
|
||||||
|
|
||||||
protected open fun makeServices(
|
protected open fun makeServices(
|
||||||
args: Args,
|
args: Args,
|
||||||
@@ -187,7 +184,7 @@ abstract class IncrementalCompilerRunner<
|
|||||||
var exitCode = ExitCode.OK
|
var exitCode = ExitCode.OK
|
||||||
val allGeneratedFiles = hashSetOf<GeneratedFile>()
|
val allGeneratedFiles = hashSetOf<GeneratedFile>()
|
||||||
|
|
||||||
while (dirtySources.any()) {
|
while (dirtySources.any() || runWithNoDirtyKotlinSources(caches)) {
|
||||||
caches.platformCache.markDirty(dirtySources)
|
caches.platformCache.markDirty(dirtySources)
|
||||||
caches.inputsCache.removeOutputForSourceFiles(dirtySources)
|
caches.inputsCache.removeOutputForSourceFiles(dirtySources)
|
||||||
|
|
||||||
@@ -248,9 +245,6 @@ abstract class IncrementalCompilerRunner<
|
|||||||
if (exitCode == ExitCode.OK) {
|
if (exitCode == ExitCode.OK) {
|
||||||
BuildInfo.write(currentBuildInfo, lastBuildInfoFile)
|
BuildInfo.write(currentBuildInfo, lastBuildInfoFile)
|
||||||
}
|
}
|
||||||
if (exitCode == ExitCode.OK && compilationMode is CompilationMode.Incremental) {
|
|
||||||
buildDirtyLookupSymbols.addAll(additionalDirtyLookupSymbols())
|
|
||||||
}
|
|
||||||
|
|
||||||
val dirtyData = DirtyData(buildDirtyLookupSymbols, buildDirtyFqNames)
|
val dirtyData = DirtyData(buildDirtyLookupSymbols, buildDirtyFqNames)
|
||||||
processChangesAfterBuild(compilationMode, currentBuildInfo, dirtyData)
|
processChangesAfterBuild(compilationMode, currentBuildInfo, dirtyData)
|
||||||
@@ -262,6 +256,8 @@ abstract class IncrementalCompilerRunner<
|
|||||||
return exitCode
|
return exitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun runWithNoDirtyKotlinSources(caches: CacheManager): Boolean = false
|
||||||
|
|
||||||
protected open fun processChangesAfterBuild(compilationMode: CompilationMode, currentBuildInfo: BuildInfo, dirtyData: DirtyData) {
|
protected open fun processChangesAfterBuild(compilationMode: CompilationMode, currentBuildInfo: BuildInfo, dirtyData: DirtyData) {
|
||||||
if (changesRegistry == null) return
|
if (changesRegistry == null) return
|
||||||
|
|
||||||
@@ -283,4 +279,4 @@ abstract class IncrementalCompilerRunner<
|
|||||||
override fun checkCanceled() {
|
override fun checkCanceled() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-15
@@ -31,14 +31,12 @@ import org.jetbrains.kotlin.config.Services
|
|||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider
|
import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider
|
||||||
import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry
|
import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry
|
||||||
|
import org.jetbrains.kotlin.load.java.JavaClassesTracker
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||||
import org.jetbrains.kotlin.modules.TargetId
|
import org.jetbrains.kotlin.modules.TargetId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
|
||||||
import kotlin.collections.HashSet
|
|
||||||
|
|
||||||
fun makeIncrementally(
|
fun makeIncrementally(
|
||||||
cachesDir: File,
|
cachesDir: File,
|
||||||
@@ -110,8 +108,6 @@ class IncrementalJvmCompilerRunner(
|
|||||||
override fun destinationDir(args: K2JVMCompilerArguments): File =
|
override fun destinationDir(args: K2JVMCompilerArguments): File =
|
||||||
args.destinationAsFile
|
args.destinationAsFile
|
||||||
|
|
||||||
private var javaFilesProcessor = ChangedJavaFilesProcessor(reporter)
|
|
||||||
|
|
||||||
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)
|
val dirtyFiles = getDirtyFiles(changedFiles)
|
||||||
|
|
||||||
@@ -170,23 +166,22 @@ class IncrementalJvmCompilerRunner(
|
|||||||
return CompilationMode.Rebuild { "could not get changes from modified classpath entries: ${reporter.pathsAsString(modifiedClasspathEntries)}" }
|
return CompilationMode.Rebuild { "could not get changes from modified classpath entries: ${reporter.pathsAsString(modifiedClasspathEntries)}" }
|
||||||
}
|
}
|
||||||
|
|
||||||
val javaFilesChanges = javaFilesProcessor.process(changedFiles)
|
processChangedJava(changedFiles, caches)
|
||||||
val affectedJavaSymbols = when (javaFilesChanges) {
|
|
||||||
is ChangesEither.Known -> javaFilesChanges.lookupSymbols
|
|
||||||
is ChangesEither.Unknown -> return CompilationMode.Rebuild { "Could not get changes for java files" }
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((changedFiles.modified + changedFiles.removed).any { it.extension.toLowerCase() == "xml" }) {
|
if ((changedFiles.modified + changedFiles.removed).any { it.extension.toLowerCase() == "xml" }) {
|
||||||
return CompilationMode.Rebuild { "XML resource files were changed" }
|
return CompilationMode.Rebuild { "XML resource files were changed" }
|
||||||
}
|
}
|
||||||
|
|
||||||
markDirtyBy(affectedJavaSymbols)
|
|
||||||
markDirtyBy(classpathChanges.lookupSymbols)
|
markDirtyBy(classpathChanges.lookupSymbols)
|
||||||
markDirtyBy(classpathChanges.fqNames)
|
markDirtyBy(classpathChanges.fqNames)
|
||||||
|
|
||||||
return CompilationMode.Incremental(dirtyFiles)
|
return CompilationMode.Incremental(dirtyFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun processChangedJava(changedFiles: ChangedFiles.Known, caches: IncrementalJvmCachesManager) {
|
||||||
|
caches.platformCache.markDirty((changedFiles.modified + changedFiles.removed).filter(File::isJavaFile))
|
||||||
|
}
|
||||||
|
|
||||||
private fun getClasspathChanges(
|
private fun getClasspathChanges(
|
||||||
modifiedClasspath: List<File>,
|
modifiedClasspath: List<File>,
|
||||||
lastBuildInfo: BuildInfo?
|
lastBuildInfo: BuildInfo?
|
||||||
@@ -249,9 +244,15 @@ class IncrementalJvmCompilerRunner(
|
|||||||
generatedFiles: List<GeneratedFile>,
|
generatedFiles: List<GeneratedFile>,
|
||||||
changesCollector: ChangesCollector
|
changesCollector: ChangesCollector
|
||||||
) {
|
) {
|
||||||
updateIncrementalCache(generatedFiles, caches.platformCache, changesCollector)
|
updateIncrementalCache(
|
||||||
|
generatedFiles, caches.platformCache, changesCollector,
|
||||||
|
services[JavaClassesTracker::class.java] as? JavaClassesTrackerImpl
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun runWithNoDirtyKotlinSources(caches: IncrementalJvmCachesManager): Boolean =
|
||||||
|
caches.platformCache.getObsoleteJavaClasses().isNotEmpty()
|
||||||
|
|
||||||
override fun additionalDirtyFiles(
|
override fun additionalDirtyFiles(
|
||||||
caches: IncrementalJvmCachesManager,
|
caches: IncrementalJvmCachesManager,
|
||||||
generatedFiles: List<GeneratedFile>
|
generatedFiles: List<GeneratedFile>
|
||||||
@@ -292,9 +293,6 @@ class IncrementalJvmCompilerRunner(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun additionalDirtyLookupSymbols(): Iterable<LookupSymbol> =
|
|
||||||
javaFilesProcessor.allChangedSymbols
|
|
||||||
|
|
||||||
override fun processChangesAfterBuild(compilationMode: CompilationMode, currentBuildInfo: BuildInfo, dirtyData: DirtyData) {
|
override fun processChangesAfterBuild(compilationMode: CompilationMode, currentBuildInfo: BuildInfo, dirtyData: DirtyData) {
|
||||||
super.processChangesAfterBuild(compilationMode, currentBuildInfo, dirtyData)
|
super.processChangesAfterBuild(compilationMode, currentBuildInfo, dirtyData)
|
||||||
|
|
||||||
@@ -323,6 +321,8 @@ class IncrementalJvmCompilerRunner(
|
|||||||
val targetToCache = mapOf(targetId to caches.platformCache)
|
val targetToCache = mapOf(targetId to caches.platformCache)
|
||||||
val incrementalComponents = IncrementalCompilationComponentsImpl(targetToCache)
|
val incrementalComponents = IncrementalCompilationComponentsImpl(targetToCache)
|
||||||
register(IncrementalCompilationComponents::class.java, incrementalComponents)
|
register(IncrementalCompilationComponents::class.java, incrementalComponents)
|
||||||
|
val changesTracker = JavaClassesTrackerImpl(caches.platformCache)
|
||||||
|
register(JavaClassesTracker::class.java, changesTracker)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun runCompiler(
|
override fun runCompiler(
|
||||||
|
|||||||
+57
@@ -1108,18 +1108,42 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/withJava/javaUsedInKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/withJava/javaUsedInKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("changeFieldType")
|
||||||
|
public void testChangeFieldType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeFieldType/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("changeNotUsedSignature")
|
@TestMetadata("changeNotUsedSignature")
|
||||||
public void testChangeNotUsedSignature() throws Exception {
|
public void testChangeNotUsedSignature() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeNotUsedSignature/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeNotUsedSignature/");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("changePropertyOverrideType")
|
||||||
|
public void testChangePropertyOverrideType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changePropertyOverrideType/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("changeSignature")
|
@TestMetadata("changeSignature")
|
||||||
public void testChangeSignature() throws Exception {
|
public void testChangeSignature() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeSignature/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeSignature/");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("changeSignaturePackagePrivate")
|
||||||
|
public void testChangeSignaturePackagePrivate() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeSignaturePackagePrivate/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("changeSignatureStatic")
|
||||||
|
public void testChangeSignatureStatic() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeSignatureStatic/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("constantChanged")
|
@TestMetadata("constantChanged")
|
||||||
public void testConstantChanged() throws Exception {
|
public void testConstantChanged() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/constantChanged/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/constantChanged/");
|
||||||
@@ -1180,6 +1204,12 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("mixedInheritance")
|
||||||
|
public void testMixedInheritance() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/mixedInheritance/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("notChangeSignature")
|
@TestMetadata("notChangeSignature")
|
||||||
public void testNotChangeSignature() throws Exception {
|
public void testNotChangeSignature() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/notChangeSignature/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/notChangeSignature/");
|
||||||
@@ -1472,4 +1502,31 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jps-plugin/testData/incremental/incrementalJvmCompilerOnly")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class IncrementalJvmCompilerOnly extends AbstractIncrementalJvmCompilerRunnerTest {
|
||||||
|
@TestMetadata("addAnnotationToJavaClass")
|
||||||
|
public void testAddAnnotationToJavaClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/incrementalJvmCompilerOnly/addAnnotationToJavaClass/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("addNestedClass")
|
||||||
|
public void testAddNestedClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/incrementalJvmCompilerOnly/addNestedClass/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInIncrementalJvmCompilerOnly() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/incrementalJvmCompilerOnly"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("changeAnnotationInJavaClass")
|
||||||
|
public void testChangeAnnotationInJavaClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/incrementalJvmCompilerOnly/changeAnnotationInJavaClass/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class Services private constructor(private val map: Map<Class<*>, Any>) {
|
|||||||
val EMPTY: Services = Builder().build()
|
val EMPTY: Services = Builder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> get(interfaceClass: Class<T>): T? {
|
operator fun <T> get(interfaceClass: Class<T>): T? {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return map[interfaceClass] as T?
|
return map[interfaceClass] as T?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -913,6 +913,7 @@ fun main(args: Array<String>) {
|
|||||||
model("incremental/classHierarchyAffected", extension = null, recursive = false)
|
model("incremental/classHierarchyAffected", extension = null, recursive = false)
|
||||||
model("incremental/inlineFunCallSite", extension = null, excludeParentDirs = true)
|
model("incremental/inlineFunCallSite", extension = null, excludeParentDirs = true)
|
||||||
model("incremental/withJava", extension = null, excludeParentDirs = true)
|
model("incremental/withJava", extension = null, excludeParentDirs = true)
|
||||||
|
model("incremental/incrementalJvmCompilerOnly", extension = null, excludeParentDirs = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractIncrementalJsCompilerRunnerTest> {
|
testClass<AbstractIncrementalJsCompilerRunnerTest> {
|
||||||
|
|||||||
+30
@@ -949,18 +949,42 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/withJava/javaUsedInKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/withJava/javaUsedInKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("changeFieldType")
|
||||||
|
public void testChangeFieldType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeFieldType/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("changeNotUsedSignature")
|
@TestMetadata("changeNotUsedSignature")
|
||||||
public void testChangeNotUsedSignature() throws Exception {
|
public void testChangeNotUsedSignature() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeNotUsedSignature/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeNotUsedSignature/");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("changePropertyOverrideType")
|
||||||
|
public void testChangePropertyOverrideType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changePropertyOverrideType/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("changeSignature")
|
@TestMetadata("changeSignature")
|
||||||
public void testChangeSignature() throws Exception {
|
public void testChangeSignature() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeSignature/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeSignature/");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("changeSignaturePackagePrivate")
|
||||||
|
public void testChangeSignaturePackagePrivate() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeSignaturePackagePrivate/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("changeSignatureStatic")
|
||||||
|
public void testChangeSignatureStatic() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeSignatureStatic/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("constantChanged")
|
@TestMetadata("constantChanged")
|
||||||
public void testConstantChanged() throws Exception {
|
public void testConstantChanged() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/constantChanged/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/constantChanged/");
|
||||||
@@ -1021,6 +1045,12 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("mixedInheritance")
|
||||||
|
public void testMixedInheritance() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/mixedInheritance/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("notChangeSignature")
|
@TestMetadata("notChangeSignature")
|
||||||
public void testNotChangeSignature() throws Exception {
|
public void testNotChangeSignature() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/notChangeSignature/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/notChangeSignature/");
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
|
|
||||||
val changesCollector = ChangesCollector()
|
val changesCollector = ChangesCollector()
|
||||||
for ((target, files) in generatedFiles) {
|
for ((target, files) in generatedFiles) {
|
||||||
updateIncrementalCache(files, incrementalCaches[target]!!, changesCollector)
|
updateIncrementalCache(files, incrementalCaches[target]!!, changesCollector, null)
|
||||||
}
|
}
|
||||||
updateLookupStorage(chunk, lookupTracker, dataManager, dirtyFilesHolder, filesToCompile)
|
updateLookupStorage(chunk, lookupTracker, dataManager, dirtyFilesHolder, filesToCompile)
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
public @interface Ann {
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public class JavaClass {
|
||||||
|
public String foo() { return null; }
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
@Ann
|
||||||
|
public class JavaClass {
|
||||||
|
public String foo() { return null; }
|
||||||
|
}
|
||||||
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
================ Step #1 =================
|
||||||
|
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/JavaClass.class
|
||||||
|
End of files
|
||||||
|
Exit code: NOTHING_DONE
|
||||||
|
------------------------------------------
|
||||||
|
Compiling files:
|
||||||
|
src/JavaClass.java
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
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: ABORT
|
||||||
|
------------------------------------------
|
||||||
|
SUCCESS
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun foo() {
|
||||||
|
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun bar() {
|
||||||
|
JavaClass().foo()
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public class JavaClass {
|
||||||
|
public String foo() { return null; }
|
||||||
|
}
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
public class JavaClass {
|
||||||
|
public String foo() { return null; }
|
||||||
|
public static class Nested {
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
================ Step #1 =================
|
||||||
|
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/JavaClass.class
|
||||||
|
End of files
|
||||||
|
Exit code: NOTHING_DONE
|
||||||
|
------------------------------------------
|
||||||
|
Compiling files:
|
||||||
|
src/JavaClass.java
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
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: ABORT
|
||||||
|
------------------------------------------
|
||||||
|
COMPILATION FAILED
|
||||||
|
Unresolved reference: Nested
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
import test.*
|
||||||
|
|
||||||
|
fun foo(x: Nested) {
|
||||||
|
JavaClass().foo()
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class Nested
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
import test.*
|
||||||
|
import JavaClass.*
|
||||||
|
|
||||||
|
fun bar(x: Nested) {
|
||||||
|
JavaClass().foo()
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public @interface Ann {
|
||||||
|
String value() default "1";
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
@Ann
|
||||||
|
public class JavaClass {
|
||||||
|
public String foo() { return null; }
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
@Ann("")
|
||||||
|
public class JavaClass {
|
||||||
|
public String foo() { return null; }
|
||||||
|
}
|
||||||
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
================ Step #1 =================
|
||||||
|
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/JavaClass.class
|
||||||
|
End of files
|
||||||
|
Exit code: NOTHING_DONE
|
||||||
|
------------------------------------------
|
||||||
|
Compiling files:
|
||||||
|
src/JavaClass.java
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
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: ABORT
|
||||||
|
------------------------------------------
|
||||||
|
SUCCESS
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun foo() {
|
||||||
|
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun bar() {
|
||||||
|
JavaClass().foo()
|
||||||
|
}
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
================ Step #1 =================
|
|
||||||
Compiling files:
|
|
||||||
src/TheClass.kt
|
|
||||||
src/other.kt
|
|
||||||
End of files
|
|
||||||
Exit code: OK
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
================ Step #2 =================
|
|
||||||
|
|
||||||
Compiling files:
|
|
||||||
End of files
|
|
||||||
Exit code: OK
|
|
||||||
------------------------------------------
|
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
public class JavaClass {
|
||||||
|
public String stringField;
|
||||||
|
public int intField;
|
||||||
|
}
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
public class JavaClass {
|
||||||
|
public CharSequence stringField;
|
||||||
|
public int intField;
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
================ Step #1 =================
|
||||||
|
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/JavaClass.class
|
||||||
|
End of files
|
||||||
|
Exit code: NOTHING_DONE
|
||||||
|
------------------------------------------
|
||||||
|
Compiling files:
|
||||||
|
src/JavaClass.java
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
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: OK
|
||||||
|
------------------------------------------
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
JavaClass().intField
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
JavaClass().stringField
|
||||||
|
}
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
public class JavaClass implements KotlinInterface {
|
||||||
|
public CharSequence getX() { return ""; }
|
||||||
|
public int getY() { return 1; }
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
public class JavaClass implements KotlinInterface {
|
||||||
|
public String getX() { return ""; }
|
||||||
|
public int getY() { return 1; }
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
interface KotlinInterface {
|
||||||
|
val x: CharSequence
|
||||||
|
val y: Int
|
||||||
|
}
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
================ Step #1 =================
|
||||||
|
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/JavaClass.class
|
||||||
|
End of files
|
||||||
|
Exit code: NOTHING_DONE
|
||||||
|
------------------------------------------
|
||||||
|
Compiling files:
|
||||||
|
src/JavaClass.java
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
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: OK
|
||||||
|
------------------------------------------
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
JavaClass().y
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
JavaClass().x
|
||||||
|
}
|
||||||
+4
-1
@@ -1,4 +1,7 @@
|
|||||||
public class JavaClass {
|
public class JavaClass {
|
||||||
public static void foo() {
|
public void foo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bar() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+5
-2
@@ -1,5 +1,8 @@
|
|||||||
public class JavaClass {
|
public class JavaClass {
|
||||||
public static String foo() {
|
public String foo() {
|
||||||
return ":)";
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bar() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
JavaClass().bar()
|
||||||
|
}
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
JavaClass.foo()
|
JavaClass().foo()
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
public class JavaClass {
|
||||||
|
public void foo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bar() {
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
public class JavaClass {
|
||||||
|
void foo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bar() {
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
================ Step #1 =================
|
||||||
|
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/JavaClass.class
|
||||||
|
End of files
|
||||||
|
Exit code: NOTHING_DONE
|
||||||
|
------------------------------------------
|
||||||
|
Compiling files:
|
||||||
|
src/JavaClass.java
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
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: OK
|
||||||
|
------------------------------------------
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
JavaClass().bar()
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
JavaClass().foo()
|
||||||
|
}
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
public class JavaClass {
|
||||||
|
public static void foo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void bar() {
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
public class JavaClass {
|
||||||
|
public static String foo() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void bar() {
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
================ Step #1 =================
|
||||||
|
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/JavaClass.class
|
||||||
|
End of files
|
||||||
|
Exit code: NOTHING_DONE
|
||||||
|
------------------------------------------
|
||||||
|
Compiling files:
|
||||||
|
src/JavaClass.java
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
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: OK
|
||||||
|
------------------------------------------
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
JavaClass.bar()
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
JavaClass.foo()
|
||||||
|
}
|
||||||
Vendored
-7
@@ -1,7 +0,0 @@
|
|||||||
================ Step #1 =================
|
|
||||||
|
|
||||||
Compiling files:
|
|
||||||
src/JavaClass.java
|
|
||||||
src/usage.kt
|
|
||||||
End of files
|
|
||||||
Exit code: OK
|
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
open class BaseClass {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
open class BaseClass {
|
||||||
|
fun foo(): String = "OK"
|
||||||
|
}
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
public class DerivedClass1 extends BaseClass {
|
||||||
|
}
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
class DerivedClass2 : DerivedClass1() {
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
================ Step #1 =================
|
||||||
|
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/BaseClass.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/BaseClass.kt
|
||||||
|
End of files
|
||||||
|
Marked as dirty by Kotlin:
|
||||||
|
src/usage1.kt
|
||||||
|
src/usage2.kt
|
||||||
|
src/usage3.kt
|
||||||
|
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||||
|
------------------------------------------
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/DerivedClass1.class
|
||||||
|
out/production/module/DerivedClass2.class
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/Usage1Kt.class
|
||||||
|
out/production/module/Usage2Kt.class
|
||||||
|
out/production/module/Usage3Kt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/DerivedClass2.kt
|
||||||
|
src/usage1.kt
|
||||||
|
src/usage2.kt
|
||||||
|
src/usage3.kt
|
||||||
|
End of files
|
||||||
|
Exit code: OK
|
||||||
|
------------------------------------------
|
||||||
|
Compiling files:
|
||||||
|
src/DerivedClass1.java
|
||||||
|
End of files
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main4() {
|
||||||
|
DerivedClass2().hashCode()
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main1() {
|
||||||
|
BaseClass().foo()
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main2() {
|
||||||
|
DerivedClass1().foo()
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun main3() {
|
||||||
|
DerivedClass2().foo()
|
||||||
|
}
|
||||||
Vendored
-6
@@ -1,6 +0,0 @@
|
|||||||
================ Step #1 =================
|
|
||||||
|
|
||||||
Compiling files:
|
|
||||||
src/JavaClass.java
|
|
||||||
src/usage.kt
|
|
||||||
End of files
|
|
||||||
Reference in New Issue
Block a user