Support type aliases in stub builder
This commit is contained in:
+2
-2
@@ -51,10 +51,10 @@ class KotlinBuiltInStubBuilder : ClsStubBuilder() {
|
||||
val context = components.createContext(nameResolver, packageFqName, TypeTable(packageProto.typeTable))
|
||||
|
||||
val fileStub = createFileStub(packageFqName)
|
||||
createCallableStubs(
|
||||
createDeclarationsStubs(
|
||||
fileStub, context,
|
||||
ProtoContainer.Package(packageFqName, context.nameResolver, context.typeTable, source = null),
|
||||
packageProto.functionList, packageProto.propertyList
|
||||
packageProto
|
||||
)
|
||||
for (classProto in file.classesToDecompile) {
|
||||
createClassStub(
|
||||
|
||||
+17
-2
@@ -31,12 +31,23 @@ import org.jetbrains.kotlin.serialization.ProtoBuf.MemberKind
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf.Modality
|
||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||
|
||||
fun createCallableStubs(
|
||||
fun createDeclarationsStubs(
|
||||
parentStub: StubElement<out PsiElement>,
|
||||
outerContext: ClsStubBuilderContext,
|
||||
protoContainer: ProtoContainer,
|
||||
packageProto: ProtoBuf.Package
|
||||
) {
|
||||
createDeclarationsStubs(
|
||||
parentStub, outerContext, protoContainer, packageProto.functionList, packageProto.propertyList, packageProto.typeAliasList)
|
||||
}
|
||||
|
||||
fun createDeclarationsStubs(
|
||||
parentStub: StubElement<out PsiElement>,
|
||||
outerContext: ClsStubBuilderContext,
|
||||
protoContainer: ProtoContainer,
|
||||
functionProtos: List<ProtoBuf.Function>,
|
||||
propertyProtos: List<ProtoBuf.Property>
|
||||
propertyProtos: List<ProtoBuf.Property>,
|
||||
typeAliasesProtos: List<ProtoBuf.TypeAlias>
|
||||
) {
|
||||
for (propertyProto in propertyProtos) {
|
||||
if (!shouldSkip(propertyProto.flags, outerContext.nameResolver.getName(propertyProto.name))) {
|
||||
@@ -48,6 +59,10 @@ fun createCallableStubs(
|
||||
FunctionClsStubBuilder(parentStub, outerContext, protoContainer, functionProto).build()
|
||||
}
|
||||
}
|
||||
|
||||
for (typeAliasProto in typeAliasesProtos) {
|
||||
createTypeAliasStub(parentStub, typeAliasProto, protoContainer, outerContext)
|
||||
}
|
||||
}
|
||||
|
||||
fun createConstructorStub(
|
||||
|
||||
+2
-1
@@ -226,7 +226,8 @@ private class ClassClsStubBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
createCallableStubs(classBody, c, thisAsProtoContainer, classProto.functionList, classProto.propertyList)
|
||||
createDeclarationsStubs(
|
||||
classBody, c, thisAsProtoContainer, classProto.functionList, classProto.propertyList, classProto.typeAliasList)
|
||||
}
|
||||
|
||||
private fun isClass(): Boolean {
|
||||
|
||||
+7
-2
@@ -44,6 +44,7 @@ import java.util.*
|
||||
class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
||||
|
||||
fun createTypeReferenceStub(parent: StubElement<out PsiElement>, type: Type) {
|
||||
if (type.hasAbbreviatedType()) return createTypeReferenceStub(parent, type.abbreviatedType)
|
||||
val typeReference = KotlinPlaceHolderStubImpl<KtTypeReference>(parent, KtStubElementTypes.TYPE_REFERENCE)
|
||||
|
||||
val annotations = c.components.annotationLoader.loadTypeAnnotations(type, c.nameResolver).filterNot {
|
||||
@@ -61,7 +62,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
||||
}
|
||||
|
||||
when {
|
||||
type.hasClassName() -> createClassReferenceTypeStub(effectiveParent, type, annotations)
|
||||
type.hasClassName() || type.hasTypeAliasName() -> createClassReferenceTypeStub(effectiveParent, type, annotations)
|
||||
type.hasTypeParameter() -> createTypeParameterStub(c.typeParameters[type.typeParameter])
|
||||
type.hasTypeParameterName() -> createTypeParameterStub(c.nameResolver.getName(type.typeParameterName))
|
||||
}
|
||||
@@ -77,7 +78,11 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
||||
}
|
||||
}
|
||||
|
||||
val classId = c.nameResolver.getClassId(type.className)
|
||||
assert(type.hasClassName() || type.hasTypeAliasName()) {
|
||||
"Class reference stub must have either class or type alias name"
|
||||
}
|
||||
|
||||
val classId = c.nameResolver.getClassId(if (type.hasClassName()) type.className else type.typeAliasName)
|
||||
val shouldBuildAsFunctionType = isNumberedFunctionClassFqName(classId.asSingleFqName().toUnsafe())
|
||||
&& type.argumentList.none { it.projection == Projection.STAR }
|
||||
if (shouldBuildAsFunctionType) {
|
||||
|
||||
+4
-6
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.flags.FlagsToModifiers
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinFileStubForIde
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
@@ -37,7 +36,6 @@ import org.jetbrains.kotlin.psi.stubs.KotlinUserTypeStub
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.serialization.Flags
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
|
||||
@@ -62,8 +60,8 @@ fun createPackageFacadeStub(
|
||||
): KotlinFileStubImpl {
|
||||
val fileStub = KotlinFileStubForIde.forFile(packageFqName, packageFqName.isRoot)
|
||||
setupFileStub(fileStub, packageFqName)
|
||||
createCallableStubs(fileStub, c, ProtoContainer.Package(packageFqName, c.nameResolver, c.typeTable, source = null),
|
||||
packageProto.functionList, packageProto.propertyList)
|
||||
createDeclarationsStubs(
|
||||
fileStub, c, ProtoContainer.Package(packageFqName, c.nameResolver, c.typeTable, source = null), packageProto)
|
||||
return fileStub
|
||||
}
|
||||
|
||||
@@ -78,7 +76,7 @@ fun createFileFacadeStub(
|
||||
val container = ProtoContainer.Package(
|
||||
packageFqName, c.nameResolver, c.typeTable, JvmPackagePartSource(JvmClassName.byClassId(ClassId.topLevel(facadeFqName)), null)
|
||||
)
|
||||
createCallableStubs(fileStub, c, container, packageProto.functionList, packageProto.propertyList)
|
||||
createDeclarationsStubs(fileStub, c, container, packageProto)
|
||||
return fileStub
|
||||
}
|
||||
|
||||
@@ -98,7 +96,7 @@ fun createMultifileClassStub(
|
||||
val partContext = components.createContext(nameResolver, packageFqName, TypeTable(packageProto.typeTable))
|
||||
val container = ProtoContainer.Package(packageFqName, partContext.nameResolver, partContext.typeTable,
|
||||
JvmPackagePartSource(partFile))
|
||||
createCallableStubs(fileStub, partContext, container, packageProto.functionList, packageProto.propertyList)
|
||||
createDeclarationsStubs(fileStub, partContext, container, packageProto)
|
||||
}
|
||||
return fileStub
|
||||
}
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.flags.VISIBILITY
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.KotlinTypeAliasStubImpl
|
||||
import org.jetbrains.kotlin.serialization.Flags
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
|
||||
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
|
||||
|
||||
fun createTypeAliasStub(
|
||||
parent: StubElement<out PsiElement>,
|
||||
typeAliasProto: ProtoBuf.TypeAlias,
|
||||
protoContainer: ProtoContainer,
|
||||
context: ClsStubBuilderContext
|
||||
) {
|
||||
val shortName = context.nameResolver.getName(typeAliasProto.name)
|
||||
|
||||
val classId = when (protoContainer) {
|
||||
is ProtoContainer.Class -> protoContainer.classId.createNestedClassId(shortName)
|
||||
is ProtoContainer.Package -> ClassId.topLevel(protoContainer.fqName.child(shortName))
|
||||
}
|
||||
|
||||
val typeAlias =
|
||||
KotlinTypeAliasStubImpl(
|
||||
parent, classId.shortClassName.ref(), classId.asSingleFqName().ref(),
|
||||
isTopLevel = !classId.isNestedClass)
|
||||
|
||||
createModifierListStubForDeclaration(typeAlias, typeAliasProto.flags, arrayListOf(VISIBILITY), listOf())
|
||||
|
||||
val typeStubBuilder = TypeClsStubBuilder(context)
|
||||
val restConstraints = typeStubBuilder.createTypeParameterListStub(typeAlias, typeAliasProto.typeParameterList)
|
||||
assert(restConstraints.isEmpty()) {
|
||||
"'where' constraints are not allowed for type aliases"
|
||||
}
|
||||
|
||||
if (Flags.HAS_ANNOTATIONS.get(typeAliasProto.flags)) {
|
||||
// TODO: support annotations
|
||||
// createAnnotationStubs(context.components.annotationLoader.loadClassAnnotations(thisAsProtoContainer), modifierList)
|
||||
}
|
||||
|
||||
typeStubBuilder.createTypeReferenceStub(typeAlias, typeAliasProto.underlyingType)
|
||||
}
|
||||
Reference in New Issue
Block a user