From a41f7dc25d418951d266227552ad4ad188b0231c Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 18 Apr 2023 19:17:45 +0200 Subject: [PATCH] [cls] save parameter name for functional types in stub to make it available for deserialized Fir --- .../ParameterName/ParameterName.kt | 5 +++ .../ParameterName/ParameterName.txt | 39 +++++++++++++++++++ .../files/AbstractAdditionalStubInfoTest.kt | 3 ++ .../AdditionalStubInfoTestGenerated.java | 6 +++ .../decompiler/stub/TypeClsStubBuilder.kt | 34 ++++++++++++---- .../StubBasedFirTypeDeserializer.kt | 31 +++++++++++---- .../kotlin/psi/stubs/KotlinStubVersions.kt | 4 +- .../elements/KtParameterElementType.java | 6 ++- .../psi/stubs/impl/KotlinParameterStubImpl.kt | 4 +- 9 files changed, 111 insertions(+), 21 deletions(-) create mode 100644 analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/ParameterName/ParameterName.kt create mode 100644 analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/ParameterName/ParameterName.txt diff --git a/analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/ParameterName/ParameterName.kt b/analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/ParameterName/ParameterName.kt new file mode 100644 index 00000000000..b0c6666a6cc --- /dev/null +++ b/analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/ParameterName/ParameterName.kt @@ -0,0 +1,5 @@ +package test + +class ParameterName { + inline fun foo(crossinline block: (input: A, state: B) -> Unit) {} +} \ No newline at end of file diff --git a/analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/ParameterName/ParameterName.txt b/analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/ParameterName/ParameterName.txt new file mode 100644 index 00000000000..e464a2f4930 --- /dev/null +++ b/analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/ParameterName/ParameterName.txt @@ -0,0 +1,39 @@ +PsiJetFileStubImpl[package=test] +KotlinStub$PACKAGE_DIRECTIVE + KotlinStub$REFERENCE_EXPRESSION[referencedName=test] +KotlinStub$IMPORT_LIST +KotlinStub$CLASS[classId=test/ParameterName, fqName=test.ParameterName, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=true, name=ParameterName, superNames=[]] + KotlinStub$MODIFIER_LIST[public final] + KotlinStub$PRIMARY_CONSTRUCTOR[fqName=null, hasBody=false, isDelegatedCallToThis=false, isExtension=false, isTopLevel=false, name=ParameterName] + KotlinStub$MODIFIER_LIST[public] + KotlinStub$VALUE_PARAMETER_LIST + KotlinStub$CLASS_BODY + KotlinStub$FUN[fqName=test.ParameterName.foo, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=true, isExtension=false, isTopLevel=false, mayHaveContract=false, name=foo] + KotlinStub$MODIFIER_LIST[public final inline] + KotlinStub$TYPE_PARAMETER_LIST + KotlinStub$TYPE_PARAMETER[fqName=null, isInVariance=false, isOutVariance=false, name=A] + KotlinStub$TYPE_PARAMETER[fqName=null, isInVariance=false, isOutVariance=false, name=B] + KotlinStub$VALUE_PARAMETER_LIST + KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=block] + KotlinStub$MODIFIER_LIST[crossinline] + KotlinStub$TYPE_REFERENCE + KotlinStub$FUNCTION_TYPE + KotlinStub$VALUE_PARAMETER_LIST + KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null] paramNameByAnnotation: input + KotlinStub$TYPE_REFERENCE + KotlinStub$USER_TYPE + KotlinStub$REFERENCE_EXPRESSION[referencedName=A] + KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null] paramNameByAnnotation: state + KotlinStub$TYPE_REFERENCE + KotlinStub$USER_TYPE + KotlinStub$REFERENCE_EXPRESSION[referencedName=B] + KotlinStub$TYPE_REFERENCE + KotlinStub$USER_TYPE + KotlinStub$USER_TYPE + KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin] + KotlinStub$REFERENCE_EXPRESSION[referencedName=Unit] + KotlinStub$TYPE_REFERENCE + KotlinStub$USER_TYPE + KotlinStub$USER_TYPE + KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin] + KotlinStub$REFERENCE_EXPRESSION[referencedName=Unit] \ No newline at end of file diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt index 8e4dfd0c8e5..db3bbdc2f9a 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt @@ -60,6 +60,9 @@ abstract class AbstractAdditionalStubInfoTest : AbstractDecompiledClassTest() { .append(arguments.entries.joinToString(", ", "(", ")") { "${it.key.asString()} = ${it.value}" }) } } + is KotlinParameterStubImpl -> { + stub.functionTypeParameterName?.let { builder.append(" paramNameByAnnotation: ").append(it) } + } } for (child in stub.childrenStubs) { builder.append("\n").append(" ".repeat(level)) diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AdditionalStubInfoTestGenerated.java b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AdditionalStubInfoTestGenerated.java index 7d6442530e1..432bdaa528d 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AdditionalStubInfoTestGenerated.java +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AdditionalStubInfoTestGenerated.java @@ -48,6 +48,12 @@ public class AdditionalStubInfoTestGenerated extends AbstractAdditionalStubInfoT runTest("analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/OuterClassesWithFlexibleArgs/"); } + @Test + @TestMetadata("ParameterName") + public void testParameterName() throws Exception { + runTest("analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/ParameterName/"); + } + @Test @TestMetadata("PropertyInitializer") public void testPropertyInitializer() throws Exception { diff --git a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt index f20a5357a09..778b3b27d98 100644 --- a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt +++ b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt @@ -7,6 +7,7 @@ import com.intellij.psi.stubs.StubElement import com.intellij.util.io.StringRef import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.isBuiltinFunctionClass +import org.jetbrains.kotlin.constant.StringValue import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.metadata.ProtoBuf @@ -21,7 +22,6 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.protobuf.MessageLite import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.stubs.ConstantValueKind import org.jetbrains.kotlin.psi.stubs.KotlinUserTypeStub import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes import org.jetbrains.kotlin.psi.stubs.impl.* @@ -37,7 +37,8 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { fun createTypeReferenceStub( parent: StubElement, type: Type, - additionalAnnotations: () -> List = { emptyList() } + additionalAnnotations: () -> List = { emptyList() }, + loadTypeAnnotations: (Type) -> List = { c.components.annotationLoader.loadTypeAnnotations(it, c.nameResolver) } ) { val abbreviatedType = type.abbreviatedType(c.typeTable) if (abbreviatedType != null) { @@ -46,7 +47,8 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { val typeReference = KotlinPlaceHolderStubImpl(parent, KtStubElementTypes.TYPE_REFERENCE) - val annotations = c.components.annotationLoader.loadTypeAnnotations(type, c.nameResolver).filterNot { + val allAnnotationsInType = loadTypeAnnotations(type) + val annotations = allAnnotationsInType.filterNot { val isTopLevelClass = !it.classId.isNestedClass isTopLevelClass && it.classId.asSingleFqName() in ANNOTATIONS_NOT_LOADED_FOR_TYPES } @@ -271,8 +273,8 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { var suspendParameterType: Type? = null for ((index, argument) in typeArgumentsWithoutReceiverAndReturnType.withIndex()) { + val parameterType = argument.type(c.typeTable)!! if (isSuspend && index == typeArgumentsWithoutReceiverAndReturnType.size - 1) { - val parameterType = argument.type(c.typeTable)!! if (parameterType.hasClassName() && parameterType.argumentCount == 1) { val classId = c.nameResolver.getClassId(parameterType.className) val fqName = classId.asSingleFqName() @@ -286,11 +288,27 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { continue } } - val parameter = KotlinParameterStubImpl( - parameterList, fqName = null, name = null, isMutable = false, hasValOrVar = false, hasDefaultValue = false - ) + val annotations = c.components.annotationLoader.loadTypeAnnotations(parameterType, c.nameResolver) - createTypeReferenceStub(parameter, argument.type(c.typeTable)!!) + fun getFunctionTypeParameterName(annotations: List): String? { + for (annotationWithArgs in annotations) { + if (annotationWithArgs.classId.asSingleFqName() == StandardNames.FqNames.parameterName) { + return (annotationWithArgs.args.values.firstOrNull() as? StringValue)?.value + } + } + return null + } + + val parameter = KotlinParameterStubImpl( + parameterList, + fqName = null, + name = null, + isMutable = false, + hasValOrVar = false, + hasDefaultValue = false, + functionTypeParameterName = getFunctionTypeParameterName(annotations) + ) + createTypeReferenceStub(parameter, parameterType, loadTypeAnnotations = { annotations }) } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirTypeDeserializer.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirTypeDeserializer.kt index 97384b07e43..ae796ed2ab8 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirTypeDeserializer.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirTypeDeserializer.kt @@ -16,10 +16,10 @@ import org.jetbrains.kotlin.fir.declarations.builder.FirTypeParameterBuilder import org.jetbrains.kotlin.fir.declarations.utils.addDefaultBoundIfNecessary import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind -import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag -import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag -import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag -import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol +import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotation +import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationArgumentMapping +import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression +import org.jetbrains.kotlin.fir.symbols.* import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.* @@ -29,11 +29,13 @@ import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.hasSuspendModifier import org.jetbrains.kotlin.psi.psiUtil.unwrapNullability import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes import org.jetbrains.kotlin.psi.stubs.impl.* +import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.types.Variance class StubBasedFirTypeDeserializer( @@ -99,11 +101,24 @@ class StubBasedFirTypeDeserializer( } } - private fun attributesFromAnnotations(typeReference: KtTypeReference): ConeAttributes = - annotationDeserializer.loadAnnotations(typeReference).computeTypeAttributes(moduleData.session, shouldExpandTypeAliases = false) - fun type(typeReference: KtTypeReference): ConeKotlinType { - return type(typeReference, attributesFromAnnotations(typeReference)) + val annotations = annotationDeserializer.loadAnnotations(typeReference).toMutableList() + val parent = typeReference.stub?.parentStub + if (parent is KotlinParameterStubImpl) { + (parent as? KotlinParameterStubImpl)?.functionTypeParameterName?.let { paramName -> + annotations += buildAnnotation { + annotationTypeRef = buildResolvedTypeRef { + type = StandardNames.FqNames.parameterNameClassId.toLookupTag() + .constructClassType(emptyArray(), isNullable = false) + } + this.argumentMapping = buildAnnotationArgumentMapping { + mapping[Name.identifier("name")] = + buildConstExpression(null, ConstantValueKind.String, paramName, setType = true) + } + } + } + } + return type(typeReference, annotations.computeTypeAttributes(moduleData.session, shouldExpandTypeAliases = false)) } fun type(type: KotlinTypeBean): ConeKotlinType? { diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt index 02f0b1e3d57..33556c541f7 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt @@ -23,12 +23,12 @@ object KotlinStubVersions { // Though only kotlin declarations (no code in the bodies) are stubbed, please do increase this version // if you are not 100% sure it can be avoided. // Increasing this version will lead to reindexing of all kotlin source files on the first IDE startup with the new version. - const val SOURCE_STUB_VERSION = 152 + const val SOURCE_STUB_VERSION = 153 // Binary stub version should be increased if stub format (org.jetbrains.kotlin.psi.stubs.impl) is changed // or changes are made to the core stub building code (org.jetbrains.kotlin.idea.decompiler.stubBuilder). // Increasing this version will lead to reindexing of all binary files that are potentially kotlin binaries (including all class files). - private const val BINARY_STUB_VERSION = 88 + private const val BINARY_STUB_VERSION = 89 // Classfile stub version should be increased if changes are made to classfile stub building subsystem (org.jetbrains.kotlin.idea.decompiler.classFile) // Increasing this version will lead to reindexing of all classfiles. diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtParameterElementType.java b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtParameterElementType.java index 06d82e3b075..f4f2a7a49a8 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtParameterElementType.java +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtParameterElementType.java @@ -42,7 +42,7 @@ public class KtParameterElementType extends KtStubElementType) parentStub, fqNameRef, StringRef.fromString(psi.getName()), - psi.isMutable(), psi.hasValOrVar(), psi.hasDefaultValue() + psi.isMutable(), psi.hasValOrVar(), psi.hasDefaultValue(), null ); } @@ -54,6 +54,7 @@ public class KtParameterElementType extends KtStubElementType) parentStub, fqName, name, isMutable, hasValOrValNode, hasDefaultValue); + return new KotlinParameterStubImpl((StubElement) parentStub, fqName, name, isMutable, hasValOrValNode, hasDefaultValue, + dataStream.readNameString()); } @Override diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinParameterStubImpl.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinParameterStubImpl.kt index 51182796247..073c8a00168 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinParameterStubImpl.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinParameterStubImpl.kt @@ -30,8 +30,10 @@ class KotlinParameterStubImpl( private val name: StringRef?, private val isMutable: Boolean, private val hasValOrVar: Boolean, - private val hasDefaultValue: Boolean + private val hasDefaultValue: Boolean, + val functionTypeParameterName: String? = null ) : KotlinStubBaseImpl(parent, KtStubElementTypes.VALUE_PARAMETER), KotlinParameterStub { + override fun getName(): String? { return StringRef.toString(name) }