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.PsiClass
|
||||
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.Nullable
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.annotations.KtConstantAnnotationValue
|
||||
import org.jetbrains.kotlin.analysis.api.annotations.KtEnumEntryAnnotationValue
|
||||
import org.jetbrains.kotlin.analysis.api.annotations.KtNamedAnnotationValue
|
||||
import org.jetbrains.kotlin.analysis.api.annotations.annotations
|
||||
import org.jetbrains.kotlin.analysis.api.annotations.*
|
||||
import org.jetbrains.kotlin.analysis.api.components.buildClassType
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
|
||||
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.descriptors.annotations.AnnotationUseSiteTarget
|
||||
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.load.java.JvmAbi.JVM_FIELD_ANNOTATION_CLASS_ID
|
||||
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_SYNTHETIC_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.inline.INLINE_ONLY_ANNOTATION_FQ_NAME
|
||||
|
||||
@@ -92,19 +96,33 @@ internal fun KtAnnotatedSymbol.hasAnnotation(
|
||||
classId: ClassId,
|
||||
annotationUseSiteTarget: AnnotationUseSiteTarget?,
|
||||
strictUseSite: Boolean = true,
|
||||
): Boolean = annotations.any {
|
||||
val useSiteTarget = it.useSiteTarget
|
||||
(useSiteTarget == annotationUseSiteTarget || !strictUseSite && useSiteTarget == null) && it.classId == classId
|
||||
}
|
||||
): Boolean = findAnnotation(classId, annotationUseSiteTarget, strictUseSite) != null
|
||||
|
||||
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(
|
||||
fqName: FqName,
|
||||
annotationUseSiteTarget: AnnotationUseSiteTarget?,
|
||||
strictUseSite: Boolean = true,
|
||||
): Boolean = annotations.any {
|
||||
val useSiteTarget = it.useSiteTarget
|
||||
(useSiteTarget == annotationUseSiteTarget || !strictUseSite && useSiteTarget == null) && it.classId?.asSingleFqName() == fqName
|
||||
}
|
||||
): Boolean = findAnnotation(fqName, annotationUseSiteTarget, strictUseSite) != null
|
||||
|
||||
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? {
|
||||
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.psi.*
|
||||
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.KtConstantInitializerValue
|
||||
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.descriptors.annotations.AnnotationUseSiteTarget
|
||||
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.getJvmNameFromAnnotation
|
||||
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
|
||||
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) {
|
||||
val nullabilityApplicable = isGetter &&
|
||||
!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.PsiParameterList
|
||||
import com.intellij.psi.impl.light.LightReferenceListBuilder
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
|
||||
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.classes.lazyPub
|
||||
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.classes.SymbolLightClassBase
|
||||
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 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 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.impl.PsiImplUtil
|
||||
import com.intellij.psi.impl.PsiSuperMethodImplUtil
|
||||
import com.intellij.psi.impl.light.LightReferenceListBuilder
|
||||
import com.intellij.psi.util.MethodSignature
|
||||
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod
|
||||
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.KtLightClassForFacade
|
||||
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.mangleInternalName
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
@@ -79,8 +81,23 @@ internal abstract class SymbolLightMethodBase(
|
||||
abstract override fun hasTypeParameters(): Boolean
|
||||
abstract override fun getTypeParameterList(): PsiTypeParameterList?
|
||||
|
||||
override fun getThrowsList(): PsiReferenceList =
|
||||
KotlinLightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST) //TODO()
|
||||
private class SymbolLightThrowsReferencesListBuilder(
|
||||
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
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@ public final class MyException /* MyException*/ extends java.lang.Exception {
|
||||
public final class C /* C*/ {
|
||||
@kotlin.jvm.Throws(exceptionClasses = {java.io.IOException.class, MyException.class})
|
||||
@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})
|
||||
public C(int);// .ctor(int)
|
||||
public C(int) throws java.lang.Exception;// .ctor(int)
|
||||
|
||||
@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()
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
public final class ThrowsAnnotationKt /* ThrowsAnnotationKt*/ {
|
||||
@kotlin.jvm.Throws(exceptionClasses = {java.io.IOException.class, MyException.class})
|
||||
@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})
|
||||
public static final void baz();// baz()
|
||||
public static final void baz() throws java.lang.Throwable;// baz()
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user