Refactor CallableClsStubBuilder, separate functions and properties
This commit is contained in:
+121
-117
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
|
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
|
||||||
|
|
||||||
import com.google.protobuf.MessageLite
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.stubs.StubElement
|
import com.intellij.psi.stubs.StubElement
|
||||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.FlagsToModifiers.*
|
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.FlagsToModifiers.*
|
||||||
@@ -42,12 +41,12 @@ fun createCallableStubs(
|
|||||||
) {
|
) {
|
||||||
for (propertyProto in propertyProtos) {
|
for (propertyProto in propertyProtos) {
|
||||||
if (!shouldSkip(propertyProto.flags, outerContext.nameResolver.getName(propertyProto.name))) {
|
if (!shouldSkip(propertyProto.flags, outerContext.nameResolver.getName(propertyProto.name))) {
|
||||||
CallableClsStubBuilder(parentStub, propertyProto, outerContext, protoContainer).build()
|
PropertyClsStubBuilder(parentStub, outerContext, protoContainer, propertyProto).build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (functionProto in functionProtos) {
|
for (functionProto in functionProtos) {
|
||||||
if (!shouldSkip(functionProto.flags, outerContext.nameResolver.getName(functionProto.name))) {
|
if (!shouldSkip(functionProto.flags, outerContext.nameResolver.getName(functionProto.name))) {
|
||||||
CallableClsStubBuilder(parentStub, functionProto, outerContext, protoContainer).build()
|
FunctionClsStubBuilder(parentStub, outerContext, protoContainer, functionProto).build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,7 +57,7 @@ fun createConstructorStub(
|
|||||||
outerContext: ClsStubBuilderContext,
|
outerContext: ClsStubBuilderContext,
|
||||||
protoContainer: ProtoContainer
|
protoContainer: ProtoContainer
|
||||||
) {
|
) {
|
||||||
ConstructorClsStubBuilder(parentStub, constructorProto, outerContext, protoContainer).build()
|
ConstructorClsStubBuilder(parentStub, outerContext, protoContainer, constructorProto).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shouldSkip(flags: Int, name: Name): Boolean {
|
private fun shouldSkip(flags: Int, name: Name): Boolean {
|
||||||
@@ -70,155 +69,160 @@ private fun shouldSkip(flags: Int, name: Name): Boolean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CallableClsStubBuilder private constructor(
|
abstract class CallableClsStubBuilder(
|
||||||
private val parent: StubElement<out PsiElement>,
|
parent: StubElement<out PsiElement>,
|
||||||
private val callableProto: MessageLite,
|
|
||||||
outerContext: ClsStubBuilderContext,
|
outerContext: ClsStubBuilderContext,
|
||||||
private val protoContainer: ProtoContainer,
|
protected val protoContainer: ProtoContainer,
|
||||||
private val callableKind: CallableClsStubBuilder.CallableKind,
|
private val typeParameters: List<ProtoBuf.TypeParameter>
|
||||||
private val nameIndex: Int,
|
|
||||||
private val typeParameterList: List<ProtoBuf.TypeParameter>,
|
|
||||||
private val valueParameterList: List<ProtoBuf.ValueParameter>,
|
|
||||||
private val receiverType: ProtoBuf.Type?,
|
|
||||||
private val returnType: ProtoBuf.Type?,
|
|
||||||
private val flags: Int
|
|
||||||
) {
|
) {
|
||||||
private val c = outerContext.child(typeParameterList)
|
protected val c = outerContext.child(typeParameters)
|
||||||
private val typeStubBuilder = TypeClsStubBuilder(c)
|
protected val typeStubBuilder = TypeClsStubBuilder(c)
|
||||||
private val isTopLevel: Boolean get() = protoContainer.packageFqName != null
|
protected val isTopLevel: Boolean get() = protoContainer.packageFqName != null
|
||||||
private val callableStub = doCreateCallableStub()
|
protected val callableStub: StubElement<out PsiElement> by lazy(LazyThreadSafetyMode.NONE) { doCreateCallableStub(parent) }
|
||||||
|
|
||||||
enum class CallableKind {
|
|
||||||
FUN, VAL, VAR
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
parent: StubElement<out PsiElement>,
|
|
||||||
functionProto: ProtoBuf.Function,
|
|
||||||
outerContext: ClsStubBuilderContext,
|
|
||||||
protoContainer: ProtoContainer
|
|
||||||
) : this(
|
|
||||||
parent, functionProto, outerContext, protoContainer, CallableKind.FUN,
|
|
||||||
functionProto.name, functionProto.typeParameterList, functionProto.valueParameterList,
|
|
||||||
if (functionProto.hasReceiverType()) functionProto.receiverType else null,
|
|
||||||
if (functionProto.hasReturnType()) functionProto.returnType else null,
|
|
||||||
functionProto.flags
|
|
||||||
)
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
parent: StubElement<out PsiElement>,
|
|
||||||
propertyProto: ProtoBuf.Property,
|
|
||||||
outerContext: ClsStubBuilderContext,
|
|
||||||
protoContainer: ProtoContainer
|
|
||||||
) : this(
|
|
||||||
parent, propertyProto, outerContext, protoContainer,
|
|
||||||
if (Flags.IS_VAR.get(propertyProto.flags)) CallableKind.VAR else CallableKind.VAL,
|
|
||||||
propertyProto.name, propertyProto.typeParameterList, emptyList(),
|
|
||||||
if (propertyProto.hasReceiverType()) propertyProto.receiverType else null,
|
|
||||||
if (propertyProto.hasReturnType()) propertyProto.returnType else null,
|
|
||||||
propertyProto.flags
|
|
||||||
)
|
|
||||||
|
|
||||||
fun build() {
|
fun build() {
|
||||||
createModifierListStub()
|
createModifierListStub()
|
||||||
val typeConstraintListData = typeStubBuilder.createTypeParameterListStub(callableStub, typeParameterList)
|
val typeConstraintListData = typeStubBuilder.createTypeParameterListStub(callableStub, typeParameters)
|
||||||
createReceiverTypeReferenceStub()
|
createReceiverTypeReferenceStub()
|
||||||
createValueParameterList()
|
createValueParameterList()
|
||||||
createReturnTypeStub()
|
createReturnTypeStub()
|
||||||
typeStubBuilder.createTypeConstraintListStub(callableStub, typeConstraintListData)
|
typeStubBuilder.createTypeConstraintListStub(callableStub, typeConstraintListData)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createValueParameterList() {
|
abstract val receiverType: ProtoBuf.Type?
|
||||||
if (callableKind == CallableKind.FUN) {
|
abstract val returnType: ProtoBuf.Type?
|
||||||
typeStubBuilder.createValueParameterListStub(callableStub, callableProto, valueParameterList, protoContainer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createReceiverTypeReferenceStub() {
|
private fun createReceiverTypeReferenceStub() {
|
||||||
if (receiverType != null) {
|
receiverType?.let {
|
||||||
typeStubBuilder.createTypeReferenceStub(callableStub, receiverType)
|
typeStubBuilder.createTypeReferenceStub(callableStub, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createReturnTypeStub() {
|
private fun createReturnTypeStub() {
|
||||||
if (returnType != null) {
|
returnType?.let {
|
||||||
typeStubBuilder.createTypeReferenceStub(callableStub, returnType)
|
typeStubBuilder.createTypeReferenceStub(callableStub, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createModifierListStub() {
|
abstract fun createModifierListStub()
|
||||||
val modalityModifiers = if (isTopLevel) listOf() else listOf(MODALITY)
|
|
||||||
val constModifiers = if (callableKind == CallableKind.VAL) listOf(CONST) else listOf()
|
|
||||||
|
|
||||||
val additionalModifiers = when (callableKind) {
|
abstract fun createValueParameterList()
|
||||||
CallableKind.FUN -> arrayOf(OPERATOR, INFIX)
|
|
||||||
CallableKind.VAL, CallableKind.VAR -> arrayOf(LATEINIT)
|
|
||||||
else -> emptyArray<FlagsToModifiers>()
|
|
||||||
}
|
|
||||||
|
|
||||||
val relevantModifiers = listOf(VISIBILITY) + constModifiers + modalityModifiers + additionalModifiers
|
abstract fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement>
|
||||||
val modifierListStubImpl = createModifierListStubForDeclaration(callableStub, flags, relevantModifiers)
|
}
|
||||||
|
|
||||||
val kind = callableProto.annotatedCallableKind
|
private class FunctionClsStubBuilder(
|
||||||
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(protoContainer, callableProto, kind)
|
parent: StubElement<out PsiElement>,
|
||||||
|
outerContext: ClsStubBuilderContext,
|
||||||
|
protoContainer: ProtoContainer,
|
||||||
|
private val functionProto: ProtoBuf.Function
|
||||||
|
) : CallableClsStubBuilder(parent, outerContext, protoContainer, functionProto.typeParameterList) {
|
||||||
|
override val receiverType: ProtoBuf.Type?
|
||||||
|
get() = if (functionProto.hasReceiverType()) functionProto.receiverType else null
|
||||||
|
|
||||||
|
override val returnType: ProtoBuf.Type?
|
||||||
|
get() = if (functionProto.hasReturnType()) functionProto.returnType else null
|
||||||
|
|
||||||
|
override fun createValueParameterList() {
|
||||||
|
typeStubBuilder.createValueParameterListStub(callableStub, functionProto, functionProto.valueParameterList, protoContainer)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createModifierListStub() {
|
||||||
|
val modalityModifier = if (isTopLevel) listOf() else listOf(MODALITY)
|
||||||
|
val modifierListStubImpl = createModifierListStubForDeclaration(
|
||||||
|
callableStub, functionProto.flags,
|
||||||
|
listOf(VISIBILITY, OPERATOR, INFIX) + modalityModifier
|
||||||
|
)
|
||||||
|
|
||||||
|
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
|
||||||
|
protoContainer, functionProto, AnnotatedCallableKind.FUNCTION
|
||||||
|
)
|
||||||
createTargetedAnnotationStubs(annotationIds, modifierListStubImpl)
|
createTargetedAnnotationStubs(annotationIds, modifierListStubImpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doCreateCallableStub(): StubElement<out PsiElement> {
|
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
|
||||||
val callableName = c.nameResolver.getName(nameIndex)
|
val callableName = c.nameResolver.getName(functionProto.name)
|
||||||
|
|
||||||
return when (callableKind) {
|
return KotlinFunctionStubImpl(
|
||||||
CallableKind.FUN -> {
|
parent,
|
||||||
KotlinFunctionStubImpl(
|
callableName.ref(),
|
||||||
parent,
|
isTopLevel,
|
||||||
callableName.ref(),
|
c.containerFqName.child(callableName),
|
||||||
isTopLevel,
|
isExtension = functionProto.hasReceiverType(),
|
||||||
c.containerFqName.child(callableName),
|
hasBlockBody = true,
|
||||||
isExtension = receiverType != null,
|
hasBody = Flags.MODALITY.get(functionProto.flags) != Modality.ABSTRACT,
|
||||||
hasBlockBody = true,
|
hasTypeParameterListBeforeFunctionName = functionProto.typeParameterList.isNotEmpty()
|
||||||
hasBody = Flags.MODALITY.get(flags) != Modality.ABSTRACT,
|
)
|
||||||
hasTypeParameterListBeforeFunctionName = typeParameterList.isNotEmpty()
|
}
|
||||||
)
|
}
|
||||||
}
|
|
||||||
CallableKind.VAL, CallableKind.VAR -> {
|
private class PropertyClsStubBuilder(
|
||||||
KotlinPropertyStubImpl(
|
parent: StubElement<out PsiElement>,
|
||||||
parent,
|
outerContext: ClsStubBuilderContext,
|
||||||
callableName.ref(),
|
protoContainer: ProtoContainer,
|
||||||
isVar = callableKind == CallableKind.VAR,
|
private val propertyProto: ProtoBuf.Property
|
||||||
isTopLevel = isTopLevel,
|
) : CallableClsStubBuilder(parent, outerContext, protoContainer, propertyProto.typeParameterList) {
|
||||||
hasDelegate = false,
|
private val isVar = Flags.IS_VAR.get(propertyProto.flags)
|
||||||
hasDelegateExpression = false,
|
|
||||||
hasInitializer = false,
|
override val receiverType: ProtoBuf.Type?
|
||||||
isExtension = receiverType != null,
|
get() = if (propertyProto.hasReceiverType()) propertyProto.receiverType else null
|
||||||
hasReturnTypeRef = true,
|
|
||||||
fqName = c.containerFqName.child(callableName)
|
override val returnType: ProtoBuf.Type?
|
||||||
)
|
get() = if (propertyProto.hasReturnType()) propertyProto.returnType else null
|
||||||
}
|
|
||||||
else -> throw IllegalStateException("Unknown callable kind $callableKind")
|
override fun createValueParameterList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun createModifierListStub() {
|
||||||
|
val constModifier = if (isVar) listOf() else listOf(CONST)
|
||||||
|
val modalityModifier = if (isTopLevel) listOf() else listOf(MODALITY)
|
||||||
|
|
||||||
|
val modifierListStubImpl = createModifierListStubForDeclaration(
|
||||||
|
callableStub, propertyProto.flags,
|
||||||
|
listOf(VISIBILITY, LATEINIT) + constModifier + modalityModifier
|
||||||
|
)
|
||||||
|
|
||||||
|
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
|
||||||
|
protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY
|
||||||
|
)
|
||||||
|
createTargetedAnnotationStubs(annotationIds, modifierListStubImpl)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
|
||||||
|
val callableName = c.nameResolver.getName(propertyProto.name)
|
||||||
|
|
||||||
|
return KotlinPropertyStubImpl(
|
||||||
|
parent,
|
||||||
|
callableName.ref(),
|
||||||
|
isVar,
|
||||||
|
isTopLevel,
|
||||||
|
hasDelegate = false,
|
||||||
|
hasDelegateExpression = false,
|
||||||
|
hasInitializer = false,
|
||||||
|
isExtension = propertyProto.hasReceiverType(),
|
||||||
|
hasReturnTypeRef = true,
|
||||||
|
fqName = c.containerFqName.child(callableName)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ConstructorClsStubBuilder(
|
private class ConstructorClsStubBuilder(
|
||||||
private val parent: StubElement<out PsiElement>,
|
parent: StubElement<out PsiElement>,
|
||||||
private val constructorProto: ProtoBuf.Constructor,
|
|
||||||
outerContext: ClsStubBuilderContext,
|
outerContext: ClsStubBuilderContext,
|
||||||
private val protoContainer: ProtoContainer
|
protoContainer: ProtoContainer,
|
||||||
) {
|
private val constructorProto: ProtoBuf.Constructor
|
||||||
private val c = outerContext.child(emptyList())
|
) : CallableClsStubBuilder(parent, outerContext, protoContainer, emptyList()) {
|
||||||
private val typeStubBuilder = TypeClsStubBuilder(c)
|
override val receiverType: ProtoBuf.Type?
|
||||||
private val callableStub = doCreateCallableStub()
|
get() = null
|
||||||
|
|
||||||
fun build() {
|
override val returnType: ProtoBuf.Type?
|
||||||
createModifierListStub()
|
get() = null
|
||||||
createValueParameterList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createValueParameterList() {
|
override fun createValueParameterList() {
|
||||||
typeStubBuilder.createValueParameterListStub(callableStub, constructorProto, constructorProto.valueParameterList, protoContainer)
|
typeStubBuilder.createValueParameterListStub(callableStub, constructorProto, constructorProto.valueParameterList, protoContainer)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createModifierListStub() {
|
override fun createModifierListStub() {
|
||||||
val modifierListStubImpl = createModifierListStubForDeclaration(callableStub, constructorProto.flags, listOf(VISIBILITY))
|
val modifierListStubImpl = createModifierListStubForDeclaration(callableStub, constructorProto.flags, listOf(VISIBILITY))
|
||||||
|
|
||||||
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
|
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
|
||||||
@@ -227,7 +231,7 @@ private class ConstructorClsStubBuilder(
|
|||||||
createTargetedAnnotationStubs(annotationIds, modifierListStubImpl)
|
createTargetedAnnotationStubs(annotationIds, modifierListStubImpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doCreateCallableStub(): StubElement<out PsiElement> {
|
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
|
||||||
return if (Flags.IS_SECONDARY.get(constructorProto.flags))
|
return if (Flags.IS_SECONDARY.get(constructorProto.flags))
|
||||||
KotlinPlaceHolderStubImpl(parent, JetStubElementTypes.SECONDARY_CONSTRUCTOR)
|
KotlinPlaceHolderStubImpl(parent, JetStubElementTypes.SECONDARY_CONSTRUCTOR)
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user