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 5a771ef495f..09dcc4eaf5d 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 @@ -14,7 +14,6 @@ import com.intellij.psi.impl.light.LightMethodBuilder import org.jetbrains.kotlin.asJava.builder.LightClassData import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightMethod -import org.jetbrains.kotlin.asJava.elements.KtLightModifierList import org.jetbrains.kotlin.asJava.elements.KtUltraLightModifierList import org.jetbrains.kotlin.backend.common.CodegenUtil import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator @@ -246,7 +245,13 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor for (parameter in propertyParameters()) { result.addAll( - membersBuilder.propertyAccessors(parameter, parameter.isMutable, forceStatic = false, onlyJvmStatic = false) + membersBuilder.propertyAccessors( + parameter, + parameter.isMutable, + forceStatic = false, + onlyJvmStatic = false, + createAsAnnotationMethod = isAnnotationType + ) ) } @@ -257,8 +262,16 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor this.classOrObject.companionObjects.firstOrNull()?.let { companion -> for (declaration in companion.declarations.filterNot { isHiddenByDeprecation(it) }) { when (declaration) { - is KtNamedFunction -> if (isJvmStatic(declaration)) result.addAll(membersBuilder.createMethods(declaration, true)) - is KtProperty -> result.addAll(membersBuilder.propertyAccessors(declaration, declaration.isVar, false, true)) + is KtNamedFunction -> + if (isJvmStatic(declaration)) result.addAll(membersBuilder.createMethods(declaration,forceStatic = true)) + is KtProperty -> result.addAll( + membersBuilder.propertyAccessors( + declaration, + declaration.isVar, + forceStatic = false, + onlyJvmStatic = true + ) + ) } } } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt index dcfb4e825c4..5cef20f2380 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt @@ -5,8 +5,7 @@ package org.jetbrains.kotlin.asJava.classes -import com.intellij.psi.PsiModifier -import com.intellij.psi.PsiType +import com.intellij.psi.* import com.intellij.psi.impl.light.LightMethodBuilder import com.intellij.psi.impl.light.LightModifierList import com.intellij.psi.impl.light.LightParameterListBuilder @@ -14,6 +13,7 @@ import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.asJava.elements.convertToLightAnnotationMemberValue import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotated @@ -132,6 +132,19 @@ internal class UltraLightMembersCreator( return result } + internal class KtUltraLightAnnotationMethod( + psiMethod: KtLightMethod, + expression: KtExpression + ) : KtLightMethod by psiMethod, + PsiAnnotationMethod { + + private val value by lazyPub { + convertToLightAnnotationMemberValue(psiMethod, expression) + } + + override fun getDefaultValue(): PsiAnnotationMemberValue? = value + } + private fun asJavaMethod( ktFunction: KtFunction, forceStatic: Boolean, @@ -146,7 +159,7 @@ internal class UltraLightMembersCreator( val method = lightMethod(name.orEmpty(), ktFunction, forceStatic, forcePrivate) val wrapper = KtUltraLightMethodForSourceDeclaration(method, ktFunction, support, containingClass) - addReceiverParameter(ktFunction, wrapper) + addReceiverParameter(ktFunction, wrapper, method) var remainingNumberOfDefaultParametersToAdd = if (numberOfDefaultParametersToAdd >= 0) @@ -180,9 +193,14 @@ internal class UltraLightMembersCreator( return wrapper } - private fun addReceiverParameter(callable: KtCallableDeclaration, method: KtUltraLightMethod) { + private fun addReceiverParameter(callable: KtCallableDeclaration, wrapper: KtUltraLightMethod, associatedBuilder: LightMethodBuilder) { if (callable.receiverTypeReference == null) return - method.delegate.addParameter(KtUltraLightReceiverParameter(callable, support, method)) + + require(wrapper.delegate == associatedBuilder) { + "Invalid use. Wrapper does not wrap an associated method builder." + } + + associatedBuilder.addParameter(KtUltraLightReceiverParameter(callable, support, wrapper)) } private fun methodReturnType(ktDeclaration: KtDeclaration, wrapper: KtUltraLightMethod, isSuspendFunction: Boolean): PsiType { @@ -250,7 +268,9 @@ internal class UltraLightMembersCreator( return when (name) { PsiModifier.FINAL -> !containingClass.isInterface && outer !is KtConstructor<*> && isFinal(outer) PsiModifier.ABSTRACT -> containingClass.isInterface || outer.hasModifier(KtTokens.ABSTRACT_KEYWORD) - PsiModifier.STATIC -> forceStatic || containingClassIsNamedObject && (outer.isJvmStatic(support) || declaration.isJvmStatic(support)) + PsiModifier.STATIC -> forceStatic || containingClassIsNamedObject && (outer.isJvmStatic(support) || declaration.isJvmStatic( + support + )) PsiModifier.STRICTFP -> declaration is KtFunction && declaration.hasAnnotation(STRICTFP_ANNOTATION_FQ_NAME) PsiModifier.SYNCHRONIZED -> declaration is KtFunction && declaration.hasAnnotation(SYNCHRONIZED_ANNOTATION_FQ_NAME) else -> false @@ -336,7 +356,8 @@ internal class UltraLightMembersCreator( declaration: KtCallableDeclaration, mutable: Boolean, forceStatic: Boolean, - onlyJvmStatic: Boolean + onlyJvmStatic: Boolean, + createAsAnnotationMethod: Boolean = false ): List { val propertyName = declaration.name ?: return emptyList() @@ -373,16 +394,24 @@ internal class UltraLightMembersCreator( auxiliaryOriginalElement = auxiliaryOrigin ) - val getterName = computeMethodName(auxiliaryOrigin, JvmAbi.getterName(propertyName), MethodType.GETTER) - val getterPrototype = lightMethod(getterName, auxiliaryOrigin, onlyJvmStatic || forceStatic) + val defaultGetterName = if (createAsAnnotationMethod) propertyName else JvmAbi.getterName(propertyName) + val getterName = computeMethodName(auxiliaryOrigin, defaultGetterName, MethodType.GETTER) + val getterPrototype = lightMethod(getterName, auxiliaryOrigin, forceStatic = onlyJvmStatic || forceStatic) val getterWrapper = KtUltraLightMethodForSourceDeclaration(getterPrototype, lightMemberOrigin, support, containingClass) + val getterType: PsiType by lazyPub { methodReturnType(declaration, getterWrapper, isSuspendFunction = false) } getterPrototype.setMethodReturnType { getterType } - addReceiverParameter(declaration, getterWrapper) - result.add(getterWrapper) + addReceiverParameter(declaration, getterWrapper, getterPrototype) + + val defaultExpression = if (createAsAnnotationMethod && declaration is KtParameter) declaration.defaultValue else null + val getterMethodResult = defaultExpression?.let { + KtUltraLightAnnotationMethod(getterWrapper, it) + } ?: getterWrapper + + result.add(getterMethodResult) } - if (mutable && needsAccessor(ktSetter)) { + if (!createAsAnnotationMethod && mutable && needsAccessor(ktSetter)) { val auxiliaryOrigin = ktSetter ?: declaration val lightMemberOrigin = LightMemberOriginForDeclaration( originalElement = declaration, @@ -390,11 +419,13 @@ internal class UltraLightMembersCreator( auxiliaryOriginalElement = auxiliaryOrigin ) + val setterName = computeMethodName(auxiliaryOrigin, JvmAbi.setterName(propertyName), MethodType.SETTER) - val setterPrototype = lightMethod(setterName, auxiliaryOrigin, onlyJvmStatic || forceStatic) + val setterPrototype = lightMethod(setterName, auxiliaryOrigin, forceStatic = onlyJvmStatic || forceStatic) .setMethodReturnType(PsiType.VOID) + val setterWrapper = KtUltraLightMethodForSourceDeclaration(setterPrototype, lightMemberOrigin, support, containingClass) - addReceiverParameter(declaration, setterWrapper) + addReceiverParameter(declaration, setterWrapper, setterPrototype) val setterParameter = ktSetter?.parameter setterPrototype.addParameter( if (setterParameter != null) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMethods.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMethods.kt index c93480750d1..694bff2bcb8 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMethods.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMethods.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.types.KotlinType internal abstract class KtUltraLightMethod( - internal val delegate: LightMethodBuilder, + internal val delegate: PsiMethod, lightMemberOrigin: LightMemberOrigin?, protected val support: KtUltraLightSupport, containingClass: KtLightClass @@ -101,7 +101,7 @@ internal abstract class KtUltraLightMethod( } internal class KtUltraLightMethodForSourceDeclaration( - delegate: LightMethodBuilder, + delegate: PsiMethod, lightMemberOrigin: LightMemberOrigin?, support: KtUltraLightSupport, containingClass: KtLightClass @@ -112,7 +112,7 @@ internal class KtUltraLightMethodForSourceDeclaration( containingClass ) { constructor( - delegate: LightMethodBuilder, + delegate: PsiMethod, declaration: KtDeclaration, support: KtUltraLightSupport, containingClass: KtLightClass diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightModifierList.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightModifierList.kt index 96a4847891c..cd7255b9da2 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightModifierList.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightModifierList.kt @@ -67,16 +67,24 @@ abstract class KtLightModifierList): List { + + val annotations = parent.clsDelegate.modifierList?.annotations + + if (annotations.isNullOrEmpty()) return emptyList() + + return annotations + .filter { it.qualifiedName !in sourceAnnotationNames } + .map { KtLightNonSourceAnnotation(this, it) } + } + private fun computeAnnotations(): List { val annotationsForEntries = owner.givenAnnotations ?: lightAnnotationsForEntries(this) val modifierListOwner = parent if (modifierListOwner is KtLightClassForSourceDeclaration && modifierListOwner.isAnnotationType) { - val sourceAnnotationNames = annotationsForEntries.mapTo(mutableSetOf()) { it.qualifiedName } - val specialAnnotationsOnAnnotationClass = modifierListOwner.clsDelegate.modifierList?.annotations.orEmpty().filter { - it.qualifiedName !in sourceAnnotationNames - }.map { KtLightNonSourceAnnotation(this, it) } - return annotationsForEntries + specialAnnotationsOnAnnotationClass + val sourceAnnotationNames = annotationsForEntries.mapNotNullTo(mutableSetOf()) { it.qualifiedName } + return annotationsForEntries + nonSourceAnnotations(sourceAnnotationNames) } if ((modifierListOwner is KtLightMember<*> && modifierListOwner !is KtLightFieldImpl.KtLightEnumConstant) || modifierListOwner is LightParameter @@ -114,6 +122,10 @@ abstract class KtUltraLightModifierList): List { + return emptyList() + } } open class KtLightSimpleModifierList( diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt index 98d1055876c..ddd10adec79 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt @@ -148,7 +148,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG } private fun findTooComplexDeclaration(declaration: KtDeclaration): PsiElement? { - if (declaration.hasExpectModifier() || declaration.hasModifier(KtTokens.ANNOTATION_KEYWORD)) { + if (declaration.hasExpectModifier()) { return declaration }