From 411ab1d6fe8695a2afdc4311a7207054e9eebce6 Mon Sep 17 00:00:00 2001 From: Ting-Yuan Huang Date: Thu, 12 Sep 2024 13:40:19 -0700 Subject: [PATCH] Make setter's parameter name `value` by default per https://kotlinlang.org/docs/properties.html#getters-and-setters KSP1 is left unchanged. --- .../symbol/kotlin/KSValueParameterImpl.kt | 2 +- .../com/google/devtools/ksp/test/KSPAATest.kt | 4 +- .../testData/annotationInDependencies.kt | 202 ++++++++++++++++++ .../testData/getSymbolsFromAnnotation.kt | 2 +- .../testData/implicitPropertyAccessors.kt | 45 ++++ .../testData/javaWildcards2.kt | 14 +- kotlin-analysis-api/testData/parent.kt | 4 +- .../ImplicitPropertyAccessorProcessor.kt | 17 +- .../testData/api/implicitPropertyAccessors.kt | 21 +- 9 files changed, 287 insertions(+), 24 deletions(-) create mode 100644 kotlin-analysis-api/testData/annotationInDependencies.kt create mode 100644 kotlin-analysis-api/testData/implicitPropertyAccessors.kt diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterImpl.kt index 29d718d227..7bca6ea13d 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterImpl.kt @@ -41,7 +41,7 @@ class KSValueParameterImpl private constructor( override val name: KSName? by lazy { if (origin == Origin.SYNTHETIC && parent is KSPropertySetter) { - KSNameImpl.getCached("") + KSNameImpl.getCached("value") } else { KSNameImpl.getCached(ktValueParameterSymbol.name.asString()) } diff --git a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt index fe77a4667e..15fdd98887 100644 --- a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt +++ b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt @@ -67,7 +67,7 @@ class KSPAATest : AbstractKSPAATest() { @TestMetadata("annotationInDependencies.kt") @Test fun testAnnotationsInDependencies() { - runTest("../test-utils/testData/api/annotationInDependencies.kt") + runTest("../kotlin-analysis-api/testData/annotationInDependencies.kt") } @TestMetadata("annotationOnConstructorParameter.kt") @@ -319,7 +319,7 @@ class KSPAATest : AbstractKSPAATest() { @TestMetadata("implicitPropertyAccessors.kt") @Test fun testImplicitPropertyAccessors() { - runTest("../test-utils/testData/api/implicitPropertyAccessors.kt") + runTest("../kotlin-analysis-api/testData/implicitPropertyAccessors.kt") } @TestMetadata("inheritedTypeAlias.kt") diff --git a/kotlin-analysis-api/testData/annotationInDependencies.kt b/kotlin-analysis-api/testData/annotationInDependencies.kt new file mode 100644 index 0000000000..34dbdb45b3 --- /dev/null +++ b/kotlin-analysis-api/testData/annotationInDependencies.kt @@ -0,0 +1,202 @@ +/* + * Copyright 2020 Google LLC + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * 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. + */ + +// WITH_RUNTIME +// TEST PROCESSOR: AnnotationsInDependenciesProcessor +// EXPECTED: +// main.KotlinClass -> +// class main.KotlinClass : annotations.ClassTarget{[value = onClass]} +// class main.KotlinClass : annotations.NoTargetAnnotation{[value = onClass]} +// function myFun : annotations.FunctionTarget{[value = onMyFun]} +// function myFun : annotations.NoTargetAnnotation{[value = onMyFun]} +// getter of property prop : annotations.PropertyGetterTarget{[value = get:]} +// parameter param1 : annotations.NoTargetAnnotation{[value = onParam1]} +// parameter param1 : annotations.ValueParameterTarget{[value = onParam1]} +// parameter param2 : annotations.NoTargetAnnotation{[value = onParam2]} +// parameter param2 : annotations.ValueParameterTarget{[value = onParam2]} +// parameter value : annotations.ValueParameterTarget{[value = onPropSetter]} +// parameter value : annotations.ValueParameterTarget{[value = onProp]} +// property prop : annotations.FieldTarget2{[value = field:]} +// property prop : annotations.FieldTarget{[value = onProp]} +// property prop : annotations.NoTargetAnnotation{[value = onProp]} +// property prop : annotations.PropertyTarget{[value = onProp]} +// setter of property prop : annotations.PropertySetterTarget{[value = set:]} +// lib.KotlinClass -> +// class lib.KotlinClass : annotations.ClassTarget{[value = onClass]} +// class lib.KotlinClass : annotations.NoTargetAnnotation{[value = onClass]} +// function myFun : annotations.FunctionTarget{[value = onMyFun]} +// function myFun : annotations.NoTargetAnnotation{[value = onMyFun]} +// getter of property prop : annotations.PropertyGetterTarget{[value = get:]} +// parameter param1 : annotations.NoTargetAnnotation{[value = onParam1]} +// parameter param1 : annotations.ValueParameterTarget{[value = onParam1]} +// parameter param2 : annotations.NoTargetAnnotation{[value = onParam2]} +// parameter param2 : annotations.ValueParameterTarget{[value = onParam2]} +// parameter propInConstructor : annotations.ValueParameterTarget{[value = propInConstructor]} +// property prop : annotations.FieldTarget2{[value = field:]} +// property prop : annotations.FieldTarget{[value = onProp]} +// property prop : annotations.NoTargetAnnotation{[value = onProp]} +// property prop : annotations.PropertyTarget{[value = onProp]} +// setter of property prop : annotations.PropertySetterTarget{[value = set:]} +// main.DataClass -> +// class main.DataClass : annotations.ClassTarget{[value = onDataClass]} +// class main.DataClass : annotations.NoTargetAnnotation{[value = onDataClass]} +// getter of property constructorParam : annotations.PropertyGetterTarget{[value = get:]} +// parameter constructorParam : annotations.NoTargetAnnotation{[value = onConstructorParam]} +// parameter constructorParam : annotations.ValueParameterTarget{[value = onConstructorParam]} +// parameter value : annotations.ValueParameterTarget{[value = onConstructorParam]} +// property constructorParam : annotations.FieldTarget2{[value = field:]} +// property constructorParam : annotations.FieldTarget{[value = onConstructorParam]} +// property constructorParam : annotations.NoTargetAnnotation{[value = onConstructorParam]} +// property constructorParam : annotations.PropertyTarget{[value = onConstructorParam]} +// property constructorParam : annotations.ValueParameterAndFieldTarget{[value = valueParameterAndField]} +// setter of property constructorParam : annotations.PropertySetterTarget{[value = set:]} +// lib.DataClass -> +// class lib.DataClass : annotations.ClassTarget{[value = onDataClass]} +// class lib.DataClass : annotations.NoTargetAnnotation{[value = onDataClass]} +// getter of property constructorParam : annotations.PropertyGetterTarget{[value = get:]} +// parameter constructorParam : annotations.NoTargetAnnotation{[value = onConstructorParam]} +// property constructorParam : annotations.FieldTarget2{[value = field:]} +// property constructorParam : annotations.FieldTarget{[value = onConstructorParam]} +// property constructorParam : annotations.PropertyTarget{[value = onConstructorParam]} +// setter of property constructorParam : annotations.PropertySetterTarget{[value = set:]} +// END +// MODULE: annotations +// FILE: Annotations.kt +package annotations; +annotation class NoTargetAnnotation(val value:String) + +@Target(AnnotationTarget.FIELD) +annotation class FieldTarget(val value:String) + +@Target(AnnotationTarget.FIELD) +annotation class FieldTarget2(val value:String) + +@Target(AnnotationTarget.PROPERTY) +annotation class PropertyTarget(val value:String) + +@Target(AnnotationTarget.PROPERTY_SETTER) +annotation class PropertySetterTarget(val value:String) + +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class PropertyGetterTarget(val value:String) + +@Target(AnnotationTarget.CLASS) +annotation class ClassTarget(val value:String) + +@Target(AnnotationTarget.FUNCTION) +annotation class FunctionTarget(val value:String) + +@Target(AnnotationTarget.VALUE_PARAMETER) +annotation class ValueParameterTarget(val value:String) + +@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FIELD) +annotation class ValueParameterAndFieldTarget(val value: String) + +// MODULE: lib(annotations) +// FILE: ClassInLib.kt +package lib; +import annotations.*; +@NoTargetAnnotation("onClass") +@ClassTarget("onClass") +class KotlinClass(@ValueParameterTarget("propInConstructor") val propInConstructor: String ) { + @NoTargetAnnotation("onProp") + @FieldTarget("onProp") + @PropertyTarget("onProp") + @set:PropertySetterTarget("set:") + @get:PropertyGetterTarget("get:") + @field:FieldTarget2("field:") + var prop : String = "" + + @NoTargetAnnotation("onMyFun") + @FunctionTarget("onMyFun") + fun myFun( + @NoTargetAnnotation("onParam1") + @ValueParameterTarget("onParam1") + param1: String, + @NoTargetAnnotation("onParam2") + @ValueParameterTarget("onParam2") + param2: Int + ) { + } +} + +@NoTargetAnnotation("onDataClass") +@ClassTarget("onDataClass") +class DataClass( + @NoTargetAnnotation("onConstructorParam") + @FieldTarget("onConstructorParam") + @PropertyTarget("onConstructorParam") + @set:PropertySetterTarget("set:") + @get:PropertyGetterTarget("get:") + @field:FieldTarget2("field:") + var constructorParam : String = "" +) +// FILE: lib/JavaClass.java +package lib; +import annotations.*; +public class JavaClass {} +// MODULE: main(lib, annotations) +// FILE: ClassInModule2.kt +package main; +import annotations.*; +@NoTargetAnnotation("onClass") +@ClassTarget("onClass") +class KotlinClass { + @NoTargetAnnotation("onProp") + @FieldTarget("onProp") + @PropertyTarget("onProp") + @set:PropertySetterTarget("set:") + @get:PropertyGetterTarget("get:") + @field:FieldTarget2("field:") + @setparam:ValueParameterTarget("onProp") + var prop : String = "" + @setparam:ValueParameterTarget("onPropSetter") + set + + @NoTargetAnnotation("onMyFun") + @FunctionTarget("onMyFun") + fun myFun( + @NoTargetAnnotation("onParam1") + @ValueParameterTarget("onParam1") + param1: String, + @NoTargetAnnotation("onParam2") + @ValueParameterTarget("onParam2") + param2: Int + ) { + } +} + +@NoTargetAnnotation("onDataClass") +@ClassTarget("onDataClass") +class DataClass( + @NoTargetAnnotation("onConstructorParam") + @FieldTarget("onConstructorParam") + @PropertyTarget("onConstructorParam") + @set:PropertySetterTarget("set:") + @get:PropertyGetterTarget("get:") + @field:FieldTarget2("field:") + @field:ValueParameterAndFieldTarget("valueParameterAndField") + @setparam:ValueParameterTarget("onConstructorParam") + @ValueParameterTarget("onConstructorParam") + var constructorParam : String = "" +) +// FILE: main/JavaClassInModule2.java +pakage main; +import annotations.*; +@NoTargetAnnotation +class JavaClassInMain { +} diff --git a/kotlin-analysis-api/testData/getSymbolsFromAnnotation.kt b/kotlin-analysis-api/testData/getSymbolsFromAnnotation.kt index 0429f8fcba..6c03b23064 100644 --- a/kotlin-analysis-api/testData/getSymbolsFromAnnotation.kt +++ b/kotlin-analysis-api/testData/getSymbolsFromAnnotation.kt @@ -116,7 +116,7 @@ // RGB.B:KSClassDeclaration // ==== Cnno in depth ==== // constructorParameterFoo:KSPropertyDeclaration -// :KSValueParameter +// value:KSValueParameter // constructorParameterFoo:KSValueParameter // x:KSPropertyDeclaration // x:KSValueParameter diff --git a/kotlin-analysis-api/testData/implicitPropertyAccessors.kt b/kotlin-analysis-api/testData/implicitPropertyAccessors.kt new file mode 100644 index 0000000000..fa048f18aa --- /dev/null +++ b/kotlin-analysis-api/testData/implicitPropertyAccessors.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2022 Google LLC + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * 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. + */ + +// TEST PROCESSOR: ImplicitPropertyAccessorProcessor +// EXPECTED: +// privateGetterVal.getter(): Int +// privateGetterVar.getter(): String +// privateGetterVar.setter()(value: String) +// val1.getter(): Int +// var2.getter(): String +// var2.setter()(value: String) +// END +// MODULE: lib +// FILE: lib/Bar.kt +package lib + +class Bar { + val val1: Int = 0 + var var2: String = "" +} +// MODULE: main(lib) +// FILE: Foo.kt + +class Foo { + val privateGetterVal: Int + private get + + var privateGetterVar: String + set + private get +} diff --git a/kotlin-analysis-api/testData/javaWildcards2.kt b/kotlin-analysis-api/testData/javaWildcards2.kt index 068dd3ccbf..0f0949efed 100644 --- a/kotlin-analysis-api/testData/javaWildcards2.kt +++ b/kotlin-analysis-api/testData/javaWildcards2.kt @@ -29,25 +29,25 @@ // R : Any? // propWithFinalType : String // propWithFinalType.getter() : String -// : String +// value : String // propWithOpenType : Number // propWithOpenType.getter() : Number -// : Number +// value : Number // propWithFinalGeneric : List // propWithFinalGeneric.getter() : List -// : List +// value : List // propWithOpenGeneric : List // propWithOpenGeneric.getter() : List -// : List +// value : List // propWithTypeArg : R // propWithTypeArg.getter() : R -// : R +// value : R // propWithTypeArgGeneric : List // propWithTypeArgGeneric.getter() : List -// : List +// value : List // propWithOpenTypeButSuppressAnnotation : Number // propWithOpenTypeButSuppressAnnotation.getter() : Number -// : Number +// value : Number // list2 : List // list1 : List // list3 : List diff --git a/kotlin-analysis-api/testData/parent.kt b/kotlin-analysis-api/testData/parent.kt index b1ccab2b46..04efe45272 100644 --- a/kotlin-analysis-api/testData/parent.kt +++ b/kotlin-analysis-api/testData/parent.kt @@ -142,8 +142,8 @@ // parent of String: String // parent of String: b.getter() // parent of b.getter(): b -// parent of String: -// parent of : b.setter() +// parent of String: value +// parent of value: b.setter() // parent of b.setter(): b // parent of b: topClass // parent of topClass: synthetic constructor for topClass diff --git a/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/ImplicitPropertyAccessorProcessor.kt b/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/ImplicitPropertyAccessorProcessor.kt index cef47f3ce5..104ecd757b 100644 --- a/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/ImplicitPropertyAccessorProcessor.kt +++ b/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/ImplicitPropertyAccessorProcessor.kt @@ -13,12 +13,17 @@ class ImplicitPropertyAccessorProcessor : AbstractTestProcessor() { } override fun process(resolver: Resolver): List { - val foo = resolver.getClassDeclarationByName("Foo")!! - foo.declarations.filterIsInstance().forEach { prop -> - result.add(prop.getter?.returnType.toString()) - prop.setter?.parameter?.let { - result.add(it.toString()) - result.add(it.type.toString()) + listOf("Foo", "lib.Bar").forEach { clsName -> + val cls = resolver.getClassDeclarationByName(clsName)!! + cls.declarations.filterIsInstance().forEach { prop -> + prop.getter?.let { getter -> + result.add("$getter: ${getter.returnType}") + } + prop.setter?.let { setter -> + val param = setter.parameter + val paramName = param.name?.getShortName() + result.add("$setter($paramName: ${setter.parameter.type})") + } } } return emptyList() diff --git a/test-utils/testData/api/implicitPropertyAccessors.kt b/test-utils/testData/api/implicitPropertyAccessors.kt index af885296d1..8a6fbf37da 100644 --- a/test-utils/testData/api/implicitPropertyAccessors.kt +++ b/test-utils/testData/api/implicitPropertyAccessors.kt @@ -17,12 +17,23 @@ // TEST PROCESSOR: ImplicitPropertyAccessorProcessor // EXPECTED: -// Int -// String -// -// String +// privateGetterVal.getter(): Int +// privateGetterVar.getter(): String +// privateGetterVar.setter()(: String) +// val1.getter(): Int +// var2.getter(): String +// var2.setter()(: String) // END -// FILE: a.kt +// MODULE: lib +// FILE: lib/Bar.kt +package lib + +class Bar { + val val1: Int = 0 + var var2: String = "" +} +// MODULE: main(lib) +// FILE: Foo.kt class Foo { val privateGetterVal: Int