Skip to content

Commit 00dbaf8

Browse files
ting-yuanKSP Auto Pick
authored andcommitted
KSP2: fix KSValueParameter.isVal and isVar
for symbols from libraries. (cherry picked from commit a8a204f)
1 parent 054ffb4 commit 00dbaf8

File tree

4 files changed

+95
-2
lines changed

4 files changed

+95
-2
lines changed

kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterImpl.kt

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ import com.google.devtools.ksp.common.lazyMemoizedSequence
2424
import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl
2525
import com.google.devtools.ksp.symbol.*
2626
import org.jetbrains.kotlin.analysis.api.fir.symbols.KaFirValueParameterSymbol
27+
import org.jetbrains.kotlin.analysis.api.symbols.KaClassSymbol
28+
import org.jetbrains.kotlin.analysis.api.symbols.KaConstructorSymbol
29+
import org.jetbrains.kotlin.analysis.api.symbols.KaPropertySymbol
30+
import org.jetbrains.kotlin.analysis.api.symbols.KaSymbolOrigin
2731
import org.jetbrains.kotlin.analysis.api.symbols.KaValueParameterSymbol
2832
import org.jetbrains.kotlin.analysis.api.types.abbreviationOrSelf
2933
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
@@ -77,11 +81,26 @@ class KSValueParameterImpl private constructor(
7781
override val isCrossInline: Boolean
7882
get() = ktValueParameterSymbol.isCrossinline
7983

84+
private val KaValueParameterSymbol.primaryConstructorProperty: KaPropertySymbol? by lazy {
85+
when (ktValueParameterSymbol.origin) {
86+
// ktValueParameterSymbol.generatedPrimaryConstructorProperty is always null in libraries.
87+
// TODO: fix in AA
88+
KaSymbolOrigin.LIBRARY, KaSymbolOrigin.JAVA_LIBRARY -> analyze {
89+
val cstr = ktValueParameterSymbol.containingDeclaration as? KaConstructorSymbol
90+
val cls = cstr?.containingDeclaration as? KaClassSymbol
91+
cls?.declaredMemberScope?.declarations?.filterIsInstance<KaPropertySymbol>()
92+
?.firstOrNull { it.name == ktValueParameterSymbol.name }
93+
}
94+
95+
else -> ktValueParameterSymbol.generatedPrimaryConstructorProperty
96+
}
97+
}
98+
8099
override val isVal: Boolean
81-
get() = (ktValueParameterSymbol.psi as? KtParameter)?.let { it.hasValOrVar() && !it.isMutable } ?: false
100+
get() = ktValueParameterSymbol.primaryConstructorProperty?.isVal == true
82101

83102
override val isVar: Boolean
84-
get() = (ktValueParameterSymbol.psi as? KtParameter)?.let { it.hasValOrVar() && it.isMutable } ?: false
103+
get() = ktValueParameterSymbol.primaryConstructorProperty?.isVal == false
85104

86105
override val hasDefault: Boolean by lazy {
87106
ktValueParameterSymbol.hasDefaultValue
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.google.devtools.ksp.processor
2+
3+
import com.google.devtools.ksp.getClassDeclarationByName
4+
import com.google.devtools.ksp.processing.Resolver
5+
import com.google.devtools.ksp.symbol.KSAnnotated
6+
7+
class ValueParameterProcessor : AbstractTestProcessor() {
8+
val results = mutableListOf<String>()
9+
10+
override fun toResult(): List<String> {
11+
return results
12+
}
13+
14+
override fun process(resolver: Resolver): List<KSAnnotated> {
15+
for (clsName in listOf("MyClassSrc", "MyClassLib")) {
16+
val clsDecl = resolver.getClassDeclarationByName(clsName)!!
17+
clsDecl.primaryConstructor!!.parameters.sortedBy { it.name!!.asString() }.forEach {
18+
results.add("$clsName.${it.name!!.asString()}: isVal: ${it.isVal}, isVar: ${it.isVar}")
19+
}
20+
}
21+
return emptyList()
22+
}
23+
}

kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,12 @@ class KSPAATest : AbstractKSPAATest() {
684684
runTest("../kotlin-analysis-api/testData/typeParameterVariance.kt")
685685
}
686686

687+
@TestMetadata("valueParameter.kt")
688+
@Test
689+
fun testValueParameter() {
690+
runTest("../kotlin-analysis-api/testData/valueParameter.kt")
691+
}
692+
687693
@TestMetadata("varianceTypeCheck.kt")
688694
@Test
689695
fun testVarianceTypeCheck() {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
* Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
// TEST PROCESSOR: ValueParameterProcessor
19+
// EXPECTED:
20+
// MyClassSrc.field: isVal: false, isVar: false
21+
// MyClassSrc.valField: isVal: true, isVar: false
22+
// MyClassSrc.varField: isVal: false, isVar: true
23+
// MyClassLib.field: isVal: false, isVar: false
24+
// MyClassLib.valField: isVal: true, isVar: false
25+
// MyClassLib.varField: isVal: false, isVar: true
26+
// END
27+
28+
// MODULE: lib
29+
// FILE: lib.kt
30+
31+
class MyClassLib(
32+
field: String,
33+
val valField: String,
34+
var varField: String,
35+
)
36+
37+
// MODULE: main(lib)
38+
// FILE: main.kt
39+
40+
class MyClassSrc(
41+
field: String,
42+
val valField: String,
43+
var varField: String,
44+
)
45+

0 commit comments

Comments
 (0)