Preserve synthetic enum methods in stub-based 'ClsClassImpl'

'ClsClassImpl' instances created by the platform contain synthetic
enum methods (added by 'ClassInnerStuffCache.calcMethods()'). Such
convention is common in IntelliJ (see KT-36095 and
'9a8b345adaded83fe13980a28db5d9f9acc7450d' in the IntelliJ repository).

This commit makes Kotlin's stub-based classes consistent with the
convention. Instead, a filter is added in place of 'ClsClassImpl' usage.

See also the following commits:
- 7c86911f44
- 43468c6d55
This commit is contained in:
Yan Zhulanow
2022-03-04 18:14:41 +09:00
parent fa4dadf9b7
commit c334a44e02
3 changed files with 9 additions and 33 deletions
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
import org.jetbrains.kotlin.asJava.classes.KotlinClassInnerStuffCache
import org.jetbrains.kotlin.asJava.classes.LightClassesLazyCreator
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.isSyntheticValuesOrValueOfMethod
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
import org.jetbrains.kotlin.psi.KtClassOrObject
@@ -155,7 +156,8 @@ open class KtLightClassForDecompiledDeclaration(
private val _methods: MutableList<PsiMethod> by lazyPub {
mutableListOf<PsiMethod>().also {
clsDelegate.methods.mapTo(it) { psiMethod ->
clsDelegate.methods.mapNotNullTo(it) { psiMethod ->
if (isSyntheticValuesOrValueOfMethod(psiMethod)) return@mapNotNullTo null
KtLightMethodForDecompiledDeclaration(
funDelegate = psiMethod,
funParent = this,
@@ -16,8 +16,6 @@ import com.intellij.psi.stubs.StubElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static org.jetbrains.kotlin.asJava.SyntheticElementUtilsKt.isSyntheticValuesOrValueOfMethod;
public class ClsWrapperStubPsiFactory extends StubPsiFactory {
public static final Key<LightElementOrigin> ORIGIN = Key.create("ORIGIN");
public static final ClsWrapperStubPsiFactory INSTANCE = new ClsWrapperStubPsiFactory();
@@ -43,30 +41,6 @@ public class ClsWrapperStubPsiFactory extends StubPsiFactory {
public PsiClass getSourceMirrorClass() {
return null;
}
@NotNull
@Override
public PsiMethod[] getMethods() {
PsiMethod[] baseMethods = super.getMethods();
if (!isEnum()) return baseMethods;
int filteredArraySize = 0;
for (PsiMethod method : baseMethods) {
if (!isSyntheticValuesOrValueOfMethod(method)) filteredArraySize++;
}
if (filteredArraySize == baseMethods.length) return baseMethods;
PsiMethod[] filteredMethods = new PsiMethod[filteredArraySize];
int index = 0;
for (PsiMethod method : baseMethods) {
if (!isSyntheticValuesOrValueOfMethod(method)) {
filteredMethods[index] = method;
index++;
}
}
return filteredMethods;
}
};
}
@@ -12,17 +12,14 @@ import com.intellij.psi.scope.PsiScopeProcessor
import com.intellij.psi.util.MethodSignature
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.*
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.builder.MemberIndex
import org.jetbrains.kotlin.asJava.builder.memberIndex
import org.jetbrains.kotlin.asJava.checkIsMangled
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.cannotModify
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.propertyNameByAccessor
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
@@ -222,8 +219,11 @@ open class KtLightMethodImpl protected constructor(
return KtLightMethodImpl(computeRealDelegate, origin, containingClass, dummyDelegate)
}
fun fromClsMethods(delegateClass: PsiClass, containingClass: KtLightClass) = delegateClass.methods.map {
KtLightMethodImpl.create(it, getOrigin(it), containingClass)
fun fromClsMethods(delegateClass: PsiClass, containingClass: KtLightClass): List<KtLightMethodImpl> = buildList {
for (method in delegateClass.methods) {
if (isSyntheticValuesOrValueOfMethod(method)) continue
this += create(method, getOrigin(method), containingClass)
}
}
fun getOrigin(method: PsiMethod) = adjustMethodOrigin(getMemberOrigin(method))