mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-28 08:31:30 +00:00
[FIR IDE] LC fix annotations with special sites and nullability
This commit is contained in:
@@ -12,7 +12,7 @@ public final class Foo /* Foo*/ {
|
||||
|
||||
public Foo();// .ctor()
|
||||
|
||||
public final /* vararg */ void nullableVararg(@org.jetbrains.annotations.Nullable() java.lang.Object...);// nullableVararg(java.lang.Object[])
|
||||
public final /* vararg */ void nullableVararg(@org.jetbrains.annotations.NotNull() java.lang.Object...);// nullableVararg(java.lang.Object[])
|
||||
|
||||
public final int bar4();// bar4()
|
||||
|
||||
|
||||
@@ -8,9 +8,11 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols.markers
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
|
||||
data class ReceiverTypeAndAnnotations(val type: KtType, val annotations: List<KtAnnotationCall>)
|
||||
|
||||
interface KtPossibleExtensionSymbol {
|
||||
val receiverTypeAndAnnotations: ReceiverTypeAndAnnotations?
|
||||
val isExtension: Boolean
|
||||
val receiverType: KtType?
|
||||
}
|
||||
|
||||
val KtCallableSymbol.isExtension: Boolean
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.asJava.elements.FirLightIdentifier
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.idea.asJava.parameters.FirLightSetterParameterForSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
import org.jetbrains.kotlin.idea.util.ifTrue
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi.getterName
|
||||
@@ -173,8 +174,9 @@ internal class FirLightAccessorMethodForSymbol(
|
||||
|
||||
if (propertyParameter != null) {
|
||||
builder.addParameter(
|
||||
FirLightParameterForSymbol(
|
||||
FirLightSetterParameterForSymbol(
|
||||
parameterSymbol = propertyParameter,
|
||||
containingPropertySymbol = containingPropertySymbol,
|
||||
containingMethod = this@FirLightAccessorMethodForSymbol
|
||||
)
|
||||
)
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.idea.asJava
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.asJava.elements.FirLightIdentifier
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
||||
import org.jetbrains.kotlin.idea.util.ifTrue
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
|
||||
internal abstract class FirLightParameterBaseForSymbol(
|
||||
private val parameterSymbol: KtParameterSymbol,
|
||||
private val containingMethod: FirLightMethod
|
||||
) : FirLightParameter(containingMethod) {
|
||||
private val _name: String = parameterSymbol.name.asString()
|
||||
override fun getName(): String = _name
|
||||
|
||||
override fun hasModifierProperty(name: String): Boolean =
|
||||
modifierList.hasModifierProperty(name)
|
||||
|
||||
override val kotlinOrigin: KtParameter? = parameterSymbol.psi as? KtParameter
|
||||
|
||||
abstract override fun getModifierList(): PsiModifierList
|
||||
|
||||
private val _identifier: PsiIdentifier by lazyPub {
|
||||
FirLightIdentifier(this, parameterSymbol)
|
||||
}
|
||||
|
||||
protected val nullabilityType: NullabilityType get() {
|
||||
val nullabilityApplicable = !containingMethod.containingClass.let { it.isAnnotationType || it.isEnum } &&
|
||||
!containingMethod.hasModifierProperty(PsiModifier.PRIVATE)
|
||||
|
||||
return if (nullabilityApplicable) parameterSymbol.type.getTypeNullability(parameterSymbol, FirResolvePhase.TYPES)
|
||||
else NullabilityType.Unknown
|
||||
}
|
||||
|
||||
override fun getNameIdentifier(): PsiIdentifier = _identifier
|
||||
|
||||
private val _type by lazyPub {
|
||||
val convertedType = parameterSymbol.asPsiType(this, FirResolvePhase.TYPES)
|
||||
|
||||
if (convertedType is PsiArrayType && parameterSymbol.isVararg) {
|
||||
PsiEllipsisType(convertedType.componentType, convertedType.annotationProvider)
|
||||
} else convertedType
|
||||
}
|
||||
|
||||
override fun getType(): PsiType = _type
|
||||
|
||||
abstract override fun equals(other: Any?): Boolean
|
||||
|
||||
abstract override fun hashCode(): Int
|
||||
}
|
||||
@@ -11,19 +11,17 @@ import com.intellij.psi.PsiModifierList
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotatedSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.ReceiverTypeAndAnnotations
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtNamedSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtPossibleExtensionSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
|
||||
internal class FirLightParameterForReceiver private constructor(
|
||||
private val annotatedSymbol: KtAnnotatedSymbol,
|
||||
type: KtType,
|
||||
private val receiverTypeAndAnnotations: ReceiverTypeAndAnnotations,
|
||||
private val context: KtSymbol,
|
||||
methodName: String,
|
||||
method: FirLightMethod
|
||||
) : FirLightParameter(method) {
|
||||
@@ -35,15 +33,14 @@ internal class FirLightParameterForReceiver private constructor(
|
||||
): FirLightParameterForReceiver? {
|
||||
|
||||
if (callableSymbol !is KtNamedSymbol) return null
|
||||
if (callableSymbol !is KtAnnotatedSymbol) return null
|
||||
if (callableSymbol !is KtPossibleExtensionSymbol) return null
|
||||
|
||||
if (!callableSymbol.isExtension) return null
|
||||
val receiverType = callableSymbol.receiverType ?: return null
|
||||
val extensionTypeAndAnnotations = callableSymbol.receiverTypeAndAnnotations ?: return null
|
||||
|
||||
return FirLightParameterForReceiver(
|
||||
annotatedSymbol = callableSymbol,
|
||||
type = receiverType,
|
||||
receiverTypeAndAnnotations = extensionTypeAndAnnotations,
|
||||
context = callableSymbol,
|
||||
methodName = callableSymbol.name.asString(),
|
||||
method = method
|
||||
)
|
||||
@@ -64,11 +61,9 @@ internal class FirLightParameterForReceiver private constructor(
|
||||
override val kotlinOrigin: KtParameter? = null
|
||||
|
||||
private val _annotations: List<PsiAnnotation> by lazyPub {
|
||||
annotatedSymbol.computeAnnotations(
|
||||
parent = this,
|
||||
nullability = type.getTypeNullability(annotatedSymbol, FirResolvePhase.TYPES),
|
||||
annotationUseSiteTarget = AnnotationUseSiteTarget.RECEIVER,
|
||||
)
|
||||
receiverTypeAndAnnotations.annotations.map {
|
||||
FirLightAnnotationForAnnotationCall(it, this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getModifierList(): PsiModifierList = _modifierList
|
||||
@@ -77,7 +72,7 @@ internal class FirLightParameterForReceiver private constructor(
|
||||
}
|
||||
|
||||
private val _type: PsiType by lazyPub {
|
||||
type.asPsiType(annotatedSymbol, method, FirResolvePhase.TYPES)
|
||||
receiverTypeAndAnnotations.type.asPsiType(context, method, FirResolvePhase.TYPES)
|
||||
}
|
||||
|
||||
override fun getType(): PsiType = _type
|
||||
@@ -85,8 +80,7 @@ internal class FirLightParameterForReceiver private constructor(
|
||||
override fun equals(other: Any?): Boolean =
|
||||
this === other ||
|
||||
(other is FirLightParameterForReceiver &&
|
||||
kotlinOrigin == other.kotlinOrigin &&
|
||||
annotatedSymbol == other.annotatedSymbol)
|
||||
receiverTypeAndAnnotations == other.receiverTypeAndAnnotations)
|
||||
|
||||
override fun hashCode(): Int = kotlinOrigin.hashCode()
|
||||
}
|
||||
|
||||
@@ -5,46 +5,30 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.asJava
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.PsiAnnotation
|
||||
import com.intellij.psi.PsiModifierList
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.asJava.elements.FirLightIdentifier
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorParameterSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtParameterSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
||||
import org.jetbrains.kotlin.idea.util.ifTrue
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
|
||||
internal class FirLightParameterForSymbol(
|
||||
private val parameterSymbol: KtParameterSymbol,
|
||||
containingMethod: FirLightMethod
|
||||
) : FirLightParameter(containingMethod) {
|
||||
private val _name: String = parameterSymbol.name.asString()
|
||||
override fun getName(): String = _name
|
||||
|
||||
private val _isVarArgs: Boolean = parameterSymbol.isVararg
|
||||
override fun isVarArgs() = _isVarArgs
|
||||
override fun hasModifierProperty(name: String): Boolean =
|
||||
modifierList.hasModifierProperty(name)
|
||||
|
||||
override val kotlinOrigin: KtParameter? = parameterSymbol.psi as? KtParameter
|
||||
) : FirLightParameterBaseForSymbol(parameterSymbol, containingMethod) {
|
||||
|
||||
private val _annotations: List<PsiAnnotation> by lazyPub {
|
||||
val annotationSite = (containingMethod.isConstructor && parameterSymbol.symbolKind == KtSymbolKind.MEMBER).ifTrue {
|
||||
|
||||
val annotationSite = (parameterSymbol is KtConstructorParameterSymbol).ifTrue {
|
||||
AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
|
||||
}
|
||||
|
||||
val nullabilityApplicable = !containingMethod.containingClass.let { it.isAnnotationType || it.isEnum } &&
|
||||
!containingMethod.hasModifierProperty(PsiModifier.PRIVATE)
|
||||
|
||||
val nullabilityType = if (nullabilityApplicable)
|
||||
parameterSymbol.type.getTypeNullability(parameterSymbol, FirResolvePhase.TYPES)
|
||||
else NullabilityType.Unknown
|
||||
val nullability = if (parameterSymbol.isVararg) NullabilityType.NotNull else super.nullabilityType
|
||||
|
||||
parameterSymbol.computeAnnotations(
|
||||
parent = this,
|
||||
nullability = nullabilityType,
|
||||
nullability = nullability,
|
||||
annotationUseSiteTarget = annotationSite,
|
||||
includeAnnotationsWithoutSite = true
|
||||
)
|
||||
@@ -55,21 +39,7 @@ internal class FirLightParameterForSymbol(
|
||||
FirLightClassModifierList(this, emptySet(), _annotations)
|
||||
}
|
||||
|
||||
private val _identifier: PsiIdentifier by lazyPub {
|
||||
FirLightIdentifier(this, parameterSymbol)
|
||||
}
|
||||
|
||||
override fun getNameIdentifier(): PsiIdentifier = _identifier
|
||||
|
||||
private val _type by lazyPub {
|
||||
val convertedType = parameterSymbol.asPsiType(this, FirResolvePhase.TYPES)
|
||||
|
||||
if (convertedType is PsiArrayType && parameterSymbol.isVararg) {
|
||||
PsiEllipsisType(convertedType.componentType, convertedType.annotationProvider)
|
||||
} else convertedType
|
||||
}
|
||||
|
||||
override fun getType(): PsiType = _type
|
||||
override fun isVarArgs() = parameterSymbol.isVararg
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
this === other ||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.idea.asJava.parameters
|
||||
|
||||
import com.intellij.psi.PsiAnnotation
|
||||
import com.intellij.psi.PsiModifierList
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.idea.asJava.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtParameterSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
|
||||
|
||||
internal class FirLightSetterParameterForSymbol(
|
||||
private val containingPropertySymbol: KtPropertySymbol,
|
||||
private val parameterSymbol: KtParameterSymbol,
|
||||
containingMethod: FirLightMethod
|
||||
) : FirLightParameterBaseForSymbol(parameterSymbol, containingMethod) {
|
||||
|
||||
private val _annotations: List<PsiAnnotation> by lazyPub {
|
||||
val annotationsFomSetter = parameterSymbol.computeAnnotations(
|
||||
parent = this,
|
||||
nullability = NullabilityType.Unknown,
|
||||
annotationUseSiteTarget = null,
|
||||
)
|
||||
|
||||
val annotationsFromProperty = containingPropertySymbol.computeAnnotations(
|
||||
parent = this,
|
||||
nullability = nullabilityType,
|
||||
annotationUseSiteTarget = AnnotationUseSiteTarget.SETTER_PARAMETER,
|
||||
includeAnnotationsWithoutSite = false
|
||||
)
|
||||
|
||||
annotationsFomSetter + annotationsFromProperty
|
||||
}
|
||||
|
||||
override fun getModifierList(): PsiModifierList = _modifierList
|
||||
private val _modifierList: PsiModifierList by lazyPub {
|
||||
FirLightClassModifierList(this, emptySet(), _annotations)
|
||||
}
|
||||
|
||||
override fun isVarArgs() = false
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
this === other ||
|
||||
(other is FirLightSetterParameterForSymbol && parameterSymbol == other.parameterSymbol)
|
||||
|
||||
override fun hashCode(): Int = kotlinOrigin.hashCode()
|
||||
}
|
||||
@@ -18,10 +18,7 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignatu
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.convertAnnotation
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotationCall
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtCommonSymbolModality
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolVisibility
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
|
||||
@@ -57,7 +54,17 @@ internal class KtFirFunctionSymbol(
|
||||
|
||||
override val isSuspend: Boolean get() = firRef.withFir { it.isSuspend }
|
||||
override val isOverride: Boolean get() = firRef.withFir { it.isOverride }
|
||||
override val receiverType: KtType? by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir -> fir.receiverTypeRef?.let(builder::buildKtType) }
|
||||
|
||||
override val receiverTypeAndAnnotations: ReceiverTypeAndAnnotations? by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir ->
|
||||
fir.receiverTypeRef?.let { typeRef ->
|
||||
val type = builder.buildKtType(typeRef)
|
||||
val annotations = typeRef.annotations.mapNotNull {
|
||||
convertAnnotation(it, fir.session)
|
||||
}
|
||||
ReceiverTypeAndAnnotations(type, annotations)
|
||||
}
|
||||
}
|
||||
|
||||
override val isOperator: Boolean get() = firRef.withFir { it.isOperator }
|
||||
override val isExternal: Boolean get() = firRef.withFir { it.isExternal }
|
||||
override val isInline: Boolean get() = firRef.withFir { it.isInline }
|
||||
|
||||
@@ -47,7 +47,17 @@ internal class KtFirKotlinPropertySymbol(
|
||||
override val isVal: Boolean get() = firRef.withFir { it.isVal }
|
||||
override val name: Name get() = firRef.withFir { it.name }
|
||||
override val type: KtType by firRef.withFirAndCache(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { fir -> builder.buildKtType(fir.returnTypeRef) }
|
||||
override val receiverType: KtType? by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir -> fir.receiverTypeRef?.let(builder::buildKtType) }
|
||||
|
||||
override val receiverTypeAndAnnotations: ReceiverTypeAndAnnotations? by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir ->
|
||||
fir.receiverTypeRef?.let { typeRef ->
|
||||
val type = builder.buildKtType(typeRef)
|
||||
val annotations = typeRef.annotations.mapNotNull {
|
||||
convertAnnotation(it, fir.session)
|
||||
}
|
||||
ReceiverTypeAndAnnotations(type, annotations)
|
||||
}
|
||||
}
|
||||
|
||||
override val isExtension: Boolean get() = firRef.withFir { it.receiverTypeRef != null }
|
||||
override val initializer: KtConstantValue? by firRef.withFirAndCache(FirResolvePhase.BODY_RESOLVE) { fir -> fir.initializer?.convertConstantExpression() }
|
||||
override val symbolKind: KtSymbolKind
|
||||
|
||||
@@ -42,7 +42,15 @@ internal class KtFirSyntheticJavaPropertySymbol(
|
||||
override val isVal: Boolean get() = firRef.withFir { it.isVal }
|
||||
override val name: Name get() = firRef.withFir { it.name }
|
||||
override val type: KtType by firRef.withFirAndCache(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { fir -> builder.buildKtType(fir.returnTypeRef) }
|
||||
override val receiverType: KtType? by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir -> fir.receiverTypeRef?.let(builder::buildKtType) }
|
||||
override val receiverTypeAndAnnotations: ReceiverTypeAndAnnotations? by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir ->
|
||||
fir.receiverTypeRef?.let { typeRef ->
|
||||
val type = builder.buildKtType(typeRef)
|
||||
val annotations = typeRef.annotations.mapNotNull {
|
||||
convertAnnotation(it, fir.session)
|
||||
}
|
||||
ReceiverTypeAndAnnotations(type, annotations)
|
||||
}
|
||||
}
|
||||
override val isExtension: Boolean get() = firRef.withFir { it.receiverTypeRef != null }
|
||||
override val initializer: KtConstantValue? by firRef.withFirAndCache(FirResolvePhase.BODY_RESOLVE) { fir -> fir.initializer?.convertConstantExpression() }
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ private fun ConeClassLikeType.expandTypeAliasIfNeeded(session: FirSession): Cone
|
||||
?: return this
|
||||
}
|
||||
|
||||
private fun convertAnnotation(
|
||||
internal fun convertAnnotation(
|
||||
annotationCall: FirAnnotationCall,
|
||||
session: FirSession
|
||||
): KtFirAnnotationCall? {
|
||||
|
||||
@@ -94,8 +94,8 @@ private fun KtCall.stringRepresentation(): String {
|
||||
is KtFunctionLikeSymbol -> buildString {
|
||||
append(if (this@stringValue is KtFunctionSymbol) callableIdIfNonLocal ?: name else "<constructor>")
|
||||
append("(")
|
||||
(this@stringValue as? KtFunctionSymbol)?.receiverType?.let { receiver ->
|
||||
append("<receiver>: ${receiver.render()}")
|
||||
(this@stringValue as? KtFunctionSymbol)?.receiverTypeAndAnnotations?.let { receiver ->
|
||||
append("<receiver>: ${receiver.type.render()}")
|
||||
if (valueParameters.isNotEmpty()) append(", ")
|
||||
}
|
||||
valueParameters.joinTo(this) { parameter ->
|
||||
|
||||
Reference in New Issue
Block a user