Skip to content

Commit c784108

Browse files
committed
Refactor CallableClsStubBuilder, separate functions and properties
1 parent 9d626ef commit c784108

File tree

1 file changed

+122
-118
lines changed

1 file changed

+122
-118
lines changed

idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/CallableClsStubBuilder.kt

Lines changed: 122 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
1818

19-
import com.google.protobuf.MessageLite
2019
import com.intellij.psi.PsiElement
2120
import com.intellij.psi.stubs.StubElement
2221
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.FlagsToModifiers.*
@@ -42,12 +41,12 @@ fun createCallableStubs(
4241
) {
4342
for (propertyProto in propertyProtos) {
4443
if (!shouldSkip(propertyProto.flags, outerContext.nameResolver.getName(propertyProto.name))) {
45-
CallableClsStubBuilder(parentStub, propertyProto, outerContext, protoContainer).build()
44+
PropertyClsStubBuilder(parentStub, outerContext, protoContainer, propertyProto).build()
4645
}
4746
}
4847
for (functionProto in functionProtos) {
4948
if (!shouldSkip(functionProto.flags, outerContext.nameResolver.getName(functionProto.name))) {
50-
CallableClsStubBuilder(parentStub, functionProto, outerContext, protoContainer).build()
49+
FunctionClsStubBuilder(parentStub, outerContext, protoContainer, functionProto).build()
5150
}
5251
}
5352
}
@@ -58,7 +57,7 @@ fun createConstructorStub(
5857
outerContext: ClsStubBuilderContext,
5958
protoContainer: ProtoContainer
6059
) {
61-
ConstructorClsStubBuilder(parentStub, constructorProto, outerContext, protoContainer).build()
60+
ConstructorClsStubBuilder(parentStub, outerContext, protoContainer, constructorProto).build()
6261
}
6362

6463
private fun shouldSkip(flags: Int, name: Name): Boolean {
@@ -70,155 +69,160 @@ private fun shouldSkip(flags: Int, name: Name): Boolean {
7069
}
7170
}
7271

73-
private class CallableClsStubBuilder private constructor(
74-
private val parent: StubElement<out PsiElement>,
75-
private val callableProto: MessageLite,
72+
abstract class CallableClsStubBuilder(
73+
parent: StubElement<out PsiElement>,
7674
outerContext: ClsStubBuilderContext,
77-
private val protoContainer: ProtoContainer,
78-
private val callableKind: CallableClsStubBuilder.CallableKind,
79-
private val nameIndex: Int,
80-
private val typeParameterList: List<ProtoBuf.TypeParameter>,
81-
private val valueParameterList: List<ProtoBuf.ValueParameter>,
82-
private val receiverType: ProtoBuf.Type?,
83-
private val returnType: ProtoBuf.Type?,
84-
private val flags: Int
75+
protected val protoContainer: ProtoContainer,
76+
private val typeParameters: List<ProtoBuf.TypeParameter>
8577
) {
86-
private val c = outerContext.child(typeParameterList)
87-
private val typeStubBuilder = TypeClsStubBuilder(c)
88-
private val isTopLevel: Boolean get() = protoContainer.packageFqName != null
89-
private val callableStub = doCreateCallableStub()
90-
91-
enum class CallableKind {
92-
FUN, VAL, VAR
93-
}
94-
95-
constructor(
96-
parent: StubElement<out PsiElement>,
97-
functionProto: ProtoBuf.Function,
98-
outerContext: ClsStubBuilderContext,
99-
protoContainer: ProtoContainer
100-
) : this(
101-
parent, functionProto, outerContext, protoContainer, CallableKind.FUN,
102-
functionProto.name, functionProto.typeParameterList, functionProto.valueParameterList,
103-
if (functionProto.hasReceiverType()) functionProto.receiverType else null,
104-
if (functionProto.hasReturnType()) functionProto.returnType else null,
105-
functionProto.flags
106-
)
107-
108-
constructor(
109-
parent: StubElement<out PsiElement>,
110-
propertyProto: ProtoBuf.Property,
111-
outerContext: ClsStubBuilderContext,
112-
protoContainer: ProtoContainer
113-
) : this(
114-
parent, propertyProto, outerContext, protoContainer,
115-
if (Flags.IS_VAR.get(propertyProto.flags)) CallableKind.VAR else CallableKind.VAL,
116-
propertyProto.name, propertyProto.typeParameterList, emptyList(),
117-
if (propertyProto.hasReceiverType()) propertyProto.receiverType else null,
118-
if (propertyProto.hasReturnType()) propertyProto.returnType else null,
119-
propertyProto.flags
120-
)
78+
protected val c = outerContext.child(typeParameters)
79+
protected val typeStubBuilder = TypeClsStubBuilder(c)
80+
protected val isTopLevel: Boolean get() = protoContainer.packageFqName != null
81+
protected val callableStub: StubElement<out PsiElement> by lazy(LazyThreadSafetyMode.NONE) { doCreateCallableStub(parent) }
12182

12283
fun build() {
12384
createModifierListStub()
124-
val typeConstraintListData = typeStubBuilder.createTypeParameterListStub(callableStub, typeParameterList)
85+
val typeConstraintListData = typeStubBuilder.createTypeParameterListStub(callableStub, typeParameters)
12586
createReceiverTypeReferenceStub()
12687
createValueParameterList()
12788
createReturnTypeStub()
12889
typeStubBuilder.createTypeConstraintListStub(callableStub, typeConstraintListData)
12990
}
13091

131-
private fun createValueParameterList() {
132-
if (callableKind == CallableKind.FUN) {
133-
typeStubBuilder.createValueParameterListStub(callableStub, callableProto, valueParameterList, protoContainer)
134-
}
135-
}
92+
abstract val receiverType: ProtoBuf.Type?
93+
abstract val returnType: ProtoBuf.Type?
13694

13795
private fun createReceiverTypeReferenceStub() {
138-
if (receiverType != null) {
139-
typeStubBuilder.createTypeReferenceStub(callableStub, receiverType)
96+
receiverType?.let {
97+
typeStubBuilder.createTypeReferenceStub(callableStub, it)
14098
}
14199
}
142100

143101
private fun createReturnTypeStub() {
144-
if (returnType != null) {
145-
typeStubBuilder.createTypeReferenceStub(callableStub, returnType)
102+
returnType?.let {
103+
typeStubBuilder.createTypeReferenceStub(callableStub, it)
146104
}
147105
}
148106

149-
private fun createModifierListStub() {
150-
val modalityModifiers = if (isTopLevel) listOf() else listOf(MODALITY)
151-
val constModifiers = if (callableKind == CallableKind.VAL) listOf(CONST) else listOf()
107+
abstract fun createModifierListStub()
152108

153-
val additionalModifiers = when (callableKind) {
154-
CallableKind.FUN -> arrayOf(OPERATOR, INFIX)
155-
CallableKind.VAL, CallableKind.VAR -> arrayOf(LATEINIT)
156-
else -> emptyArray<FlagsToModifiers>()
157-
}
109+
abstract fun createValueParameterList()
110+
111+
abstract fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement>
112+
}
113+
114+
private class FunctionClsStubBuilder(
115+
parent: StubElement<out PsiElement>,
116+
outerContext: ClsStubBuilderContext,
117+
protoContainer: ProtoContainer,
118+
private val functionProto: ProtoBuf.Function
119+
) : CallableClsStubBuilder(parent, outerContext, protoContainer, functionProto.typeParameterList) {
120+
override val receiverType: ProtoBuf.Type?
121+
get() = if (functionProto.hasReceiverType()) functionProto.receiverType else null
158122

159-
val relevantModifiers = listOf(VISIBILITY) + constModifiers + modalityModifiers + additionalModifiers
160-
val modifierListStubImpl = createModifierListStubForDeclaration(callableStub, flags, relevantModifiers)
123+
override val returnType: ProtoBuf.Type?
124+
get() = if (functionProto.hasReturnType()) functionProto.returnType else null
161125

162-
val kind = callableProto.annotatedCallableKind
163-
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(protoContainer, callableProto, kind)
126+
override fun createValueParameterList() {
127+
typeStubBuilder.createValueParameterListStub(callableStub, functionProto, functionProto.valueParameterList, protoContainer)
128+
}
129+
130+
override fun createModifierListStub() {
131+
val modalityModifier = if (isTopLevel) listOf() else listOf(MODALITY)
132+
val modifierListStubImpl = createModifierListStubForDeclaration(
133+
callableStub, functionProto.flags,
134+
listOf(VISIBILITY, OPERATOR, INFIX) + modalityModifier
135+
)
136+
137+
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
138+
protoContainer, functionProto, AnnotatedCallableKind.FUNCTION
139+
)
164140
createTargetedAnnotationStubs(annotationIds, modifierListStubImpl)
165141
}
166142

167-
private fun doCreateCallableStub(): StubElement<out PsiElement> {
168-
val callableName = c.nameResolver.getName(nameIndex)
169-
170-
return when (callableKind) {
171-
CallableKind.FUN -> {
172-
KotlinFunctionStubImpl(
173-
parent,
174-
callableName.ref(),
175-
isTopLevel,
176-
c.containerFqName.child(callableName),
177-
isExtension = receiverType != null,
178-
hasBlockBody = true,
179-
hasBody = Flags.MODALITY.get(flags) != Modality.ABSTRACT,
180-
hasTypeParameterListBeforeFunctionName = typeParameterList.isNotEmpty()
181-
)
182-
}
183-
CallableKind.VAL, CallableKind.VAR -> {
184-
KotlinPropertyStubImpl(
185-
parent,
186-
callableName.ref(),
187-
isVar = callableKind == CallableKind.VAR,
188-
isTopLevel = isTopLevel,
189-
hasDelegate = false,
190-
hasDelegateExpression = false,
191-
hasInitializer = false,
192-
isExtension = receiverType != null,
193-
hasReturnTypeRef = true,
194-
fqName = c.containerFqName.child(callableName)
195-
)
196-
}
197-
else -> throw IllegalStateException("Unknown callable kind $callableKind")
198-
}
143+
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
144+
val callableName = c.nameResolver.getName(functionProto.name)
145+
146+
return KotlinFunctionStubImpl(
147+
parent,
148+
callableName.ref(),
149+
isTopLevel,
150+
c.containerFqName.child(callableName),
151+
isExtension = functionProto.hasReceiverType(),
152+
hasBlockBody = true,
153+
hasBody = Flags.MODALITY.get(functionProto.flags) != Modality.ABSTRACT,
154+
hasTypeParameterListBeforeFunctionName = functionProto.typeParameterList.isNotEmpty()
155+
)
199156
}
200157
}
201158

202-
private class ConstructorClsStubBuilder(
203-
private val parent: StubElement<out PsiElement>,
204-
private val constructorProto: ProtoBuf.Constructor,
159+
private class PropertyClsStubBuilder(
160+
parent: StubElement<out PsiElement>,
205161
outerContext: ClsStubBuilderContext,
206-
private val protoContainer: ProtoContainer
207-
) {
208-
private val c = outerContext.child(emptyList())
209-
private val typeStubBuilder = TypeClsStubBuilder(c)
210-
private val callableStub = doCreateCallableStub()
162+
protoContainer: ProtoContainer,
163+
private val propertyProto: ProtoBuf.Property
164+
) : CallableClsStubBuilder(parent, outerContext, protoContainer, propertyProto.typeParameterList) {
165+
private val isVar = Flags.IS_VAR.get(propertyProto.flags)
211166

212-
fun build() {
213-
createModifierListStub()
214-
createValueParameterList()
167+
override val receiverType: ProtoBuf.Type?
168+
get() = if (propertyProto.hasReceiverType()) propertyProto.receiverType else null
169+
170+
override val returnType: ProtoBuf.Type?
171+
get() = if (propertyProto.hasReturnType()) propertyProto.returnType else null
172+
173+
override fun createValueParameterList() {
174+
}
175+
176+
override fun createModifierListStub() {
177+
val constModifier = if (isVar) listOf() else listOf(CONST)
178+
val modalityModifier = if (isTopLevel) listOf() else listOf(MODALITY)
179+
180+
val modifierListStubImpl = createModifierListStubForDeclaration(
181+
callableStub, propertyProto.flags,
182+
listOf(VISIBILITY, LATEINIT) + constModifier + modalityModifier
183+
)
184+
185+
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
186+
protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY
187+
)
188+
createTargetedAnnotationStubs(annotationIds, modifierListStubImpl)
189+
}
190+
191+
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
192+
val callableName = c.nameResolver.getName(propertyProto.name)
193+
194+
return KotlinPropertyStubImpl(
195+
parent,
196+
callableName.ref(),
197+
isVar,
198+
isTopLevel,
199+
hasDelegate = false,
200+
hasDelegateExpression = false,
201+
hasInitializer = false,
202+
isExtension = propertyProto.hasReceiverType(),
203+
hasReturnTypeRef = true,
204+
fqName = c.containerFqName.child(callableName)
205+
)
215206
}
207+
}
208+
209+
private class ConstructorClsStubBuilder(
210+
parent: StubElement<out PsiElement>,
211+
outerContext: ClsStubBuilderContext,
212+
protoContainer: ProtoContainer,
213+
private val constructorProto: ProtoBuf.Constructor
214+
) : CallableClsStubBuilder(parent, outerContext, protoContainer, emptyList()) {
215+
override val receiverType: ProtoBuf.Type?
216+
get() = null
217+
218+
override val returnType: ProtoBuf.Type?
219+
get() = null
216220

217-
private fun createValueParameterList() {
221+
override fun createValueParameterList() {
218222
typeStubBuilder.createValueParameterListStub(callableStub, constructorProto, constructorProto.valueParameterList, protoContainer)
219223
}
220224

221-
private fun createModifierListStub() {
225+
override fun createModifierListStub() {
222226
val modifierListStubImpl = createModifierListStubForDeclaration(callableStub, constructorProto.flags, listOf(VISIBILITY))
223227

224228
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
@@ -227,7 +231,7 @@ private class ConstructorClsStubBuilder(
227231
createTargetedAnnotationStubs(annotationIds, modifierListStubImpl)
228232
}
229233

230-
private fun doCreateCallableStub(): StubElement<out PsiElement> {
234+
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
231235
return if (Flags.IS_SECONDARY.get(constructorProto.flags))
232236
KotlinPlaceHolderStubImpl(parent, JetStubElementTypes.SECONDARY_CONSTRUCTOR)
233237
else

0 commit comments

Comments
 (0)