diff --git a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/Incremental.kt b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/Incremental.kt index fb20321428..18bbc51b0b 100644 --- a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/Incremental.kt +++ b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/Incremental.kt @@ -36,7 +36,9 @@ import org.jetbrains.kotlin.incremental.* import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.Position import org.jetbrains.kotlin.incremental.components.ScopeKind -import org.jetbrains.kotlin.incremental.storage.AppendableAbstractBasicMap +import org.jetbrains.kotlin.incremental.storage.AppendableBasicMap +import org.jetbrains.kotlin.incremental.storage.AppendableDataExternalizer +import org.jetbrains.kotlin.incremental.storage.CollectionExternalizer import org.jetbrains.kotlin.incremental.storage.FileToPathConverter import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny import org.jetbrains.kotlin.types.KotlinType @@ -49,19 +51,44 @@ import java.util.* abstract class PersistentMap, V>( storageFile: File, keyDescriptor: KeyDescriptor, - valueExternalizer: DataExternalizer, + valueExternalizer: AppendableDataExternalizer, icContext: IncrementalCompilationContext, -) : AppendableAbstractBasicMap>(storageFile, keyDescriptor, valueExternalizer, icContext) +) : AppendableBasicMap(storageFile, keyDescriptor, valueExternalizer, icContext) { + abstract operator fun get(key: K): V? + abstract operator fun set(key: K, value: V) + abstract fun remove(key: K) +} class FileToSymbolsMap( storageFile: File, icContext: IncrementalCompilationContext -) : PersistentMap( +) : PersistentMap>( storageFile, FileKeyDescriptor, - LookupSymbolExternalizer, + CollectionExternalizer(LookupSymbolExternalizer, { HashSet() }), icContext, -) +) { + override fun dumpKey(key: File): String = key.toString() + + override fun dumpValue(value: Collection): String = value.toString() + + fun add(file: File, symbol: LookupSymbol) { + storage.append(file, listOf(symbol)) + } + + override operator fun get(key: File): Collection? = storage[key] + + override operator fun set(key: File, symbols: Collection) { + storage[key] = symbols + } + + override fun remove(key: File) { + storage.remove(key) + } + + val keys: Collection + get() = storage.keys +} object FileKeyDescriptor : KeyDescriptor { override fun read(input: DataInput): File { @@ -97,16 +124,30 @@ object FileExternalizer : DataExternalizer { class FileToFilesMap( storageFile: File, icContext: IncrementalCompilationContext -) : PersistentMap( +) : PersistentMap>( storageFile, FileKeyDescriptor, - FileExternalizer, + CollectionExternalizer(FileExternalizer, { HashSet() }), icContext, ) { + + override operator fun get(key: File): Collection? = storage[key] + + override operator fun set(key: File, value: Collection) { + storage[key] = value + } + override fun dumpKey(key: File): String = key.path override fun dumpValue(value: Collection) = value.dumpCollection() + + override fun remove(key: File) { + storage.remove(key) + } + + val keys: Collection + get() = storage.keys } object symbolCollector : KSDefaultVisitor<(LookupSymbol) -> Unit, Unit>() { @@ -453,14 +494,14 @@ class IncrementalContext( updateLookupCache(dirtyFiles) // Update symbolsMap - fun , V> update(m: PersistentMap, u: MultiMap) { + fun , V> update(m: PersistentMap>, u: MultiMap) { // Update symbol caches from modified files. u.keySet().forEach { m.set(it, u[it].toSet()) } } - fun , V> remove(m: PersistentMap, removedKeys: Collection) { + fun , V> remove(m: PersistentMap>, removedKeys: Collection) { // Remove symbol caches from removed files. removedKeys.forEach { m.remove(it) diff --git a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/symbol/impl/binary/KSDeclarationDescriptorImpl.kt b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/symbol/impl/binary/KSDeclarationDescriptorImpl.kt index 1dfaa219fb..db041b2668 100644 --- a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/symbol/impl/binary/KSDeclarationDescriptorImpl.kt +++ b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/symbol/impl/binary/KSDeclarationDescriptorImpl.kt @@ -20,10 +20,10 @@ package com.google.devtools.ksp.symbol.impl.binary import com.google.devtools.ksp.memoized import com.google.devtools.ksp.processing.impl.KSNameImpl import com.google.devtools.ksp.symbol.* +import org.jetbrains.kotlin.backend.common.serialization.findPackage import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.findPackage import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.parents @@ -50,7 +50,7 @@ abstract class KSDeclarationDescriptorImpl(private val descriptor: DeclarationDe is ClassDescriptor -> KSClassDeclarationDescriptorImpl.getCached(containingDescriptor) is FunctionDescriptor -> KSFunctionDeclarationDescriptorImpl.getCached(containingDescriptor) else -> null - } + } as KSDeclaration? } override val parent: KSNode? by lazy { diff --git a/gradle.properties b/gradle.properties index 702717f109..c79458646d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ # Copied from kotlinc org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx2200m -Dfile.encoding=UTF-8 -kotlinBaseVersion=2.0.0-dev-4562 +kotlinBaseVersion=1.9.30-dev-2548 agpBaseVersion=7.0.0 intellijVersion=213.7172.25 junitVersion=4.13.1 diff --git a/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/KSPCmdLineOptionsIT.kt b/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/KSPCmdLineOptionsIT.kt index bb6dcc6804..e06136a849 100644 --- a/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/KSPCmdLineOptionsIT.kt +++ b/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/KSPCmdLineOptionsIT.kt @@ -38,7 +38,6 @@ class KSPCmdLineOptionsIT(val useKSP2: Boolean) { }.maxByOrNull { it.lastModified() }!! val compilerArgs = mutableListOf( "-no-stdlib", - "-language-version", "1.9", "-Xplugin=${kspPluginJar.absolutePath}", "-Xplugin=${kspApiJar.absolutePath}", "-P", "plugin:$kspPluginId:apclasspath=${processorJar.absolutePath}", diff --git a/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/PlaygroundIT.kt b/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/PlaygroundIT.kt index f54f0e6150..853ff5393d 100644 --- a/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/PlaygroundIT.kt +++ b/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/PlaygroundIT.kt @@ -223,6 +223,7 @@ class PlaygroundIT(val useKSP2: Boolean) { Assert.assertTrue(jarFile.getEntry("hello/HELLO.class").size > 0) Assert.assertTrue(jarFile.getEntry("com/example/AClassBuilder.class").size > 0) } + Assert.assertTrue(result.output.contains("w: Language version 2.0 is experimental")) project.restore(buildFile.path) } @@ -262,6 +263,7 @@ class PlaygroundIT(val useKSP2: Boolean) { Assert.assertTrue(jarFile.getEntry("hello/HELLO.class").size > 0) Assert.assertTrue(jarFile.getEntry("com/example/AClassBuilder.class").size > 0) } + Assert.assertTrue(result.output.contains("w: Language version 2.0 is experimental")) project.restore(buildFile.path) project.restore(gradleProperties.path) } @@ -281,10 +283,7 @@ class PlaygroundIT(val useKSP2: Boolean) { gradleRunner.buildAndCheck("clean", "build") { result -> Assert.assertTrue(result.output.contains("language version: 1.5")) Assert.assertTrue(result.output.contains("api version: 1.5")) - if (!useKSP2) { - // In case KSP 1 and KSP 2 uses different compiler versions, ignore this test for KSP 2 for now. - Assert.assertTrue(result.output.contains("compiler version: $kotlinVersion")) - } + Assert.assertTrue(result.output.contains("compiler version: $kotlinVersion")) } project.restore(buildFile.path) } @@ -300,12 +299,12 @@ class PlaygroundIT(val useKSP2: Boolean) { gradleRunner.withArguments("build").buildAndFail().let { Assert.assertEquals(TaskOutcome.SUCCESS, it.task(":workload:kspKotlin")?.outcome) Assert.assertEquals(TaskOutcome.FAILED, it.task(":workload:compileKotlin")?.outcome) - Assert.assertTrue("Unresolved reference 'AClassBuilder'" in it.output) + Assert.assertTrue("Unresolved reference: AClassBuilder" in it.output) } gradleRunner.withArguments("build").buildAndFail().let { Assert.assertEquals(TaskOutcome.UP_TO_DATE, it.task(":workload:kspKotlin")?.outcome) Assert.assertEquals(TaskOutcome.FAILED, it.task(":workload:compileKotlin")?.outcome) - Assert.assertTrue("Unresolved reference 'AClassBuilder'" in it.output) + Assert.assertTrue("Unresolved reference: AClassBuilder" in it.output) } project.restore("workload/build.gradle.kts")