[LC] reduce memory consumption from SLC and DLC
The main change is drop `LightClassesLazyCreator` KtLightClassForDecompiledDeclaration: * fixed a few captured fields ^KT-56561 Fixed
This commit is contained in:
committed by
Space Team
parent
a8e8fc1f11
commit
761553ea75
+66
-71
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -18,8 +18,7 @@ import org.jetbrains.kotlin.analysis.decompiled.light.classes.origin.LightMember
|
|||||||
import org.jetbrains.kotlin.analysis.decompiled.light.classes.origin.LightMemberOriginForCompiledMethod
|
import org.jetbrains.kotlin.analysis.decompiled.light.classes.origin.LightMemberOriginForCompiledMethod
|
||||||
import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile
|
import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile
|
||||||
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
||||||
import org.jetbrains.kotlin.asJava.classes.KotlinClassInnerStuffCache
|
import org.jetbrains.kotlin.asJava.classes.ClassInnerStuffCache
|
||||||
import org.jetbrains.kotlin.asJava.classes.LightClassesLazyCreator
|
|
||||||
import org.jetbrains.kotlin.asJava.classes.getEnumEntriesPsiMethod
|
import org.jetbrains.kotlin.asJava.classes.getEnumEntriesPsiMethod
|
||||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.asJava.isGetEntriesMethod
|
import org.jetbrains.kotlin.asJava.isGetEntriesMethod
|
||||||
@@ -29,36 +28,37 @@ import org.jetbrains.kotlin.psi.KtClassOrObject
|
|||||||
|
|
||||||
open class KtLightClassForDecompiledDeclaration(
|
open class KtLightClassForDecompiledDeclaration(
|
||||||
clsDelegate: PsiClass,
|
clsDelegate: PsiClass,
|
||||||
private val clsParent: PsiElement,
|
clsParent: PsiElement,
|
||||||
private val file: KtClsFile,
|
protected val file: KtClsFile,
|
||||||
kotlinOrigin: KtClassOrObject?
|
kotlinOrigin: KtClassOrObject?
|
||||||
) : KtLightClassForDecompiledDeclarationBase(clsDelegate, clsParent, kotlinOrigin) {
|
) : KtLightClassForDecompiledDeclarationBase(clsDelegate, clsParent, kotlinOrigin) {
|
||||||
|
private val myInnersCache by lazyPub {
|
||||||
|
ClassInnerStuffCache(
|
||||||
|
/* aClass = */ this,
|
||||||
|
/* generateEnumMethods = */ true,
|
||||||
|
/* modificationTracker = */ KotlinModificationTrackerService.getInstance(manager.project).outOfBlockModificationTracker,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private val myInnersCache = KotlinClassInnerStuffCache(
|
override fun getOwnMethods(): List<PsiMethod> = _methods
|
||||||
myClass = this,
|
|
||||||
dependencies = listOf(KotlinModificationTrackerService.getInstance(manager.project).outOfBlockModificationTracker),
|
|
||||||
lazyCreator = LightClassesLazyCreator(project)
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun getOwnMethods(): MutableList<PsiMethod> = _methods
|
override fun getOwnFields(): List<PsiField> = _fields
|
||||||
|
|
||||||
override fun getOwnFields(): MutableList<PsiField> = _fields
|
override fun getOwnInnerClasses(): List<PsiClass> = _innerClasses
|
||||||
|
|
||||||
override fun getOwnInnerClasses(): MutableList<PsiClass> = _innerClasses
|
override fun getFields(): Array<PsiField> = myInnersCache.fields
|
||||||
|
|
||||||
override fun getFields() = myInnersCache.fields
|
override fun getMethods(): Array<PsiMethod> = myInnersCache.methods
|
||||||
|
|
||||||
override fun getMethods() = myInnersCache.methods
|
override fun getConstructors(): Array<PsiMethod> = myInnersCache.constructors
|
||||||
|
|
||||||
override fun getConstructors() = myInnersCache.constructors
|
override fun getInnerClasses(): Array<PsiClass> = myInnersCache.innerClasses
|
||||||
|
|
||||||
override fun getInnerClasses() = myInnersCache.innerClasses
|
override fun findFieldByName(name: String, checkBases: Boolean): PsiField? = myInnersCache.findFieldByName(name, checkBases)
|
||||||
|
|
||||||
override fun findFieldByName(name: String, checkBases: Boolean) = myInnersCache.findFieldByName(name, checkBases)
|
override fun findMethodsByName(name: String, checkBases: Boolean): Array<PsiMethod> = myInnersCache.findMethodsByName(name, checkBases)
|
||||||
|
|
||||||
override fun findMethodsByName(name: String, checkBases: Boolean) = myInnersCache.findMethodsByName(name, checkBases)
|
override fun findInnerClassByName(name: String, checkBases: Boolean): PsiClass? = myInnersCache.findInnerClassByName(name, checkBases)
|
||||||
|
|
||||||
override fun findInnerClassByName(name: String, checkBases: Boolean) = myInnersCache.findInnerClassByName(name, checkBases)
|
|
||||||
|
|
||||||
override fun hasModifierProperty(name: String): Boolean =
|
override fun hasModifierProperty(name: String): Boolean =
|
||||||
clsDelegate.hasModifierProperty(name)
|
clsDelegate.hasModifierProperty(name)
|
||||||
@@ -82,15 +82,15 @@ open class KtLightClassForDecompiledDeclaration(
|
|||||||
|
|
||||||
override fun getContainingClass(): PsiClass? = parent as? PsiClass
|
override fun getContainingClass(): PsiClass? = parent as? PsiClass
|
||||||
|
|
||||||
override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = clsDelegate.isInheritorDeep(baseClass, classToByPass)
|
override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean =
|
||||||
|
clsDelegate.isInheritorDeep(baseClass, classToByPass)
|
||||||
|
|
||||||
override fun getAllMethodsAndTheirSubstitutors(): List<Pair<PsiMethod?, PsiSubstitutor?>?> =
|
override fun getAllMethodsAndTheirSubstitutors(): List<Pair<PsiMethod?, PsiSubstitutor?>?> =
|
||||||
PsiClassImplUtil.getAllWithSubstitutorsByMap<PsiMethod>(this, PsiClassImplUtil.MemberType.METHOD)
|
PsiClassImplUtil.getAllWithSubstitutorsByMap<PsiMethod>(this, PsiClassImplUtil.MemberType.METHOD)
|
||||||
|
|
||||||
override fun isInterface(): Boolean = clsDelegate.isInterface
|
override fun isInterface(): Boolean = clsDelegate.isInterface
|
||||||
|
|
||||||
override fun getTypeParameters(): Array<PsiTypeParameter> =
|
override fun getTypeParameters(): Array<PsiTypeParameter> = clsDelegate.typeParameters
|
||||||
clsDelegate.typeParameters
|
|
||||||
|
|
||||||
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean =
|
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean =
|
||||||
clsDelegate.isInheritor(baseClass, checkDeep)
|
clsDelegate.isInheritor(baseClass, checkDeep)
|
||||||
@@ -159,59 +159,54 @@ open class KtLightClassForDecompiledDeclaration(
|
|||||||
|
|
||||||
override fun getAllFields(): Array<PsiField> = PsiClassImplUtil.getAllFields(this)
|
override fun getAllFields(): Array<PsiField> = PsiClassImplUtil.getAllFields(this)
|
||||||
|
|
||||||
private val _methods: MutableList<PsiMethod> by lazyPub {
|
private val _methods: List<PsiMethod> by lazyPub {
|
||||||
mutableListOf<PsiMethod>().also {
|
val isEnum = isEnum
|
||||||
val isEnum = isEnum
|
this.clsDelegate.methods.mapNotNull { psiMethod ->
|
||||||
clsDelegate.methods.mapNotNullTo(it) { psiMethod ->
|
if (isSyntheticValuesOrValueOfMethod(psiMethod)) return@mapNotNull null
|
||||||
if (isSyntheticValuesOrValueOfMethod(psiMethod)) return@mapNotNullTo null
|
if (isEnum && isGetEntriesMethod(psiMethod)) {
|
||||||
if (isEnum && isGetEntriesMethod(psiMethod)) {
|
return@mapNotNull getEnumEntriesPsiMethod(this)
|
||||||
return@mapNotNullTo getEnumEntriesPsiMethod(this)
|
}
|
||||||
}
|
|
||||||
KtLightMethodForDecompiledDeclaration(
|
KtLightMethodForDecompiledDeclaration(
|
||||||
funDelegate = psiMethod,
|
funDelegate = psiMethod,
|
||||||
funParent = this,
|
funParent = this,
|
||||||
lightMemberOrigin = LightMemberOriginForCompiledMethod(psiMethod, file)
|
lightMemberOrigin = LightMemberOriginForCompiledMethod(psiMethod, file)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val _fields: List<PsiField> by lazyPub {
|
||||||
|
this.clsDelegate.fields.map { psiField ->
|
||||||
|
if (psiField !is PsiEnumConstant) {
|
||||||
|
KtLightFieldForDecompiledDeclaration(
|
||||||
|
fldDelegate = psiField,
|
||||||
|
fldParent = this,
|
||||||
|
lightMemberOrigin = LightMemberOriginForCompiledField(psiField, file)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
KtLightEnumEntryForDecompiledDeclaration(
|
||||||
|
fldDelegate = psiField,
|
||||||
|
fldParent = this,
|
||||||
|
lightMemberOrigin = LightMemberOriginForCompiledField(psiField, file),
|
||||||
|
file = file
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val _fields: MutableList<PsiField> by lazyPub {
|
private val _innerClasses: List<PsiClass> by lazyPub {
|
||||||
mutableListOf<PsiField>().also {
|
this.clsDelegate.innerClasses.map { psiClass ->
|
||||||
clsDelegate.fields.mapTo(it) { psiField ->
|
val innerDeclaration = this.kotlinOrigin
|
||||||
if (psiField !is PsiEnumConstant) {
|
?.declarations
|
||||||
KtLightFieldForDecompiledDeclaration(
|
?.filterIsInstance<KtClassOrObject>()
|
||||||
fldDelegate = psiField,
|
?.firstOrNull { cls -> cls.name == this.clsDelegate.name }
|
||||||
fldParent = this,
|
|
||||||
lightMemberOrigin = LightMemberOriginForCompiledField(psiField, file)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
KtLightEnumEntryForDecompiledDeclaration(
|
|
||||||
fldDelegate = psiField,
|
|
||||||
fldParent = this,
|
|
||||||
lightMemberOrigin = LightMemberOriginForCompiledField(psiField, file),
|
|
||||||
file = file
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val _innerClasses: MutableList<PsiClass> by lazyPub {
|
KtLightClassForDecompiledDeclaration(
|
||||||
mutableListOf<PsiClass>().also {
|
clsDelegate = psiClass,
|
||||||
clsDelegate.innerClasses.mapTo(it) { psiClass ->
|
clsParent = this,
|
||||||
val innerDeclaration = kotlinOrigin
|
file = file,
|
||||||
?.declarations
|
kotlinOrigin = innerDeclaration,
|
||||||
?.filterIsInstance<KtClassOrObject>()
|
)
|
||||||
?.firstOrNull { cls -> cls.name == clsDelegate.name }
|
|
||||||
|
|
||||||
KtLightClassForDecompiledDeclaration(
|
|
||||||
clsDelegate = psiClass,
|
|
||||||
clsParent = this,
|
|
||||||
file = file,
|
|
||||||
kotlinOrigin = innerDeclaration,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-4
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -23,8 +23,6 @@ internal class KtLightClassForDecompiledFacade(
|
|||||||
override val files: Collection<KtFile>,
|
override val files: Collection<KtFile>,
|
||||||
) : KtLightClassForDecompiledDeclaration(clsDelegate, clsParent, file, kotlinOrigin), KtLightClassForFacade {
|
) : KtLightClassForDecompiledDeclaration(clsDelegate, clsParent, file, kotlinOrigin), KtLightClassForFacade {
|
||||||
override fun getName(): String = super<KtLightClassForFacade>.getName()
|
override fun getName(): String = super<KtLightClassForFacade>.getName()
|
||||||
|
override val facadeClassFqName: FqName get() = file.javaFileFacadeFqName
|
||||||
override val facadeClassFqName: FqName = file.javaFileFacadeFqName
|
|
||||||
|
|
||||||
override val originKind: LightClassOriginKind get() = LightClassOriginKind.BINARY
|
override val originKind: LightClassOriginKind get() = LightClassOriginKind.BINARY
|
||||||
}
|
}
|
||||||
+10
-9
@@ -1,4 +1,7 @@
|
|||||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.decompiled.light.classes
|
package org.jetbrains.kotlin.analysis.decompiled.light.classes
|
||||||
|
|
||||||
@@ -12,14 +15,12 @@ internal class KtLightEnumClassForDecompiledDeclaration(
|
|||||||
clsParent: KtLightClassForDecompiledDeclaration,
|
clsParent: KtLightClassForDecompiledDeclaration,
|
||||||
file: KtClsFile,
|
file: KtClsFile,
|
||||||
kotlinOrigin: KtClassOrObject?
|
kotlinOrigin: KtClassOrObject?
|
||||||
) :
|
) : KtLightClassForDecompiledDeclaration(
|
||||||
KtLightClassForDecompiledDeclaration(
|
clsDelegate = psiConstantInitializer,
|
||||||
clsDelegate = psiConstantInitializer,
|
clsParent = clsParent,
|
||||||
clsParent = clsParent,
|
file = file,
|
||||||
file = file,
|
kotlinOrigin = kotlinOrigin
|
||||||
kotlinOrigin = kotlinOrigin
|
), PsiEnumConstantInitializer {
|
||||||
), PsiEnumConstantInitializer {
|
|
||||||
|
|
||||||
override fun getBaseClassType(): PsiClassType = psiConstantInitializer.baseClassType
|
override fun getBaseClassType(): PsiClassType = psiConstantInitializer.baseClassType
|
||||||
|
|
||||||
override fun getArgumentList(): PsiExpressionList? = psiConstantInitializer.argumentList
|
override fun getArgumentList(): PsiExpressionList? = psiConstantInitializer.argumentList
|
||||||
|
|||||||
+241
-73
@@ -6,21 +6,22 @@
|
|||||||
package org.jetbrains.kotlin.asJava.classes;
|
package org.jetbrains.kotlin.asJava.classes;
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
|
import com.intellij.openapi.util.ModificationTracker;
|
||||||
import com.intellij.openapi.util.Pair;
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.openapi.util.Ref;
|
import com.intellij.openapi.util.Ref;
|
||||||
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||||
import com.intellij.psi.impl.PsiClassImplUtil;
|
import com.intellij.psi.impl.PsiClassImplUtil;
|
||||||
import com.intellij.psi.impl.PsiImplUtil;
|
import com.intellij.psi.impl.PsiImplUtil;
|
||||||
import com.intellij.psi.impl.PsiSuperMethodImplUtil;
|
import com.intellij.psi.impl.PsiSuperMethodImplUtil;
|
||||||
import com.intellij.psi.impl.light.*;
|
import com.intellij.psi.impl.light.*;
|
||||||
import com.intellij.psi.impl.source.PsiExtensibleClass;
|
|
||||||
import com.intellij.psi.javadoc.PsiDocComment;
|
import com.intellij.psi.javadoc.PsiDocComment;
|
||||||
import com.intellij.psi.search.GlobalSearchScope;
|
import com.intellij.psi.search.GlobalSearchScope;
|
||||||
|
import com.intellij.psi.util.CachedValueProvider;
|
||||||
import com.intellij.psi.util.CachedValuesManager;
|
import com.intellij.psi.util.CachedValuesManager;
|
||||||
import com.intellij.psi.util.MethodSignature;
|
import com.intellij.psi.util.MethodSignature;
|
||||||
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
||||||
import com.intellij.psi.util.PsiUtil;
|
|
||||||
import com.intellij.util.ArrayUtil;
|
import com.intellij.util.ArrayUtil;
|
||||||
import com.intellij.util.IncorrectOperationException;
|
import com.intellij.util.IncorrectOperationException;
|
||||||
import com.intellij.util.containers.ConcurrentFactoryMap;
|
import com.intellij.util.containers.ConcurrentFactoryMap;
|
||||||
@@ -30,6 +31,11 @@ import com.intellij.util.containers.JBIterable;
|
|||||||
import org.jetbrains.annotations.NonNls;
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin;
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod;
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightParameter;
|
||||||
|
import org.jetbrains.kotlin.psi.KtDeclaration;
|
||||||
|
import org.jetbrains.kotlin.psi.KtParameter;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -41,31 +47,65 @@ import static com.intellij.util.ObjectUtils.notNull;
|
|||||||
* @see com.intellij.psi.impl.source.ClassInnerStuffCache
|
* @see com.intellij.psi.impl.source.ClassInnerStuffCache
|
||||||
*/
|
*/
|
||||||
public final class ClassInnerStuffCache {
|
public final class ClassInnerStuffCache {
|
||||||
private final PsiExtensibleClass myClass;
|
public static final String NOT_NULL_ANNOTATION_QUALIFIER = "@" + NotNull.class.getName();
|
||||||
private final Ref<Pair<Long, Interner<PsiMember>>> myInterner = Ref.create();
|
|
||||||
|
|
||||||
public ClassInnerStuffCache(@NotNull PsiExtensibleClass aClass) {
|
private final @NotNull KtExtensibleLightClass myClass;
|
||||||
|
private final @NotNull ModificationTracker myModificationTracker;
|
||||||
|
private final @NotNull Ref<Pair<Long, Interner<PsiMember>>> myInterner = Ref.create();
|
||||||
|
private final boolean myGenerateEnumMethods;
|
||||||
|
|
||||||
|
public ClassInnerStuffCache(
|
||||||
|
@NotNull KtExtensibleLightClass aClass,
|
||||||
|
boolean generateEnumMethods,
|
||||||
|
@NotNull ModificationTracker modificationTracker
|
||||||
|
) {
|
||||||
|
myGenerateEnumMethods = generateEnumMethods;
|
||||||
myClass = aClass;
|
myClass = aClass;
|
||||||
|
myModificationTracker = modificationTracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PsiMethod @NotNull [] getConstructors() {
|
@NotNull
|
||||||
return copy(CachedValuesManager.getProjectPsiDependentCache(myClass, PsiImplUtil::getConstructors));
|
public PsiMethod[] getConstructors() {
|
||||||
|
return copy(CachedValuesManager.getCachedValue(
|
||||||
|
myClass,
|
||||||
|
() -> CachedValueProvider.Result.createSingleDependency(
|
||||||
|
PsiImplUtil.getConstructors(myClass),
|
||||||
|
myModificationTracker
|
||||||
|
)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public PsiField @NotNull [] getFields() {
|
@NotNull
|
||||||
return copy(CachedValuesManager.getProjectPsiDependentCache(myClass, __ -> calcFields()));
|
public PsiField[] getFields() {
|
||||||
|
return copy(CachedValuesManager.getCachedValue(
|
||||||
|
myClass,
|
||||||
|
() -> CachedValueProvider.Result.createSingleDependency(
|
||||||
|
calcFields(),
|
||||||
|
myModificationTracker
|
||||||
|
)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public PsiMethod @NotNull [] getMethods() {
|
@NotNull
|
||||||
return copy(CachedValuesManager.getProjectPsiDependentCache(myClass, __ -> calcMethods()));
|
public PsiMethod[] getMethods() {
|
||||||
|
return copy(CachedValuesManager.getCachedValue(
|
||||||
|
myClass,
|
||||||
|
() -> CachedValueProvider.Result.createSingleDependency(
|
||||||
|
calcMethods(),
|
||||||
|
myModificationTracker
|
||||||
|
)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public PsiClass @NotNull [] getInnerClasses() {
|
@NotNull
|
||||||
return copy(CachedValuesManager.getProjectPsiDependentCache(myClass, __ -> calcInnerClasses()));
|
public PsiClass[] getInnerClasses() {
|
||||||
}
|
return copy(CachedValuesManager.getCachedValue(
|
||||||
|
myClass,
|
||||||
public PsiRecordComponent @NotNull [] getRecordComponents() {
|
() -> CachedValueProvider.Result.createSingleDependency(
|
||||||
return copy(CachedValuesManager.getProjectPsiDependentCache(myClass, __ -> calcRecordComponents()));
|
calcInnerClasses(),
|
||||||
|
myModificationTracker
|
||||||
|
)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -74,16 +114,29 @@ public final class ClassInnerStuffCache {
|
|||||||
return PsiClassImplUtil.findFieldByName(myClass, name, true);
|
return PsiClassImplUtil.findFieldByName(myClass, name, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return CachedValuesManager.getProjectPsiDependentCache(myClass, __ -> getFieldsMap()).get(name);
|
return CachedValuesManager.getCachedValue(
|
||||||
|
myClass,
|
||||||
|
() -> CachedValueProvider.Result.createSingleDependency(
|
||||||
|
getFieldsMap(),
|
||||||
|
myModificationTracker
|
||||||
|
)
|
||||||
|
).get(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PsiMethod @NotNull [] findMethodsByName(String name, boolean checkBases) {
|
@NotNull
|
||||||
|
public PsiMethod[] findMethodsByName(String name, boolean checkBases) {
|
||||||
if (checkBases) {
|
if (checkBases) {
|
||||||
return PsiClassImplUtil.findMethodsByName(myClass, name, true);
|
return PsiClassImplUtil.findMethodsByName(myClass, name, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return copy(notNull(CachedValuesManager.getProjectPsiDependentCache(myClass, __ -> getMethodsMap()).get(name), PsiMethod.EMPTY_ARRAY));
|
return copy(notNull(CachedValuesManager.getCachedValue(
|
||||||
|
myClass,
|
||||||
|
() -> CachedValueProvider.Result.createSingleDependency(
|
||||||
|
getMethodsMap(),
|
||||||
|
myModificationTracker
|
||||||
|
)
|
||||||
|
).get(name), PsiMethod.EMPTY_ARRAY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,37 +146,48 @@ public final class ClassInnerStuffCache {
|
|||||||
return PsiClassImplUtil.findInnerByName(myClass, name, true);
|
return PsiClassImplUtil.findInnerByName(myClass, name, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return CachedValuesManager.getProjectPsiDependentCache(myClass, __ -> getInnerClassesMap()).get(name);
|
return CachedValuesManager.getCachedValue(
|
||||||
|
myClass,
|
||||||
|
() -> CachedValueProvider.Result.createSingleDependency(
|
||||||
|
getInnerClassesMap(),
|
||||||
|
myModificationTracker
|
||||||
|
)
|
||||||
|
).get(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
PsiMethod getValuesMethod() {
|
private PsiMethod getValuesMethod() {
|
||||||
return myClass.isEnum() && !isAnonymousClass() && !classNameIsSealed()
|
return isEnum() ? internMember(CachedValuesManager.getCachedValue(
|
||||||
? internMember(CachedValuesManager.getProjectPsiDependentCache(myClass, ClassInnerStuffCache::makeValuesMethod))
|
myClass,
|
||||||
: null;
|
() -> CachedValueProvider.Result.createSingleDependency(
|
||||||
}
|
makeValuesMethod(myClass),
|
||||||
|
myModificationTracker
|
||||||
private boolean classNameIsSealed() {
|
)
|
||||||
return PsiKeyword.SEALED.equals(myClass.getName()) && PsiUtil.getLanguageLevel(myClass).isAtLeast(LanguageLevel.JDK_17);
|
)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private PsiMethod getValueOfMethod() {
|
private PsiMethod getValueOfMethod() {
|
||||||
return myClass.isEnum() && !isAnonymousClass()
|
return isEnum() ? internMember(CachedValuesManager.getCachedValue(
|
||||||
? internMember(CachedValuesManager.getProjectPsiDependentCache(myClass, ClassInnerStuffCache::makeValueOfMethod))
|
myClass,
|
||||||
: null;
|
() -> CachedValueProvider.Result.createSingleDependency(
|
||||||
|
makeValueOfMethod(myClass),
|
||||||
|
myModificationTracker
|
||||||
|
)
|
||||||
|
)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAnonymousClass() {
|
private boolean isEnum() {
|
||||||
return myClass.getName() == null || myClass instanceof PsiAnonymousClass;
|
return myGenerateEnumMethods && myClass.isEnum();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> T[] copy(T[] value) {
|
private static <T> T[] copy(T[] value) {
|
||||||
return value.length == 0 ? value : value.clone();
|
return value.length == 0 ? value : value.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
private PsiField @NotNull [] calcFields() {
|
@NotNull
|
||||||
|
private PsiField[] calcFields() {
|
||||||
List<PsiField> own = myClass.getOwnFields();
|
List<PsiField> own = myClass.getOwnFields();
|
||||||
List<PsiField> ext = internMembers(PsiAugmentProvider.collectAugments(myClass, PsiField.class, null));
|
List<PsiField> ext = internMembers(PsiAugmentProvider.collectAugments(myClass, PsiField.class, null));
|
||||||
return ArrayUtil.mergeCollections(own, ext, PsiField.ARRAY_FACTORY);
|
return ArrayUtil.mergeCollections(own, ext, PsiField.ARRAY_FACTORY);
|
||||||
@@ -134,23 +198,25 @@ public final class ClassInnerStuffCache {
|
|||||||
return ContainerUtil.map(members, this::internMember);
|
return ContainerUtil.map(members, this::internMember);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private <T extends PsiMember> T internMember(T m) {
|
private <T extends PsiMember> T internMember(T m) {
|
||||||
if (m == null) return null;
|
if (m == null) return null;
|
||||||
long modCount = myClass.getManager().getModificationTracker().getModificationCount();
|
long modCount = myModificationTracker.getModificationCount();
|
||||||
synchronized (myInterner) {
|
synchronized (myInterner) {
|
||||||
Pair<Long, Interner<PsiMember>> pair = myInterner.get();
|
Pair<Long, Interner<PsiMember>> pair = myInterner.get();
|
||||||
if (pair == null || pair.first.longValue() != modCount) {
|
if (pair == null || pair.first.longValue() != modCount) {
|
||||||
myInterner.set(pair = Pair.create(modCount, Interner.createWeakInterner()));
|
myInterner.set(pair = Pair.create(modCount, Interner.createWeakInterner()));
|
||||||
}
|
}
|
||||||
//noinspection unchecked
|
|
||||||
return (T) pair.second.intern(m);
|
return (T) pair.second.intern(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PsiMethod @NotNull [] calcMethods() {
|
@NotNull
|
||||||
|
private PsiMethod[] calcMethods() {
|
||||||
List<PsiMethod> own = myClass.getOwnMethods();
|
List<PsiMethod> own = myClass.getOwnMethods();
|
||||||
List<PsiMethod> ext = internMembers(PsiAugmentProvider.collectAugments(myClass, PsiMethod.class, null));
|
List<PsiMethod> ext = internMembers(PsiAugmentProvider.collectAugments(myClass, PsiMethod.class, null));
|
||||||
if (myGenerateEnumMethods && myClass.isEnum()) {
|
if (isEnum()) {
|
||||||
ext = new ArrayList<>(ext);
|
ext = new ArrayList<>(ext);
|
||||||
ContainerUtil.addIfNotNull(ext, getValuesMethod());
|
ContainerUtil.addIfNotNull(ext, getValuesMethod());
|
||||||
ContainerUtil.addIfNotNull(ext, getValueOfMethod());
|
ContainerUtil.addIfNotNull(ext, getValueOfMethod());
|
||||||
@@ -158,26 +224,21 @@ public final class ClassInnerStuffCache {
|
|||||||
return ArrayUtil.mergeCollections(own, ext, PsiMethod.ARRAY_FACTORY);
|
return ArrayUtil.mergeCollections(own, ext, PsiMethod.ARRAY_FACTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PsiClass @NotNull [] calcInnerClasses() {
|
@NotNull
|
||||||
|
private PsiClass[] calcInnerClasses() {
|
||||||
List<PsiClass> own = myClass.getOwnInnerClasses();
|
List<PsiClass> own = myClass.getOwnInnerClasses();
|
||||||
List<PsiClass> ext = internMembers(PsiAugmentProvider.collectAugments(myClass, PsiClass.class, null));
|
List<PsiClass> ext = internMembers(PsiAugmentProvider.collectAugments(myClass, PsiClass.class, null));
|
||||||
return ArrayUtil.mergeCollections(own, ext, PsiClass.ARRAY_FACTORY);
|
return ArrayUtil.mergeCollections(own, ext, PsiClass.ARRAY_FACTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PsiRecordComponent @NotNull [] calcRecordComponents() {
|
|
||||||
PsiRecordHeader header = myClass.getRecordHeader();
|
|
||||||
return header == null ? PsiRecordComponent.EMPTY_ARRAY : header.getRecordComponents();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Map<String, PsiField> getFieldsMap() {
|
private Map<String, PsiField> getFieldsMap() {
|
||||||
Map<String, PsiField> cachedFields = new HashMap<>();
|
Map<String, PsiField> cachedFields = new HashMap<>();
|
||||||
for (PsiField field : myClass.getOwnFields()) {
|
for (PsiField field : myClass.getOwnFields()) {
|
||||||
String name = field.getName();
|
String name = field.getName();
|
||||||
if (!cachedFields.containsKey(name)) {
|
cachedFields.putIfAbsent(name, field);
|
||||||
cachedFields.put(name, field);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ConcurrentFactoryMap.createMap(name -> {
|
return ConcurrentFactoryMap.createMap(name -> {
|
||||||
PsiField result = cachedFields.get(name);
|
PsiField result = cachedFields.get(name);
|
||||||
return result != null ? result :
|
return result != null ? result :
|
||||||
@@ -188,14 +249,13 @@ public final class ClassInnerStuffCache {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private Map<String, PsiMethod[]> getMethodsMap() {
|
private Map<String, PsiMethod[]> getMethodsMap() {
|
||||||
List<PsiMethod> ownMethods = myClass.getOwnMethods();
|
List<PsiMethod> ownMethods = myClass.getOwnMethods();
|
||||||
return ConcurrentFactoryMap.createMap(name -> {
|
return ConcurrentFactoryMap.createMap(name -> JBIterable
|
||||||
return JBIterable
|
.from(ownMethods)
|
||||||
.from(ownMethods).filter(m -> name.equals(m.getName()))
|
.filter(m -> name.equals(m.getName()))
|
||||||
.append("values".equals(name) ? getValuesMethod() : null)
|
.append("values".equals(name) ? getValuesMethod() : null)
|
||||||
.append("valueOf".equals(name) ? getValueOfMethod() : null)
|
.append("valueOf".equals(name) ? getValueOfMethod() : null)
|
||||||
.append(internMembers(PsiAugmentProvider.collectAugments(myClass, PsiMethod.class, name)))
|
.append(internMembers(PsiAugmentProvider.collectAugments(myClass, PsiMethod.class, name)))
|
||||||
.toArray(PsiMethod.EMPTY_ARRAY);
|
.toArray(PsiMethod.EMPTY_ARRAY));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -210,18 +270,20 @@ public final class ClassInnerStuffCache {
|
|||||||
cachedInners.put(name, psiClass);
|
cachedInners.put(name, psiClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ConcurrentFactoryMap.createMap(name -> {
|
return ConcurrentFactoryMap.createMap(name -> {
|
||||||
PsiClass result = cachedInners.get(name);
|
PsiClass result = cachedInners.get(name);
|
||||||
return result != null ? result :
|
return result != null
|
||||||
internMember(ContainerUtil.getFirstItem(PsiAugmentProvider.collectAugments(myClass, PsiClass.class, name)));
|
? result
|
||||||
|
: internMember(ContainerUtil.getFirstItem(PsiAugmentProvider.collectAugments(myClass, PsiClass.class, name)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PsiMethod makeValuesMethod(PsiExtensibleClass enumClass) {
|
private static PsiMethod makeValuesMethod(KtExtensibleLightClass enumClass) {
|
||||||
return new EnumSyntheticMethod(enumClass, EnumMethodKind.Values);
|
return new EnumSyntheticMethod(enumClass, EnumMethodKind.Values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PsiMethod makeValueOfMethod(PsiExtensibleClass enumClass) {
|
private static PsiMethod makeValueOfMethod(KtExtensibleLightClass enumClass) {
|
||||||
return new EnumSyntheticMethod(enumClass, EnumMethodKind.ValueOf);
|
return new EnumSyntheticMethod(enumClass, EnumMethodKind.ValueOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,14 +292,14 @@ public final class ClassInnerStuffCache {
|
|||||||
Values,
|
Values,
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class EnumSyntheticMethod extends LightElement implements PsiMethod, SyntheticElement {
|
private static class EnumSyntheticMethod extends LightElement implements PsiMethod, SyntheticElement, KtLightMethod {
|
||||||
private final PsiClass myClass;
|
private final KtExtensibleLightClass myClass;
|
||||||
private final EnumMethodKind myKind;
|
private final EnumMethodKind myKind;
|
||||||
private final PsiType myReturnType;
|
private final PsiType myReturnType;
|
||||||
private final LightParameterListBuilder myParameterList;
|
private final LightParameterListBuilder myParameterList;
|
||||||
private final LightModifierList myModifierList;
|
private final LightModifierList myModifierList;
|
||||||
|
|
||||||
EnumSyntheticMethod(@NotNull PsiClass enumClass, EnumMethodKind kind) {
|
EnumSyntheticMethod(@NotNull KtExtensibleLightClass enumClass, EnumMethodKind kind) {
|
||||||
super(enumClass.getManager(), enumClass.getLanguage());
|
super(enumClass.getManager(), enumClass.getLanguage());
|
||||||
myClass = enumClass;
|
myClass = enumClass;
|
||||||
myKind = kind;
|
myKind = kind;
|
||||||
@@ -256,6 +318,12 @@ public final class ClassInnerStuffCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private @NotNull PsiAnnotation[] createNotNullAnnotation() {
|
||||||
|
return new PsiAnnotation[] {
|
||||||
|
PsiElementFactory.getInstance(getProject()).createAnnotationFromText(NOT_NULL_ANNOTATION_QUALIFIER, myClass)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private @NotNull PsiType createReturnType() {
|
private @NotNull PsiType createReturnType() {
|
||||||
PsiClassType type = JavaPsiFacade.getElementFactory(getProject()).createType(myClass);
|
PsiClassType type = JavaPsiFacade.getElementFactory(getProject()).createType(myClass);
|
||||||
if (myKind == EnumMethodKind.Values) {
|
if (myKind == EnumMethodKind.Values) {
|
||||||
@@ -267,6 +335,20 @@ public final class ClassInnerStuffCache {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private LightModifierList createModifierList() {
|
private LightModifierList createModifierList() {
|
||||||
return new LightModifierList(myManager, getLanguage(), PsiModifier.PUBLIC, PsiModifier.STATIC) {
|
return new LightModifierList(myManager, getLanguage(), PsiModifier.PUBLIC, PsiModifier.STATIC) {
|
||||||
|
private final PsiAnnotation[] notNullAnnotations = createNotNullAnnotation();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public PsiAnnotation[] getAnnotations() {
|
||||||
|
return ClassInnerStuffCache.copy(notNullAnnotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PsiAnnotation findAnnotation(@NotNull String qualifiedName) {
|
||||||
|
PsiAnnotation notNullAnnotation = notNullAnnotations[0];
|
||||||
|
return qualifiedName == notNullAnnotation.getQualifiedName() ? notNullAnnotation : null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PsiElement getParent() {
|
public PsiElement getParent() {
|
||||||
return EnumSyntheticMethod.this;
|
return EnumSyntheticMethod.this;
|
||||||
@@ -279,12 +361,54 @@ public final class ClassInnerStuffCache {
|
|||||||
LightParameterListBuilder parameters = new LightParameterListBuilder(myManager, getLanguage());
|
LightParameterListBuilder parameters = new LightParameterListBuilder(myManager, getLanguage());
|
||||||
if (myKind == EnumMethodKind.ValueOf) {
|
if (myKind == EnumMethodKind.ValueOf) {
|
||||||
PsiClassType string = PsiType.getJavaLangString(myManager, GlobalSearchScope.allScope(getProject()));
|
PsiClassType string = PsiType.getJavaLangString(myManager, GlobalSearchScope.allScope(getProject()));
|
||||||
LightParameter parameter = new LightParameter("name", string, this, getLanguage(), false);
|
LightParameter parameter = new MyKtLightParameter(string, this);
|
||||||
parameters.addParameter(parameter);
|
parameters.addParameter(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class MyKtLightParameter extends LightParameter implements KtLightParameter {
|
||||||
|
private final @NotNull KtLightMethod myMethod;
|
||||||
|
|
||||||
|
MyKtLightParameter(@NotNull PsiType type, @NotNull KtLightMethod declarationScope) {
|
||||||
|
super("name", type, declarationScope, declarationScope.getLanguage(), false);
|
||||||
|
myMethod = declarationScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public KtParameter getKotlinOrigin() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public KtLightMethod getMethod() {
|
||||||
|
return myMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PsiElement getParent() {
|
||||||
|
return myMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PsiFile getContainingFile() {
|
||||||
|
return myMethod.getContainingFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextRange getTextRange() {
|
||||||
|
return TextRange.EMPTY_RANGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTextOffset() {
|
public int getTextOffset() {
|
||||||
return myClass.getTextOffset();
|
return myClass.getTextOffset();
|
||||||
@@ -292,7 +416,17 @@ public final class ClassInnerStuffCache {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return null;
|
return myClass.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextRange getTextRange() {
|
||||||
|
return TextRange.EMPTY_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -319,7 +453,7 @@ public final class ClassInnerStuffCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable PsiClass getContainingClass() {
|
public @NotNull KtExtensibleLightClass getContainingClass() {
|
||||||
return myClass;
|
return myClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,9 +474,15 @@ public final class ClassInnerStuffCache {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull PsiReferenceList getThrowsList() {
|
public @NotNull PsiReferenceList getThrowsList() {
|
||||||
LightReferenceListBuilder throwsList = new LightReferenceListBuilder(myManager, getLanguage(), PsiReferenceList.Role.THROWS_LIST);
|
LightReferenceListBuilder throwsList = new LightReferenceListBuilder(
|
||||||
|
myManager,
|
||||||
|
getLanguage(),
|
||||||
|
PsiReferenceList.Role.THROWS_LIST
|
||||||
|
);
|
||||||
|
|
||||||
if (myKind == EnumMethodKind.ValueOf) {
|
if (myKind == EnumMethodKind.ValueOf) {
|
||||||
throwsList.addReference("java.lang.IllegalArgumentException");
|
throwsList.addReference(IllegalArgumentException.class.getName());
|
||||||
|
throwsList.addReference(NullPointerException.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return throwsList;
|
return throwsList;
|
||||||
@@ -382,17 +522,20 @@ public final class ClassInnerStuffCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PsiMethod @NotNull [] findSuperMethods() {
|
@NotNull
|
||||||
|
public PsiMethod[] findSuperMethods() {
|
||||||
return PsiSuperMethodImplUtil.findSuperMethods(this);
|
return PsiSuperMethodImplUtil.findSuperMethods(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PsiMethod @NotNull [] findSuperMethods(boolean checkAccess) {
|
@NotNull
|
||||||
|
public PsiMethod[] findSuperMethods(boolean checkAccess) {
|
||||||
return PsiSuperMethodImplUtil.findSuperMethods(this, checkAccess);
|
return PsiSuperMethodImplUtil.findSuperMethods(this, checkAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PsiMethod @NotNull [] findSuperMethods(PsiClass parentClass) {
|
@NotNull
|
||||||
|
public PsiMethod[] findSuperMethods(PsiClass parentClass) {
|
||||||
return PsiSuperMethodImplUtil.findSuperMethods(this, parentClass);
|
return PsiSuperMethodImplUtil.findSuperMethods(this, parentClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,12 +545,14 @@ public final class ClassInnerStuffCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public @Nullable PsiMethod findDeepestSuperMethod() {
|
public @Nullable PsiMethod findDeepestSuperMethod() {
|
||||||
return PsiSuperMethodImplUtil.findDeepestSuperMethod(this);
|
return PsiSuperMethodImplUtil.findDeepestSuperMethod(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PsiMethod @NotNull [] findDeepestSuperMethods() {
|
@NotNull
|
||||||
|
public PsiMethod[] findDeepestSuperMethods() {
|
||||||
return PsiMethod.EMPTY_ARRAY;
|
return PsiMethod.EMPTY_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,6 +576,11 @@ public final class ClassInnerStuffCache {
|
|||||||
return PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this);
|
return PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable PsiAnnotationMemberValue getDefaultValue() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTypeParameters() {
|
public boolean hasTypeParameters() {
|
||||||
return false;
|
return false;
|
||||||
@@ -447,8 +597,26 @@ public final class ClassInnerStuffCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PsiTypeParameter @NotNull [] getTypeParameters() {
|
@NotNull
|
||||||
|
public PsiTypeParameter[] getTypeParameters() {
|
||||||
return PsiTypeParameter.EMPTY_ARRAY;
|
return PsiTypeParameter.EMPTY_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMangled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public KtDeclaration getKotlinOrigin() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public LightMemberOrigin getLightMemberOrigin() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+7
-3
@@ -14,11 +14,12 @@ import com.intellij.psi.impl.PsiSuperMethodImplUtil
|
|||||||
import com.intellij.psi.impl.light.*
|
import com.intellij.psi.impl.light.*
|
||||||
import com.intellij.psi.javadoc.PsiDocComment
|
import com.intellij.psi.javadoc.PsiDocComment
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.util.*
|
import com.intellij.psi.util.MethodSignature
|
||||||
|
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod
|
||||||
|
import com.intellij.psi.util.PsiUtil
|
||||||
import com.intellij.util.ArrayUtil
|
import com.intellij.util.ArrayUtil
|
||||||
import com.intellij.util.IncorrectOperationException
|
import com.intellij.util.IncorrectOperationException
|
||||||
import gnu.trove.THashMap
|
import gnu.trove.THashMap
|
||||||
import org.jetbrains.annotations.NotNull
|
|
||||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightParameter
|
import org.jetbrains.kotlin.asJava.elements.KtLightParameter
|
||||||
@@ -288,7 +289,10 @@ private class KotlinEnumSyntheticMethod(
|
|||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
private fun makeNotNullAnnotation(context: PsiClass): PsiAnnotation {
|
private fun makeNotNullAnnotation(context: PsiClass): PsiAnnotation {
|
||||||
return PsiElementFactory.getInstance(context.project).createAnnotationFromText("@" + NotNull::class.java.name, context)
|
return PsiElementFactory.getInstance(context.project).createAnnotationFromText(
|
||||||
|
ClassInnerStuffCache.NOT_NULL_ANNOTATION_QUALIFIER,
|
||||||
|
context,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-24
@@ -7,15 +7,16 @@ package org.jetbrains.kotlin.light.classes.symbol.classes
|
|||||||
|
|
||||||
import com.intellij.navigation.ItemPresentation
|
import com.intellij.navigation.ItemPresentation
|
||||||
import com.intellij.navigation.ItemPresentationProviders
|
import com.intellij.navigation.ItemPresentationProviders
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.util.Pair
|
import com.intellij.openapi.util.Pair
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.impl.*
|
import com.intellij.psi.impl.InheritanceImplUtil
|
||||||
|
import com.intellij.psi.impl.PsiClassImplUtil
|
||||||
|
import com.intellij.psi.impl.PsiImplUtil
|
||||||
|
import com.intellij.psi.impl.PsiSuperMethodImplUtil
|
||||||
import com.intellij.psi.impl.light.LightElement
|
import com.intellij.psi.impl.light.LightElement
|
||||||
import com.intellij.psi.javadoc.PsiDocComment
|
import com.intellij.psi.javadoc.PsiDocComment
|
||||||
import com.intellij.psi.scope.PsiScopeProcessor
|
import com.intellij.psi.scope.PsiScopeProcessor
|
||||||
import com.intellij.psi.util.CachedValueProvider
|
|
||||||
import com.intellij.psi.util.PsiUtil
|
import com.intellij.psi.util.PsiUtil
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
@@ -33,30 +34,15 @@ import javax.swing.Icon
|
|||||||
|
|
||||||
abstract class SymbolLightClassBase protected constructor(val ktModule: KtModule, manager: PsiManager) :
|
abstract class SymbolLightClassBase protected constructor(val ktModule: KtModule, manager: PsiManager) :
|
||||||
LightElement(manager, KotlinLanguage.INSTANCE), PsiClass, KtExtensibleLightClass {
|
LightElement(manager, KotlinLanguage.INSTANCE), PsiClass, KtExtensibleLightClass {
|
||||||
private class SymbolLightClassesLazyCreator(private val project: Project) : KotlinClassInnerStuffCache.LazyCreator() {
|
|
||||||
override fun <T : Any> get(initializer: () -> T, dependencies: List<Any>): Lazy<T> = object : Lazy<T> {
|
|
||||||
private val cachedValue = PsiCachedValueImpl(PsiManager.getInstance(project)) {
|
|
||||||
CachedValueProvider.Result.create(initializer(), dependencies)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val value: T get() = cachedValue.value ?: error("Unexpected null value from PsiCachedValueImpl")
|
private val myInnersCache by lazyPub {
|
||||||
|
ClassInnerStuffCache(
|
||||||
override fun isInitialized(): Boolean {
|
/* aClass = */ this,
|
||||||
// Lazy is a bad interface here as it has unneeded and unused in LC `isInitialized` method
|
/* generateEnumMethods = */ false,
|
||||||
// considering Interface Segregation Principle, Lazy should be repaced with a simpler interface with only `value` method
|
/* modificationTracker = */ project.createProjectWideOutOfBlockModificationTracker(),
|
||||||
error("Should not be called for LC")
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("LeakingThis")
|
|
||||||
private val myInnersCache = KotlinClassInnerStuffCache(
|
|
||||||
myClass = this@SymbolLightClassBase,
|
|
||||||
dependencies = listOf(manager.project.createProjectWideOutOfBlockModificationTracker()),
|
|
||||||
lazyCreator = SymbolLightClassesLazyCreator(project),
|
|
||||||
generateEnumMethods = false,
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun getFields(): Array<PsiField> = myInnersCache.fields
|
override fun getFields(): Array<PsiField> = myInnersCache.fields
|
||||||
|
|
||||||
override fun getMethods(): Array<PsiMethod> = myInnersCache.methods
|
override fun getMethods(): Array<PsiMethod> = myInnersCache.methods
|
||||||
|
|||||||
Reference in New Issue
Block a user