diff --git a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinClassInnerStuffCache.kt b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinClassInnerStuffCache.kt index f827fa858bf..7295ae69bcd 100644 --- a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinClassInnerStuffCache.kt +++ b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinClassInnerStuffCache.kt @@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull 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.name.StandardClassIds import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.utils.addIfNotNull @@ -166,16 +167,33 @@ private class KotlinEnumSyntheticMethod( private val kind: Kind ) : LightElement(enumClass.manager, enumClass.language), KtLightMethod, SyntheticElement { enum class Kind(val methodName: String) { - VALUE_OF("valueOf"), VALUES("values") + VALUE_OF("valueOf"), VALUES("values"), ENTRIES("getEntries"), } private val returnType = run { - val enumType = JavaPsiFacade.getElementFactory(project).createType(enumClass) + val elementFactory = JavaPsiFacade.getElementFactory(project) + val enumTypeWithoutAnnotation = elementFactory.createType(enumClass) + val enumType = enumTypeWithoutAnnotation .annotate { arrayOf(makeNotNullAnnotation(enumClass)) } when (kind) { Kind.VALUE_OF -> enumType Kind.VALUES -> enumType.createArrayType().annotate { arrayOf(makeNotNullAnnotation(enumClass)) } + Kind.ENTRIES -> { + val enumEntriesClass = JavaPsiFacade.getInstance(project).findClass( + /* qualifiedName = */ StandardClassIds.EnumEntries.asFqNameString(), + /* scope = */ resolveScope + ) + val type = if (enumEntriesClass != null) { + elementFactory.createType(enumEntriesClass, enumTypeWithoutAnnotation) + } else { + elementFactory.createTypeFromText( + /* text = */ "${StandardClassIds.EnumEntries.asFqNameString()}<${enumClass.qualifiedName}>", + /* context = */ enumClass, + ) + } + type.annotate { arrayOf(makeNotNullAnnotation(enumClass)) } + } } } @@ -281,3 +299,6 @@ private val PsiClass.isAnonymous: Boolean private fun copy(value: Array): Array { return if (value.isEmpty()) value else value.clone() } + +fun getEnumEntriesPsiMethod(enumClass: KtExtensibleLightClass): PsiMethod = + KotlinEnumSyntheticMethod(enumClass, KotlinEnumSyntheticMethod.Kind.ENTRIES) \ No newline at end of file diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt index 34eff755d47..929abc53dcc 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.codegen.kotlinType +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor @@ -266,8 +267,8 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor private fun propertyParameters() = classOrObject.primaryConstructorParameters.filter { it.hasValOrVar() } - private fun ownMethods(): List { - val result = mutableListOf() + private fun ownMethods(): List { + val result = mutableListOf() for (declaration in this.classOrObject.declarations.filterNot { it.isHiddenByDeprecation(support) }) { if (declaration.hasModifier(PRIVATE_KEYWORD) && isInterface) continue @@ -319,18 +320,23 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor val lazyDescriptor = lazy { getDescriptor() } project.applyCompilerPlugins { + val methodsList = mutableListOf() it.interceptMethodsBuilding( declaration = kotlinOrigin, descriptor = lazyDescriptor, containingDeclaration = this, - methodsList = result + methodsList = methodsList ) + result.addAll(methodsList) + } + if (isEnum && support.languageVersionSettings.supportsFeature(LanguageFeature.EnumEntries)) { + result.add(getEnumEntriesPsiMethod(this)) } return result } - private val _ownMethods: CachedValue> = CachedValuesManager.getManager(project).createCachedValue( + private val _ownMethods: CachedValue> = CachedValuesManager.getManager(project).createCachedValue( { CachedValueProvider.Result.create( ownMethods(), @@ -339,7 +345,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor }, false ) - private fun addMethodsFromDataClass(result: MutableList) { + private fun addMethodsFromDataClass(result: MutableList) { if (!classOrObject.hasModifier(DATA_KEYWORD)) return val ktClass = classOrObject as? KtClass ?: return val descriptor = classOrObject.resolve() as? ClassDescriptor ?: return @@ -381,7 +387,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor }.generate() } - private fun addDelegatesToInterfaceMethods(result: MutableList) { + private fun addDelegatesToInterfaceMethods(result: MutableList) { classOrObject.superTypeListEntries.filterIsInstance().forEach { addDelegatesToInterfaceMethods(it, result) } @@ -389,7 +395,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor private fun addDelegatesToInterfaceMethods( superTypeEntry: KtDelegatedSuperTypeEntry, - result: MutableList + result: MutableList ) { val classDescriptor = classOrObject.resolve() as? ClassDescriptor ?: return val typeReference = superTypeEntry.typeReference ?: return @@ -475,7 +481,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor private fun isJvmStatic(declaration: KtAnnotated): Boolean = declaration.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) - override fun getOwnMethods(): List = _ownMethods.value + override fun getOwnMethods(): List = _ownMethods.value private fun KtAnnotated.hasAnnotation(name: FqName) = support.findAnnotation(this, name) != null diff --git a/compiler/testData/asJava/lightClasses/EnumClassWithEnumEntries.fir.java b/compiler/testData/asJava/lightClasses/EnumClassWithEnumEntries.fir.java deleted file mode 100644 index 6de553cf51a..00000000000 --- a/compiler/testData/asJava/lightClasses/EnumClassWithEnumEntries.fir.java +++ /dev/null @@ -1,17 +0,0 @@ -public enum MyEnumClass /* one.MyEnumClass*/ { - Entry; - - @org.jetbrains.annotations.NotNull() - public static kotlin.enums.EnumEntries getEntries();// getEntries() - - @org.jetbrains.annotations.NotNull() - public static one.MyEnumClass valueOf(java.lang.String) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;// valueOf(java.lang.String) - - @org.jetbrains.annotations.NotNull() - public static one.MyEnumClass[] values();// values() - - private MyEnumClass();// .ctor() - - public final int doo();// doo() - -} diff --git a/compiler/testData/asJava/lightClasses/EnumClassWithEnumEntries.java b/compiler/testData/asJava/lightClasses/EnumClassWithEnumEntries.java index dcecef082c6..6de553cf51a 100644 --- a/compiler/testData/asJava/lightClasses/EnumClassWithEnumEntries.java +++ b/compiler/testData/asJava/lightClasses/EnumClassWithEnumEntries.java @@ -1,6 +1,9 @@ public enum MyEnumClass /* one.MyEnumClass*/ { Entry; + @org.jetbrains.annotations.NotNull() + public static kotlin.enums.EnumEntries getEntries();// getEntries() + @org.jetbrains.annotations.NotNull() public static one.MyEnumClass valueOf(java.lang.String) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;// valueOf(java.lang.String) diff --git a/compiler/testData/asJava/lightClasses/EnumClassWithEnumEntries.kt b/compiler/testData/asJava/lightClasses/EnumClassWithEnumEntries.kt index 6aa36cbecad..80dfb1d501d 100644 --- a/compiler/testData/asJava/lightClasses/EnumClassWithEnumEntries.kt +++ b/compiler/testData/asJava/lightClasses/EnumClassWithEnumEntries.kt @@ -1,5 +1,7 @@ // one.MyEnumClass // !LANGUAGE: +EnumEntries +// IDEA tests don't support !LANGUAGE directive: +// COMPILER_ARGUMENTS: -XXLanguage:+EnumEntries package one