[FIR] Fix resolve for java synthetic properties in KDoc
^KT-62880 fixed
This commit is contained in:
+24
@@ -1808,6 +1808,12 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/FunctionQualifiedWithKotlinSubclass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NoSyntheticFieldInClass.kt")
|
||||
public void testNoSyntheticFieldInClass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/NoSyntheticFieldInClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("StaticFieldQualified.kt")
|
||||
public void testStaticFieldQualified() {
|
||||
@@ -1843,6 +1849,24 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte
|
||||
public void testStaticFunctionQualifiedWithKotlinSubclass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/StaticFunctionQualifiedWithKotlinSubclass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticFieldInAnnotationInterface.kt")
|
||||
public void testSyntheticFieldInAnnotationInterface() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticFieldInAnnotationInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticFieldInClass.kt")
|
||||
public void testSyntheticFieldInClass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticFieldInClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticPropertyInKotlinSubclass.kt")
|
||||
public void testSyntheticPropertyInKotlinSubclass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticPropertyInKotlinSubclass.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+14
-1
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
||||
import kotlin.reflect.KClass
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
|
||||
import org.jetbrains.kotlin.load.java.possibleGetMethodNames
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
|
||||
internal object KDocReferenceResolver {
|
||||
@@ -122,7 +123,7 @@ internal object KDocReferenceResolver {
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun resolveKdocFqName(fqName: FqName, contextElement: KtElement): Collection<ResolveResult> {
|
||||
private fun resolveKdocFqName(fqName: FqName, contextElement: KtElement, trySyntheticGetters: Boolean = true): Collection<ResolveResult> {
|
||||
getExtensionReceiverSymbolByThisQualifier(fqName, contextElement).ifNotEmpty { return this }
|
||||
|
||||
buildList {
|
||||
@@ -135,9 +136,21 @@ internal object KDocReferenceResolver {
|
||||
|
||||
AdditionalKDocResolutionProvider.resolveKdocFqName(fqName, contextElement).map { it.toResolveResult() }.ifNotEmpty { return this }
|
||||
|
||||
if (trySyntheticGetters) {
|
||||
getSymbolsFromSyntheticProperty(fqName, contextElement).ifNotEmpty { return this }
|
||||
}
|
||||
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun getSymbolsFromSyntheticProperty(fqName: FqName, contextElement: KtElement): Collection<ResolveResult> {
|
||||
val getterNames = possibleGetMethodNames(fqName.shortNameOrSpecial())
|
||||
return getterNames.flatMap { getterName ->
|
||||
resolveKdocFqName(fqName.parent().child(getterName), contextElement, trySyntheticGetters = false)
|
||||
}
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun getExtensionReceiverSymbolByThisQualifier(fqName: FqName, contextElement: KtElement): Collection<ResolveResult> {
|
||||
val owner = contextElement.parentOfType<KtDeclaration>() ?: return emptyList()
|
||||
|
||||
+17
@@ -5,10 +5,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.fir.references
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSyntheticJavaPropertySymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.idea.references.KDocReference
|
||||
import org.jetbrains.kotlin.idea.references.KtFirReference
|
||||
import org.jetbrains.kotlin.idea.references.getPsiDeclarations
|
||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
|
||||
|
||||
|
||||
@@ -18,4 +22,17 @@ internal class KtFirKDocReference(element: KDocName) : KDocReference(element), K
|
||||
val selectedFqName = element.getQualifiedNameAsFqName()
|
||||
return KDocReferenceResolver.resolveKdocFqName(selectedFqName, fullFqName, element)
|
||||
}
|
||||
|
||||
override fun getResolvedToPsi(
|
||||
analysisSession: KtAnalysisSession,
|
||||
referenceTargetSymbols: Collection<KtSymbol>,
|
||||
): Collection<PsiElement> = with(analysisSession) {
|
||||
referenceTargetSymbols.flatMap { symbol ->
|
||||
when (symbol) {
|
||||
is KtFirSyntheticJavaPropertySymbol -> listOfNotNull(symbol.javaGetterSymbol.psi, symbol.javaSetterSymbol?.psi)
|
||||
is KtFirSymbol<*> -> getPsiDeclarations(symbol)
|
||||
else -> listOfNotNull(symbol.psi)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-7
@@ -13,9 +13,6 @@ import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.navigationTargetsProvider
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleStructureInternals
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
interface KtFirReference : KtReference, KtSymbolBasedReference {
|
||||
fun getResolvedToPsi(analysisSession: KtAnalysisSession, referenceTargetSymbols: Collection<KtSymbol>): Collection<PsiElement> =
|
||||
@@ -33,7 +30,10 @@ interface KtFirReference : KtReference, KtSymbolBasedReference {
|
||||
getResolvedToPsi(analysisSession, resolveToSymbols())
|
||||
}
|
||||
|
||||
private fun KtAnalysisSession.getPsiDeclarations(symbol: KtFirSymbol<*>): Collection<PsiElement> {
|
||||
override val resolver get() = KtFirReferenceResolver
|
||||
}
|
||||
|
||||
internal fun KtAnalysisSession.getPsiDeclarations(symbol: KtFirSymbol<*>): Collection<PsiElement> {
|
||||
val intersectionOverriddenSymbolsOrSingle = when {
|
||||
symbol.origin == KtSymbolOrigin.INTERSECTION_OVERRIDE && symbol is KtCallableSymbol -> symbol.getIntersectionOverriddenSymbols()
|
||||
else -> listOf(symbol)
|
||||
@@ -45,6 +45,3 @@ interface KtFirReference : KtReference, KtSymbolBasedReference {
|
||||
require(this is KtFirSymbol<*>)
|
||||
return firSymbol.fir.findReferencePsi()
|
||||
}
|
||||
|
||||
override val resolver get() = KtFirReferenceResolver
|
||||
}
|
||||
+24
@@ -1808,6 +1808,12 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/FunctionQualifiedWithKotlinSubclass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NoSyntheticFieldInClass.kt")
|
||||
public void testNoSyntheticFieldInClass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/NoSyntheticFieldInClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("StaticFieldQualified.kt")
|
||||
public void testStaticFieldQualified() {
|
||||
@@ -1843,6 +1849,24 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex
|
||||
public void testStaticFunctionQualifiedWithKotlinSubclass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/StaticFunctionQualifiedWithKotlinSubclass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticFieldInAnnotationInterface.kt")
|
||||
public void testSyntheticFieldInAnnotationInterface() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticFieldInAnnotationInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticFieldInClass.kt")
|
||||
public void testSyntheticFieldInClass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticFieldInClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticPropertyInKotlinSubclass.kt")
|
||||
public void testSyntheticPropertyInKotlinSubclass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticPropertyInKotlinSubclass.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+24
@@ -1692,6 +1692,12 @@ public class FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerate
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/FunctionQualifiedWithKotlinSubclass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NoSyntheticFieldInClass.kt")
|
||||
public void testNoSyntheticFieldInClass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/NoSyntheticFieldInClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("StaticFieldQualified.kt")
|
||||
public void testStaticFieldQualified() {
|
||||
@@ -1727,6 +1733,24 @@ public class FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerate
|
||||
public void testStaticFunctionQualifiedWithKotlinSubclass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/StaticFunctionQualifiedWithKotlinSubclass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticFieldInAnnotationInterface.kt")
|
||||
public void testSyntheticFieldInAnnotationInterface() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticFieldInAnnotationInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticFieldInClass.kt")
|
||||
public void testSyntheticFieldInClass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticFieldInClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticPropertyInKotlinSubclass.kt")
|
||||
public void testSyntheticPropertyInKotlinSubclass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticPropertyInKotlinSubclass.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+24
@@ -1808,6 +1808,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/FunctionQualifiedWithKotlinSubclass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NoSyntheticFieldInClass.kt")
|
||||
public void testNoSyntheticFieldInClass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/NoSyntheticFieldInClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("StaticFieldQualified.kt")
|
||||
public void testStaticFieldQualified() {
|
||||
@@ -1843,6 +1849,24 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten
|
||||
public void testStaticFunctionQualifiedWithKotlinSubclass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/StaticFunctionQualifiedWithKotlinSubclass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticFieldInAnnotationInterface.kt")
|
||||
public void testSyntheticFieldInAnnotationInterface() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticFieldInAnnotationInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticFieldInClass.kt")
|
||||
public void testSyntheticFieldInClass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticFieldInClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticPropertyInKotlinSubclass.kt")
|
||||
public void testSyntheticPropertyInKotlinSubclass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticPropertyInKotlinSubclass.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+24
@@ -1808,6 +1808,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/FunctionQualifiedWithKotlinSubclass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NoSyntheticFieldInClass.kt")
|
||||
public void testNoSyntheticFieldInClass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/NoSyntheticFieldInClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("StaticFieldQualified.kt")
|
||||
public void testStaticFieldQualified() {
|
||||
@@ -1843,6 +1849,24 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate
|
||||
public void testStaticFunctionQualifiedWithKotlinSubclass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/StaticFunctionQualifiedWithKotlinSubclass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticFieldInAnnotationInterface.kt")
|
||||
public void testSyntheticFieldInAnnotationInterface() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticFieldInAnnotationInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticFieldInClass.kt")
|
||||
public void testSyntheticFieldInClass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticFieldInClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SyntheticPropertyInKotlinSubclass.kt")
|
||||
public void testSyntheticPropertyInKotlinSubclass() {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/javaDeclarations/SyntheticPropertyInKotlinSubclass.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
// FILE: main.kt
|
||||
/**
|
||||
* [Storage.<caret_1>value]
|
||||
* [Storage.<caret_2>setValue]
|
||||
* [Storage.<caret_3>prop]
|
||||
*/
|
||||
fun usage() {
|
||||
|
||||
}
|
||||
|
||||
// FILE: Storage.java
|
||||
class Storage {
|
||||
void prop() {}
|
||||
void setValue(String value) {}
|
||||
String getProp() { return null; }
|
||||
}
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
<caret_1> resolved to:
|
||||
Nothing (Unresolved reference)
|
||||
|
||||
<caret_2> resolved to:
|
||||
0: (in Storage) open fun setValue(value: kotlin.String!)
|
||||
|
||||
<caret_3> resolved to:
|
||||
0: (in Storage) open fun prop()
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// FILE: main.kt
|
||||
/**
|
||||
* [Storage.<caret_1>value]
|
||||
* [Storage2.<caret_2>value2]
|
||||
*/
|
||||
fun usage() {
|
||||
|
||||
}
|
||||
|
||||
// FILE: Storage.java
|
||||
@interface Storage {
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
// FILE: Storage2.java
|
||||
@interface Storage2 {
|
||||
String value2();
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<caret_1> resolved to:
|
||||
0: (in Storage) val value: kotlin.String
|
||||
|
||||
<caret_2> resolved to:
|
||||
0: (in Storage2) val value2: kotlin.String
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
// FILE: main.kt
|
||||
/**
|
||||
* [Storage.<caret_1>value]
|
||||
* [Storage.<caret_2>getValue]
|
||||
*/
|
||||
fun usage() {
|
||||
|
||||
}
|
||||
|
||||
// FILE: Storage.java
|
||||
class Storage {
|
||||
String getValue() { return null; }
|
||||
}
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
<caret_1> resolved to:
|
||||
0: (in Storage) open fun getValue(): kotlin.String!
|
||||
|
||||
<caret_2> resolved to:
|
||||
0: (in Storage) open fun getValue(): kotlin.String!
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// FILE: main.kt
|
||||
import dependency.JavaBase
|
||||
|
||||
/**
|
||||
* [<caret_2>prop]
|
||||
* [KotlinChild.<caret_1>prop]
|
||||
*/
|
||||
class KotlinChild : JavaBase()
|
||||
|
||||
// FILE: dependency/JavaBase.java
|
||||
package dependency;
|
||||
|
||||
public class JavaBase {
|
||||
public String getProp() { return null; }
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<caret_2> resolved to:
|
||||
0: (in dependency.JavaBase) open fun getProp(): kotlin.String!
|
||||
|
||||
<caret_1> resolved to:
|
||||
0: (in dependency.JavaBase) open fun getProp(): kotlin.String!
|
||||
Reference in New Issue
Block a user