SLC: implement PsiMethod#getThrowsList
This commit is contained in:
committed by
Space Team
parent
42a0acac4f
commit
cc7083d59e
+60
-12
@@ -9,18 +9,21 @@ import com.intellij.psi.CommonClassNames.JAVA_LANG_ANNOTATION_RETENTION
|
|||||||
import com.intellij.psi.PsiAnnotation
|
import com.intellij.psi.PsiAnnotation
|
||||||
import com.intellij.psi.PsiClass
|
import com.intellij.psi.PsiClass
|
||||||
import com.intellij.psi.PsiModifierList
|
import com.intellij.psi.PsiModifierList
|
||||||
|
import com.intellij.psi.PsiClassType
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.impl.light.LightReferenceListBuilder
|
||||||
import org.jetbrains.annotations.NotNull
|
import org.jetbrains.annotations.NotNull
|
||||||
import org.jetbrains.annotations.Nullable
|
import org.jetbrains.annotations.Nullable
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.KtConstantAnnotationValue
|
import org.jetbrains.kotlin.analysis.api.annotations.*
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.KtEnumEntryAnnotationValue
|
import org.jetbrains.kotlin.analysis.api.components.buildClassType
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.KtNamedAnnotationValue
|
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.annotations
|
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol
|
||||||
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER
|
import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.NullabilityType
|
import org.jetbrains.kotlin.light.classes.symbol.NullabilityType
|
||||||
|
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethod
|
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethod
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_CLASS_ID
|
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_CLASS_ID
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.RETENTION_POLICY_ENUM
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.RETENTION_POLICY_ENUM
|
||||||
@@ -30,6 +33,7 @@ import org.jetbrains.kotlin.name.JvmNames.JVM_NAME_CLASS_ID
|
|||||||
import org.jetbrains.kotlin.name.JvmNames.JVM_OVERLOADS_CLASS_ID
|
import org.jetbrains.kotlin.name.JvmNames.JVM_OVERLOADS_CLASS_ID
|
||||||
import org.jetbrains.kotlin.name.JvmNames.JVM_SYNTHETIC_ANNOTATION_CLASS_ID
|
import org.jetbrains.kotlin.name.JvmNames.JVM_SYNTHETIC_ANNOTATION_CLASS_ID
|
||||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_CLASS_ID
|
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_CLASS_ID
|
||||||
|
import org.jetbrains.kotlin.resolve.annotations.JVM_THROWS_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
||||||
import org.jetbrains.kotlin.resolve.inline.INLINE_ONLY_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.resolve.inline.INLINE_ONLY_ANNOTATION_FQ_NAME
|
||||||
|
|
||||||
@@ -92,19 +96,33 @@ internal fun KtAnnotatedSymbol.hasAnnotation(
|
|||||||
classId: ClassId,
|
classId: ClassId,
|
||||||
annotationUseSiteTarget: AnnotationUseSiteTarget?,
|
annotationUseSiteTarget: AnnotationUseSiteTarget?,
|
||||||
strictUseSite: Boolean = true,
|
strictUseSite: Boolean = true,
|
||||||
): Boolean = annotations.any {
|
): Boolean = findAnnotation(classId, annotationUseSiteTarget, strictUseSite) != null
|
||||||
val useSiteTarget = it.useSiteTarget
|
|
||||||
(useSiteTarget == annotationUseSiteTarget || !strictUseSite && useSiteTarget == null) && it.classId == classId
|
internal fun KtAnnotatedSymbol.findAnnotation(
|
||||||
}
|
classId: ClassId,
|
||||||
|
annotationUseSiteTarget: AnnotationUseSiteTarget?,
|
||||||
|
strictUseSite: Boolean = true,
|
||||||
|
): KtAnnotationApplication? =
|
||||||
|
annotations.find {
|
||||||
|
val useSiteTarget = it.useSiteTarget
|
||||||
|
(useSiteTarget == annotationUseSiteTarget || !strictUseSite && useSiteTarget == null) && it.classId == classId
|
||||||
|
}
|
||||||
|
|
||||||
internal fun KtAnnotatedSymbol.hasAnnotation(
|
internal fun KtAnnotatedSymbol.hasAnnotation(
|
||||||
fqName: FqName,
|
fqName: FqName,
|
||||||
annotationUseSiteTarget: AnnotationUseSiteTarget?,
|
annotationUseSiteTarget: AnnotationUseSiteTarget?,
|
||||||
strictUseSite: Boolean = true,
|
strictUseSite: Boolean = true,
|
||||||
): Boolean = annotations.any {
|
): Boolean = findAnnotation(fqName, annotationUseSiteTarget, strictUseSite) != null
|
||||||
val useSiteTarget = it.useSiteTarget
|
|
||||||
(useSiteTarget == annotationUseSiteTarget || !strictUseSite && useSiteTarget == null) && it.classId?.asSingleFqName() == fqName
|
internal fun KtAnnotatedSymbol.findAnnotation(
|
||||||
}
|
fqName: FqName,
|
||||||
|
annotationUseSiteTarget: AnnotationUseSiteTarget?,
|
||||||
|
strictUseSite: Boolean = true,
|
||||||
|
): KtAnnotationApplication? =
|
||||||
|
annotations.find {
|
||||||
|
val useSiteTarget = it.useSiteTarget
|
||||||
|
(useSiteTarget == annotationUseSiteTarget || !strictUseSite && useSiteTarget == null) && it.classId?.asSingleFqName() == fqName
|
||||||
|
}
|
||||||
|
|
||||||
internal fun NullabilityType.computeNullabilityAnnotation(parent: PsiModifierList): SymbolLightSimpleAnnotation? {
|
internal fun NullabilityType.computeNullabilityAnnotation(parent: PsiModifierList): SymbolLightSimpleAnnotation? {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
@@ -192,3 +210,33 @@ private fun createRetentionRuntimeAnnotation(modifierList: PsiModifierList, rete
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
context(KtAnalysisSession)
|
||||||
|
internal fun KtAnnotatedSymbol.computeThrowsList(
|
||||||
|
builder: LightReferenceListBuilder,
|
||||||
|
annotationUseSiteTarget: AnnotationUseSiteTarget?,
|
||||||
|
useSitePosition: PsiElement,
|
||||||
|
containingClass: SymbolLightClassBase,
|
||||||
|
strictUseSite: Boolean = true,
|
||||||
|
) {
|
||||||
|
val annoApp = findAnnotation(JVM_THROWS_ANNOTATION_FQ_NAME, annotationUseSiteTarget, strictUseSite) ?: return
|
||||||
|
|
||||||
|
fun handleAnnotationValue(annotationValue: KtAnnotationValue) = when (annotationValue) {
|
||||||
|
is KtArrayAnnotationValue -> {
|
||||||
|
annotationValue.values.forEach(::handleAnnotationValue)
|
||||||
|
}
|
||||||
|
is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> {
|
||||||
|
val psiType = buildClassType(annotationValue.classId).asPsiType(
|
||||||
|
useSitePosition,
|
||||||
|
KtTypeMappingMode.DEFAULT,
|
||||||
|
containingClass.isAnnotationType
|
||||||
|
)
|
||||||
|
(psiType as? PsiClassType)?.let {
|
||||||
|
builder.addReference(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
annoApp.arguments.forEach { handleAnnotationValue(it.expression) }
|
||||||
|
}
|
||||||
|
|||||||
+14
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.light.classes.symbol.methods
|
|||||||
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.light.LightParameterListBuilder
|
import com.intellij.psi.impl.light.LightParameterListBuilder
|
||||||
|
import com.intellij.psi.impl.light.LightReferenceListBuilder
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue
|
import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue
|
||||||
import org.jetbrains.kotlin.analysis.api.KtConstantValueForAnnotation
|
import org.jetbrains.kotlin.analysis.api.KtConstantValueForAnnotation
|
||||||
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.asJava.classes.lazyPub
|
|||||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.*
|
import org.jetbrains.kotlin.light.classes.symbol.*
|
||||||
|
import org.jetbrains.kotlin.light.classes.symbol.annotations.*
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations
|
import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.annotations.getJvmNameFromAnnotation
|
import org.jetbrains.kotlin.light.classes.symbol.annotations.getJvmNameFromAnnotation
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation
|
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation
|
||||||
@@ -131,6 +133,18 @@ internal class SymbolLightAccessorMethod private constructor(
|
|||||||
//TODO Fix it when SymbolConstructorValueParameter be ready
|
//TODO Fix it when SymbolConstructorValueParameter be ready
|
||||||
private val isParameter: Boolean get() = containingPropertyDeclaration == null || containingPropertyDeclaration is KtParameter
|
private val isParameter: Boolean get() = containingPropertyDeclaration == null || containingPropertyDeclaration is KtParameter
|
||||||
|
|
||||||
|
override fun computeThrowsList(builder: LightReferenceListBuilder) {
|
||||||
|
analyzeForLightClasses(ktModule) {
|
||||||
|
propertyAccessorSymbol().computeThrowsList(
|
||||||
|
builder,
|
||||||
|
accessorSite,
|
||||||
|
this@SymbolLightAccessorMethod,
|
||||||
|
containingClass,
|
||||||
|
strictUseSite = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun computeAnnotations(modifierList: PsiModifierList): List<PsiAnnotation> = analyzeForLightClasses(ktModule) {
|
private fun computeAnnotations(modifierList: PsiModifierList): List<PsiAnnotation> = analyzeForLightClasses(ktModule) {
|
||||||
val nullabilityApplicable = isGetter &&
|
val nullabilityApplicable = isGetter &&
|
||||||
!modifierList.hasModifierProperty(PsiModifier.PRIVATE) &&
|
!modifierList.hasModifierProperty(PsiModifier.PRIVATE) &&
|
||||||
|
|||||||
+13
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.light.classes.symbol.methods
|
|||||||
|
|
||||||
import com.intellij.psi.PsiIdentifier
|
import com.intellij.psi.PsiIdentifier
|
||||||
import com.intellij.psi.PsiParameterList
|
import com.intellij.psi.PsiParameterList
|
||||||
|
import com.intellij.psi.impl.light.LightReferenceListBuilder
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
|
||||||
@@ -16,6 +17,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.sourcePsiSafe
|
|||||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
||||||
|
import org.jetbrains.kotlin.light.classes.symbol.annotations.computeThrowsList
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation
|
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase
|
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.compareSymbolPointers
|
import org.jetbrains.kotlin.light.classes.symbol.compareSymbolPointers
|
||||||
@@ -120,6 +122,17 @@ internal abstract class SymbolLightMethod<FType : KtFunctionLikeSymbol> private
|
|||||||
|
|
||||||
override fun getParameterList(): PsiParameterList = _parametersList
|
override fun getParameterList(): PsiParameterList = _parametersList
|
||||||
|
|
||||||
|
override fun computeThrowsList(builder: LightReferenceListBuilder) {
|
||||||
|
withFunctionSymbol { functionSymbol ->
|
||||||
|
functionSymbol.computeThrowsList(
|
||||||
|
builder,
|
||||||
|
annotationUseSiteTarget = null,
|
||||||
|
this@SymbolLightMethod,
|
||||||
|
containingClass
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun isValid(): Boolean = super.isValid() && functionDeclaration?.isValid ?: functionSymbolPointer.isValid(ktModule)
|
override fun isValid(): Boolean = super.isValid() && functionDeclaration?.isValid ?: functionSymbolPointer.isValid(ktModule)
|
||||||
|
|
||||||
override fun isOverride(): Boolean = withFunctionSymbol { it.getDirectlyOverriddenSymbols().isNotEmpty() }
|
override fun isOverride(): Boolean = withFunctionSymbol { it.getDirectlyOverriddenSymbols().isNotEmpty() }
|
||||||
|
|||||||
+19
-2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.light.classes.symbol.methods
|
|||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
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.LightReferenceListBuilder
|
||||||
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 org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
@@ -19,6 +20,7 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
|||||||
import org.jetbrains.kotlin.asJava.classes.KotlinLightReferenceListBuilder
|
import org.jetbrains.kotlin.asJava.classes.KotlinLightReferenceListBuilder
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||||
import org.jetbrains.kotlin.asJava.classes.cannotModify
|
import org.jetbrains.kotlin.asJava.classes.cannotModify
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
import org.jetbrains.kotlin.asJava.mangleInternalName
|
import org.jetbrains.kotlin.asJava.mangleInternalName
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
@@ -79,8 +81,23 @@ internal abstract class SymbolLightMethodBase(
|
|||||||
abstract override fun hasTypeParameters(): Boolean
|
abstract override fun hasTypeParameters(): Boolean
|
||||||
abstract override fun getTypeParameterList(): PsiTypeParameterList?
|
abstract override fun getTypeParameterList(): PsiTypeParameterList?
|
||||||
|
|
||||||
override fun getThrowsList(): PsiReferenceList =
|
private class SymbolLightThrowsReferencesListBuilder(
|
||||||
KotlinLightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST) //TODO()
|
private val parentMethod: PsiMethod
|
||||||
|
) : KotlinLightReferenceListBuilder(parentMethod.manager, parentMethod.language, PsiReferenceList.Role.THROWS_LIST) {
|
||||||
|
override fun getParent(): PsiElement = parentMethod
|
||||||
|
|
||||||
|
override fun getContainingFile(): PsiFile = parentMethod.containingFile
|
||||||
|
}
|
||||||
|
|
||||||
|
private val _throwsList by lazyPub {
|
||||||
|
val builder = SymbolLightThrowsReferencesListBuilder(this)
|
||||||
|
computeThrowsList(builder)
|
||||||
|
builder
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun computeThrowsList(builder: LightReferenceListBuilder) {}
|
||||||
|
|
||||||
|
override fun getThrowsList(): PsiReferenceList = _throwsList
|
||||||
|
|
||||||
override fun getDefaultValue(): PsiAnnotationMemberValue? = null
|
override fun getDefaultValue(): PsiAnnotationMemberValue? = null
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ public final class MyException /* MyException*/ extends java.lang.Exception {
|
|||||||
public final class C /* C*/ {
|
public final class C /* C*/ {
|
||||||
@kotlin.jvm.Throws(exceptionClasses = {java.io.IOException.class, MyException.class})
|
@kotlin.jvm.Throws(exceptionClasses = {java.io.IOException.class, MyException.class})
|
||||||
@org.jetbrains.annotations.NotNull()
|
@org.jetbrains.annotations.NotNull()
|
||||||
public final java.lang.String readFile(@org.jetbrains.annotations.NotNull() java.lang.String);// readFile(java.lang.String)
|
public final java.lang.String readFile(@org.jetbrains.annotations.NotNull() java.lang.String) throws java.io.IOException, MyException;// readFile(java.lang.String)
|
||||||
|
|
||||||
@kotlin.jvm.Throws(exceptionClasses = {java.lang.Exception.class})
|
@kotlin.jvm.Throws(exceptionClasses = {java.lang.Exception.class})
|
||||||
public C(int);// .ctor(int)
|
public C(int) throws java.lang.Exception;// .ctor(int)
|
||||||
|
|
||||||
@kotlin.jvm.Throws(exceptionClasses = {java.lang.Throwable.class})
|
@kotlin.jvm.Throws(exceptionClasses = {java.lang.Throwable.class})
|
||||||
public final void baz();// baz()
|
public final void baz() throws java.lang.Throwable;// baz()
|
||||||
|
|
||||||
public C();// .ctor()
|
public C();// .ctor()
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
public final class ThrowsAnnotationKt /* ThrowsAnnotationKt*/ {
|
public final class ThrowsAnnotationKt /* ThrowsAnnotationKt*/ {
|
||||||
@kotlin.jvm.Throws(exceptionClasses = {java.io.IOException.class, MyException.class})
|
@kotlin.jvm.Throws(exceptionClasses = {java.io.IOException.class, MyException.class})
|
||||||
@org.jetbrains.annotations.NotNull()
|
@org.jetbrains.annotations.NotNull()
|
||||||
public static final java.lang.String readFile(@org.jetbrains.annotations.NotNull() java.lang.String);// readFile(java.lang.String)
|
public static final java.lang.String readFile(@org.jetbrains.annotations.NotNull() java.lang.String) throws java.io.IOException, MyException;// readFile(java.lang.String)
|
||||||
|
|
||||||
@kotlin.jvm.Throws(exceptionClasses = {java.lang.Throwable.class})
|
@kotlin.jvm.Throws(exceptionClasses = {java.lang.Throwable.class})
|
||||||
public static final void baz();// baz()
|
public static final void baz() throws java.lang.Throwable;// baz()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user