KT-43205 Ignore annotations in CallableClsStubBuilder when needed

Kotlin compiler can add `@Deprecated` annotations to the fields of
private companion objects, and if those annotations are not supposed to
be shown in decompiled code and used, the field is marked with
`HAS_ANNOTATIONS=false` flag (see KT-25009)

However, it was not taken into account in stubs building process, which
led to the 'Stubs vs PSI mismatch' exceptions

^KT-43205 Fixed

Also, restore the order of nested typealiases and classes (see KT-41859)

We didn't want to bump the version of the stubs when we fixed this
issue; now we have an opportunity to restore the order back to
match the `MemberComparator`

Also, some refactoring is done to underscore that
`createPackageDeclarationsStubs` is suitable only for packages, not
for any declarations container
This commit is contained in:
Roman Golyshev
2020-11-09 15:49:50 +00:00
parent fdd7fa5aea
commit ebfbc2f601
13 changed files with 202 additions and 51 deletions
@@ -47,7 +47,7 @@ open class KotlinMetadataStubBuilder(
val context = components.createContext(nameResolver, packageFqName, TypeTable(packageProto.typeTable))
val fileStub = createFileStub(packageFqName, isScript = false)
createDeclarationsStubs(
createPackageDeclarationsStubs(
fileStub, context,
ProtoContainer.Package(packageFqName, context.nameResolver, context.typeTable, source = null),
packageProto
@@ -26,15 +26,14 @@ import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
import org.jetbrains.kotlin.serialization.deserialization.getName
fun createDeclarationsStubs(
fun createPackageDeclarationsStubs(
parentStub: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer,
protoContainer: ProtoContainer.Package,
packageProto: ProtoBuf.Package
) {
createDeclarationsStubs(
parentStub, outerContext, protoContainer, packageProto.functionList, packageProto.propertyList, packageProto.typeAliasList
)
createDeclarationsStubs(parentStub, outerContext, protoContainer, packageProto.functionList, packageProto.propertyList)
createTypeAliasesStubs(parentStub, outerContext, protoContainer, packageProto.typeAliasList)
}
fun createDeclarationsStubs(
@@ -43,7 +42,6 @@ fun createDeclarationsStubs(
protoContainer: ProtoContainer,
functionProtos: List<ProtoBuf.Function>,
propertyProtos: List<ProtoBuf.Property>,
typeAliasesProtos: List<ProtoBuf.TypeAlias>
) {
for (propertyProto in propertyProtos) {
if (!shouldSkip(propertyProto.flags, outerContext.nameResolver.getName(propertyProto.name))) {
@@ -55,7 +53,14 @@ fun createDeclarationsStubs(
FunctionClsStubBuilder(parentStub, outerContext, protoContainer, functionProto).build()
}
}
}
fun createTypeAliasesStubs(
parentStub: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
protoContainer: ProtoContainer,
typeAliasesProtos: List<ProtoBuf.TypeAlias>
) {
for (typeAliasProto in typeAliasesProtos) {
createTypeAliasStub(parentStub, typeAliasProto, protoContainer, outerContext)
}
@@ -139,7 +144,7 @@ private class FunctionClsStubBuilder(
.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.RECEIVER) }
}
override val returnType: ProtoBuf.Type?
override val returnType: ProtoBuf.Type
get() = functionProto.returnType(c.typeTable)
override fun createValueParameterList() {
@@ -153,6 +158,9 @@ private class FunctionClsStubBuilder(
listOf(VISIBILITY, OPERATOR, INFIX, EXTERNAL_FUN, INLINE, TAILREC, SUSPEND) + modalityModifier
)
// If function is marked as having no annotations, we don't create stubs for it
if (!Flags.HAS_ANNOTATIONS.get(functionProto.flags)) return
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
protoContainer, functionProto, AnnotatedCallableKind.FUNCTION
)
@@ -192,7 +200,7 @@ private class PropertyClsStubBuilder(
.loadExtensionReceiverParameterAnnotations(protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY_GETTER)
.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.RECEIVER) }
override val returnType: ProtoBuf.Type?
override val returnType: ProtoBuf.Type
get() = propertyProto.returnType(c.typeTable)
override fun createValueParameterList() {
@@ -207,6 +215,9 @@ private class PropertyClsStubBuilder(
listOf(VISIBILITY, LATEINIT, EXTERNAL_PROPERTY) + constModifier + modalityModifier
)
// If field is marked as having no annotations, we don't create stubs for it
if (!Flags.HAS_ANNOTATIONS.get(propertyProto.flags)) return
val propertyAnnotations =
c.components.annotationLoader.loadCallableAnnotations(protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY)
val backingFieldAnnotations =
@@ -260,6 +271,9 @@ private class ConstructorClsStubBuilder(
override fun createModifierListStub() {
val modifierListStubImpl = createModifierListStubForDeclaration(callableStub, constructorProto.flags, listOf(VISIBILITY))
// If constructor is marked as having no annotations, we don't create stubs for it
if (!Flags.HAS_ANNOTATIONS.get(constructorProto.flags)) return
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
protoContainer, constructorProto, AnnotatedCallableKind.FUNCTION
)
@@ -178,6 +178,7 @@ private class ClassClsStubBuilder(
createCompanionObjectStub(classBody)
createCallableMemberStubs(classBody)
createInnerAndNestedClasses(classBody)
createTypeAliasesStubs(classBody)
}
private fun createCompanionObjectStub(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
@@ -219,10 +220,7 @@ private class ClassClsStubBuilder(
}
}
// FIXME using this function breaks the order of `MemberComparator` (see KT-41859)
createDeclarationsStubs(
classBody, c, thisAsProtoContainer, classProto.functionList, classProto.propertyList, classProto.typeAliasList
)
createDeclarationsStubs(classBody, c, thisAsProtoContainer, classProto.functionList, classProto.propertyList)
}
private fun isClass(): Boolean {
@@ -245,6 +243,10 @@ private class ClassClsStubBuilder(
}
}
private fun createTypeAliasesStubs(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
createTypeAliasesStubs(classBody, c, thisAsProtoContainer, classProto.typeAliasList)
}
private fun createNestedClassStub(classBody: StubElement<out PsiElement>, nestedClassId: ClassId) {
val (nameResolver, classProto, _, sourceElement) =
c.components.classDataFinder.findClassData(nestedClassId)
@@ -50,7 +50,7 @@ fun createPackageFacadeStub(
): KotlinFileStubImpl {
val fileStub = KotlinFileStubForIde.forFile(packageFqName, isScript = false)
setupFileStub(fileStub, packageFqName)
createDeclarationsStubs(
createPackageDeclarationsStubs(
fileStub, c, ProtoContainer.Package(packageFqName, c.nameResolver, c.typeTable, source = null), packageProto
)
return fileStub
@@ -68,7 +68,7 @@ fun createFileFacadeStub(
packageFqName, c.nameResolver, c.typeTable,
JvmPackagePartSource(JvmClassName.byClassId(ClassId.topLevel(facadeFqName)), null, packageProto, c.nameResolver)
)
createDeclarationsStubs(fileStub, c, container, packageProto)
createPackageDeclarationsStubs(fileStub, c, container, packageProto)
return fileStub
}
@@ -90,7 +90,7 @@ fun createMultifileClassStub(
packageFqName, partContext.nameResolver, partContext.typeTable,
JvmPackagePartSource(partFile, packageProto, nameResolver)
)
createDeclarationsStubs(fileStub, partContext, container, packageProto)
createPackageDeclarationsStubs(fileStub, partContext, container, packageProto)
}
return fileStub
}