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.incremental.components.IncrementalCache
|
||||
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.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
||||
@@ -54,6 +55,7 @@ open class IncrementalJvmCache(
|
||||
private val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
|
||||
private val INLINE_FUNCTIONS = "inline-functions"
|
||||
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
|
||||
}
|
||||
@@ -68,6 +70,7 @@ open class IncrementalJvmCache(
|
||||
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
|
||||
// todo: try to use internal names only?
|
||||
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" } }
|
||||
|
||||
@@ -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) {
|
||||
val dirtyClasses = dirtyOutputClassesMap
|
||||
.getDirtyOutputClasses()
|
||||
@@ -203,6 +228,7 @@ open class IncrementalJvmCache(
|
||||
constantsMap.remove(it)
|
||||
inlineFunctionsMap.remove(it)
|
||||
internalNameToSource.remove(it.internalName)
|
||||
javaSourcesProtoMap.remove(it, changesCollector)
|
||||
}
|
||||
|
||||
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?
|
||||
private inner class ConstantsMap(storageFile: File) : BasicStringMap<Map<String, Any>>(storageFile, ConstantsMapExternalizer) {
|
||||
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(
|
||||
generatedFiles: Iterable<GeneratedFile>,
|
||||
cache: IncrementalJvmCache,
|
||||
changesCollector: ChangesCollector
|
||||
changesCollector: ChangesCollector,
|
||||
javaChangesTracker: JavaClassesTrackerImpl?
|
||||
) {
|
||||
for (generatedFile in generatedFiles) {
|
||||
when {
|
||||
@@ -88,6 +89,11 @@ fun updateIncrementalCache(
|
||||
}
|
||||
}
|
||||
|
||||
javaChangesTracker?.javaClassesUpdates?.forEach {
|
||||
(source, serializedJavaClass) ->
|
||||
cache.saveJavaClassProto(source, serializedJavaClass, changesCollector)
|
||||
}
|
||||
|
||||
cache.clearCacheForRemovedClasses(changesCollector)
|
||||
}
|
||||
|
||||
@@ -173,7 +179,7 @@ fun mapClassesFqNamesToFiles(
|
||||
for (cache in caches) {
|
||||
for (dirtyClassFqName in classesFqNames) {
|
||||
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)}") }
|
||||
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.progress.CompilationCanceledStatus
|
||||
import java.io.File
|
||||
import java.util.ArrayList
|
||||
import java.util.HashSet
|
||||
import java.util.*
|
||||
|
||||
abstract class IncrementalCompilerRunner<
|
||||
Args : CommonCompilerArguments,
|
||||
@@ -143,8 +142,6 @@ abstract class IncrementalCompilerRunner<
|
||||
protected open fun postCompilationHook(exitCode: ExitCode) {}
|
||||
protected open fun additionalDirtyFiles(caches: CacheManager, generatedFiles: List<GeneratedFile>): Iterable<File> =
|
||||
emptyList()
|
||||
protected open fun additionalDirtyLookupSymbols(): Iterable<LookupSymbol> =
|
||||
emptyList()
|
||||
|
||||
protected open fun makeServices(
|
||||
args: Args,
|
||||
@@ -187,7 +184,7 @@ abstract class IncrementalCompilerRunner<
|
||||
var exitCode = ExitCode.OK
|
||||
val allGeneratedFiles = hashSetOf<GeneratedFile>()
|
||||
|
||||
while (dirtySources.any()) {
|
||||
while (dirtySources.any() || runWithNoDirtyKotlinSources(caches)) {
|
||||
caches.platformCache.markDirty(dirtySources)
|
||||
caches.inputsCache.removeOutputForSourceFiles(dirtySources)
|
||||
|
||||
@@ -248,9 +245,6 @@ abstract class IncrementalCompilerRunner<
|
||||
if (exitCode == ExitCode.OK) {
|
||||
BuildInfo.write(currentBuildInfo, lastBuildInfoFile)
|
||||
}
|
||||
if (exitCode == ExitCode.OK && compilationMode is CompilationMode.Incremental) {
|
||||
buildDirtyLookupSymbols.addAll(additionalDirtyLookupSymbols())
|
||||
}
|
||||
|
||||
val dirtyData = DirtyData(buildDirtyLookupSymbols, buildDirtyFqNames)
|
||||
processChangesAfterBuild(compilationMode, currentBuildInfo, dirtyData)
|
||||
@@ -262,6 +256,8 @@ abstract class IncrementalCompilerRunner<
|
||||
return exitCode
|
||||
}
|
||||
|
||||
open fun runWithNoDirtyKotlinSources(caches: CacheManager): Boolean = false
|
||||
|
||||
protected open fun processChangesAfterBuild(compilationMode: CompilationMode, currentBuildInfo: BuildInfo, dirtyData: DirtyData) {
|
||||
if (changesRegistry == null) return
|
||||
|
||||
@@ -283,4 +279,4 @@ abstract class IncrementalCompilerRunner<
|
||||
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.multiproject.ArtifactChangesProvider
|
||||
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.incremental.components.IncrementalCompilationComponents
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.collections.HashSet
|
||||
|
||||
fun makeIncrementally(
|
||||
cachesDir: File,
|
||||
@@ -110,8 +108,6 @@ class IncrementalJvmCompilerRunner(
|
||||
override fun destinationDir(args: K2JVMCompilerArguments): File =
|
||||
args.destinationAsFile
|
||||
|
||||
private var javaFilesProcessor = ChangedJavaFilesProcessor(reporter)
|
||||
|
||||
override fun calculateSourcesToCompile(caches: IncrementalJvmCachesManager, changedFiles: ChangedFiles.Known, args: K2JVMCompilerArguments): CompilationMode {
|
||||
val dirtyFiles = getDirtyFiles(changedFiles)
|
||||
|
||||
@@ -170,23 +166,22 @@ class IncrementalJvmCompilerRunner(
|
||||
return CompilationMode.Rebuild { "could not get changes from modified classpath entries: ${reporter.pathsAsString(modifiedClasspathEntries)}" }
|
||||
}
|
||||
|
||||
val javaFilesChanges = javaFilesProcessor.process(changedFiles)
|
||||
val affectedJavaSymbols = when (javaFilesChanges) {
|
||||
is ChangesEither.Known -> javaFilesChanges.lookupSymbols
|
||||
is ChangesEither.Unknown -> return CompilationMode.Rebuild { "Could not get changes for java files" }
|
||||
}
|
||||
processChangedJava(changedFiles, caches)
|
||||
|
||||
if ((changedFiles.modified + changedFiles.removed).any { it.extension.toLowerCase() == "xml" }) {
|
||||
return CompilationMode.Rebuild { "XML resource files were changed" }
|
||||
}
|
||||
|
||||
markDirtyBy(affectedJavaSymbols)
|
||||
markDirtyBy(classpathChanges.lookupSymbols)
|
||||
markDirtyBy(classpathChanges.fqNames)
|
||||
|
||||
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(
|
||||
modifiedClasspath: List<File>,
|
||||
lastBuildInfo: BuildInfo?
|
||||
@@ -249,9 +244,15 @@ class IncrementalJvmCompilerRunner(
|
||||
generatedFiles: List<GeneratedFile>,
|
||||
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(
|
||||
caches: IncrementalJvmCachesManager,
|
||||
generatedFiles: List<GeneratedFile>
|
||||
@@ -292,9 +293,6 @@ class IncrementalJvmCompilerRunner(
|
||||
return result
|
||||
}
|
||||
|
||||
override fun additionalDirtyLookupSymbols(): Iterable<LookupSymbol> =
|
||||
javaFilesProcessor.allChangedSymbols
|
||||
|
||||
override fun processChangesAfterBuild(compilationMode: CompilationMode, currentBuildInfo: BuildInfo, dirtyData: DirtyData) {
|
||||
super.processChangesAfterBuild(compilationMode, currentBuildInfo, dirtyData)
|
||||
|
||||
@@ -323,6 +321,8 @@ class IncrementalJvmCompilerRunner(
|
||||
val targetToCache = mapOf(targetId to caches.platformCache)
|
||||
val incrementalComponents = IncrementalCompilationComponentsImpl(targetToCache)
|
||||
register(IncrementalCompilationComponents::class.java, incrementalComponents)
|
||||
val changesTracker = JavaClassesTrackerImpl(caches.platformCache)
|
||||
register(JavaClassesTracker::class.java, changesTracker)
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@TestMetadata("changeFieldType")
|
||||
public void testChangeFieldType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeFieldType/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("changeNotUsedSignature")
|
||||
public void testChangeNotUsedSignature() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeNotUsedSignature/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("changePropertyOverrideType")
|
||||
public void testChangePropertyOverrideType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changePropertyOverrideType/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("changeSignature")
|
||||
public void testChangeSignature() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeSignature/");
|
||||
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")
|
||||
public void testConstantChanged() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/constantChanged/");
|
||||
@@ -1180,6 +1204,12 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("mixedInheritance")
|
||||
public void testMixedInheritance() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/mixedInheritance/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("notChangeSignature")
|
||||
public void testNotChangeSignature() throws Exception {
|
||||
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()
|
||||
}
|
||||
|
||||
fun <T> get(interfaceClass: Class<T>): T? {
|
||||
operator fun <T> get(interfaceClass: Class<T>): T? {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return map[interfaceClass] as T?
|
||||
}
|
||||
|
||||
@@ -913,6 +913,7 @@ fun main(args: Array<String>) {
|
||||
model("incremental/classHierarchyAffected", extension = null, recursive = false)
|
||||
model("incremental/inlineFunCallSite", extension = null, excludeParentDirs = true)
|
||||
model("incremental/withJava", extension = null, excludeParentDirs = true)
|
||||
model("incremental/incrementalJvmCompilerOnly", extension = null, excludeParentDirs = true)
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@TestMetadata("changeFieldType")
|
||||
public void testChangeFieldType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeFieldType/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("changeNotUsedSignature")
|
||||
public void testChangeNotUsedSignature() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeNotUsedSignature/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("changePropertyOverrideType")
|
||||
public void testChangePropertyOverrideType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changePropertyOverrideType/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("changeSignature")
|
||||
public void testChangeSignature() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeSignature/");
|
||||
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")
|
||||
public void testConstantChanged() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/constantChanged/");
|
||||
@@ -1021,6 +1045,12 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("mixedInheritance")
|
||||
public void testMixedInheritance() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/mixedInheritance/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("notChangeSignature")
|
||||
public void testNotChangeSignature() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/notChangeSignature/");
|
||||
|
||||
@@ -333,7 +333,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
|
||||
val changesCollector = ChangesCollector()
|
||||
for ((target, files) in generatedFiles) {
|
||||
updateIncrementalCache(files, incrementalCaches[target]!!, changesCollector)
|
||||
updateIncrementalCache(files, incrementalCaches[target]!!, changesCollector, null)
|
||||
}
|
||||
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 static void foo() {
|
||||
public void foo() {
|
||||
}
|
||||
|
||||
public void bar() {
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+5
-2
@@ -1,5 +1,8 @@
|
||||
public class JavaClass {
|
||||
public static String foo() {
|
||||
return ":)";
|
||||
public String foo() {
|
||||
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>) {
|
||||
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