KT-62695 [AA] Better resolve ambiguous receiver types in KDocReferenceResolver
When encountering multiple available same named types, resolve all of them together with corresponding extensions. This aligns well with the current resolve behavior of classes with the same name (see `SameNameClassesFromStarImports.kt`) Also, add extra test for resolving the ambiguous type without the extension function. The behavior is the same - resolve to the both classes.
This commit is contained in:
committed by
Space Team
parent
e5c6a5bac3
commit
d45662c2c3
+18
@@ -1486,6 +1486,18 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/qualifiers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("receiverTypesWithSameName_nestedScopes.kt")
|
||||
public void testReceiverTypesWithSameName_nestedScopes() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/receiverTypesWithSameName_nestedScopes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("receiverTypesWithSameName_starImports.kt")
|
||||
public void testReceiverTypesWithSameName_starImports() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/receiverTypesWithSameName_starImports.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("topLevelFunction.kt")
|
||||
public void testTopLevelFunction() throws Exception {
|
||||
@@ -1554,6 +1566,12 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/kDoc/imports"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SameNameClassesFromStarImports.kt")
|
||||
public void testSameNameClassesFromStarImports() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/imports/SameNameClassesFromStarImports.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("TypeAliasedImport.kt")
|
||||
public void testTypeAliasedImport() throws Exception {
|
||||
|
||||
+6
-7
@@ -60,7 +60,7 @@ internal object KDocReferenceResolver {
|
||||
context(KtAnalysisSession)
|
||||
internal fun resolveKdocFqName(selectedFqName: FqName, fullFqName: FqName, contextElement: KtElement): Collection<KtSymbol> {
|
||||
val fullSymbolsResolved = resolveKdocFqName(fullFqName, contextElement)
|
||||
if (selectedFqName == fullFqName) return fullSymbolsResolved.map { it.symbol }
|
||||
if (selectedFqName == fullFqName) return fullSymbolsResolved.mapTo(mutableSetOf()) { it.symbol }
|
||||
if (fullSymbolsResolved.isEmpty()) {
|
||||
val parent = fullFqName.parent()
|
||||
return resolveKdocFqName(selectedFqName = selectedFqName, fullFqName = parent, contextElement = contextElement)
|
||||
@@ -290,13 +290,12 @@ internal object KDocReferenceResolver {
|
||||
|
||||
val possibleReceivers = getReceiverTypeCandidates(receiverTypeName, contextElement)
|
||||
|
||||
// we abandon resolve if there are multiple different classifiers in scope
|
||||
val receiverClassSymbol = possibleReceivers.singleOrNull() ?: return emptyList()
|
||||
val receiverType = buildClassType(receiverClassSymbol)
|
||||
return possibleReceivers.flatMap { receiverClassSymbol ->
|
||||
val receiverType = buildClassType(receiverClassSymbol)
|
||||
val applicableExtensions = possibleExtensions.filter { it.canBeReferencedAsExtensionOn(receiverType) }
|
||||
|
||||
return possibleExtensions
|
||||
.filter { it.canBeReferencedAsExtensionOn(receiverType) }
|
||||
.map { it.toResolveResult(receiverClassReference = receiverClassSymbol) }
|
||||
applicableExtensions.map { it.toResolveResult(receiverClassReference = receiverClassSymbol) }
|
||||
}
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
|
||||
+18
@@ -1486,6 +1486,18 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/qualifiers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("receiverTypesWithSameName_nestedScopes.kt")
|
||||
public void testReceiverTypesWithSameName_nestedScopes() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/receiverTypesWithSameName_nestedScopes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("receiverTypesWithSameName_starImports.kt")
|
||||
public void testReceiverTypesWithSameName_starImports() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/receiverTypesWithSameName_starImports.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("topLevelFunction.kt")
|
||||
public void testTopLevelFunction() throws Exception {
|
||||
@@ -1554,6 +1566,12 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/kDoc/imports"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SameNameClassesFromStarImports.kt")
|
||||
public void testSameNameClassesFromStarImports() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/imports/SameNameClassesFromStarImports.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("TypeAliasedImport.kt")
|
||||
public void testTypeAliasedImport() throws Exception {
|
||||
|
||||
+18
@@ -1370,6 +1370,18 @@ public class FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerate
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/qualifiers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("receiverTypesWithSameName_nestedScopes.kt")
|
||||
public void testReceiverTypesWithSameName_nestedScopes() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/receiverTypesWithSameName_nestedScopes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("receiverTypesWithSameName_starImports.kt")
|
||||
public void testReceiverTypesWithSameName_starImports() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/receiverTypesWithSameName_starImports.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("topLevelFunction.kt")
|
||||
public void testTopLevelFunction() throws Exception {
|
||||
@@ -1438,6 +1450,12 @@ public class FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerate
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/kDoc/imports"), Pattern.compile("^([^.]+)\\.kt$"), null, true, "withErrors");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SameNameClassesFromStarImports.kt")
|
||||
public void testSameNameClassesFromStarImports() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/imports/SameNameClassesFromStarImports.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("TypeAliasedImport.kt")
|
||||
public void testTypeAliasedImport() throws Exception {
|
||||
|
||||
+18
@@ -1486,6 +1486,18 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/qualifiers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("receiverTypesWithSameName_nestedScopes.kt")
|
||||
public void testReceiverTypesWithSameName_nestedScopes() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/receiverTypesWithSameName_nestedScopes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("receiverTypesWithSameName_starImports.kt")
|
||||
public void testReceiverTypesWithSameName_starImports() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/receiverTypesWithSameName_starImports.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("topLevelFunction.kt")
|
||||
public void testTopLevelFunction() throws Exception {
|
||||
@@ -1554,6 +1566,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/kDoc/imports"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SameNameClassesFromStarImports.kt")
|
||||
public void testSameNameClassesFromStarImports() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/imports/SameNameClassesFromStarImports.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("TypeAliasedImport.kt")
|
||||
public void testTypeAliasedImport() throws Exception {
|
||||
|
||||
+18
@@ -1486,6 +1486,18 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/qualifiers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("receiverTypesWithSameName_nestedScopes.kt")
|
||||
public void testReceiverTypesWithSameName_nestedScopes() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/receiverTypesWithSameName_nestedScopes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("receiverTypesWithSameName_starImports.kt")
|
||||
public void testReceiverTypesWithSameName_starImports() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/extensions/receiverTypesWithSameName_starImports.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("topLevelFunction.kt")
|
||||
public void testTopLevelFunction() throws Exception {
|
||||
@@ -1554,6 +1566,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/kDoc/imports"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SameNameClassesFromStarImports.kt")
|
||||
public void testSameNameClassesFromStarImports() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/kDoc/imports/SameNameClassesFromStarImports.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("TypeAliasedImport.kt")
|
||||
public void testTypeAliasedImport() throws Exception {
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package test
|
||||
|
||||
fun Any.ext() {}
|
||||
|
||||
class Foo
|
||||
|
||||
class Outer {
|
||||
class Foo
|
||||
|
||||
/**
|
||||
* [<caret_1>Foo.ext]
|
||||
*
|
||||
* [Outer.<caret_2>Foo.ext]
|
||||
* [test.Outer.<caret_3>Foo.ext]
|
||||
*
|
||||
* [test.<caret_4>Foo.ext]
|
||||
*/
|
||||
fun test1() {}
|
||||
|
||||
class Nested {
|
||||
|
||||
class Foo
|
||||
|
||||
/**
|
||||
* [<caret_nested_1>Foo.ext]
|
||||
*
|
||||
* [Nested.<caret_nested_2>Foo.ext]
|
||||
* [Outer.Nested.<caret_nested_3>Foo.ext]
|
||||
* [test.Outer.Nested.<caret_nested_4>Foo.ext]
|
||||
*
|
||||
* [test.<caret_nested_5>Foo.ext]
|
||||
*/
|
||||
fun test2() {}
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
<caret_1> resolved to:
|
||||
0: (in test.Outer) class Foo
|
||||
|
||||
<caret_2> resolved to:
|
||||
0: (in test.Outer) class Foo
|
||||
|
||||
<caret_3> resolved to:
|
||||
0: (in test.Outer) class Foo
|
||||
|
||||
<caret_4> resolved to:
|
||||
0: (in test) class Foo
|
||||
|
||||
<caret_nested_1> resolved to:
|
||||
0: (in test.Outer.Nested) class Foo
|
||||
|
||||
<caret_nested_2> resolved to:
|
||||
0: (in test.Outer.Nested) class Foo
|
||||
|
||||
<caret_nested_3> resolved to:
|
||||
0: (in test.Outer.Nested) class Foo
|
||||
|
||||
<caret_nested_4> resolved to:
|
||||
0: (in test.Outer.Nested) class Foo
|
||||
|
||||
<caret_nested_5> resolved to:
|
||||
0: (in test) class Foo
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
// FILE: main.kt
|
||||
package test
|
||||
|
||||
import dep2.*
|
||||
import dep1.*
|
||||
|
||||
fun Any.ext() {}
|
||||
|
||||
/**
|
||||
* [Foo.<caret_1>ext]
|
||||
* [<caret_2>Foo.ext]
|
||||
*
|
||||
* [Foo.<caret_3>depExtShared]
|
||||
* [<caret_4>Foo.depExtShared]
|
||||
*
|
||||
* [Foo.<caret_5>depExt1]
|
||||
* [<caret_6>Foo.depExt1]
|
||||
*
|
||||
* [Foo.<caret_7>depExt2]
|
||||
* [<caret_8>Foo.depExt2]
|
||||
*
|
||||
* [dep1.<caret_9>Foo.ext]
|
||||
* [dep2.<caret_10>Foo.ext]
|
||||
*/
|
||||
fun test() {}
|
||||
|
||||
// FILE: dep1.kt
|
||||
package dep1
|
||||
|
||||
class Foo
|
||||
|
||||
fun Foo.depExtShared() {}
|
||||
|
||||
fun Foo.depExt1() {}
|
||||
|
||||
// FILE: dep2.kt
|
||||
package dep2
|
||||
|
||||
class Foo
|
||||
|
||||
fun Foo.depExtShared() {}
|
||||
|
||||
fun Foo.depExt2() {}
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<caret_1> resolved to:
|
||||
0: (in test) fun kotlin.Any.ext()
|
||||
|
||||
<caret_2> resolved to:
|
||||
0: (in dep1) class Foo
|
||||
1: (in dep2) class Foo
|
||||
|
||||
<caret_3> resolved to:
|
||||
0: (in dep1) fun dep1.Foo.depExtShared()
|
||||
1: (in dep2) fun dep2.Foo.depExtShared()
|
||||
|
||||
<caret_4> resolved to:
|
||||
0: (in dep1) class Foo
|
||||
1: (in dep2) class Foo
|
||||
|
||||
<caret_5> resolved to:
|
||||
0: (in dep1) fun dep1.Foo.depExt1()
|
||||
|
||||
<caret_6> resolved to:
|
||||
0: (in dep1) class Foo
|
||||
|
||||
<caret_7> resolved to:
|
||||
0: (in dep2) fun dep2.Foo.depExt2()
|
||||
|
||||
<caret_8> resolved to:
|
||||
0: (in dep2) class Foo
|
||||
|
||||
<caret_9> resolved to:
|
||||
0: (in dep1) class Foo
|
||||
|
||||
<caret_10> resolved to:
|
||||
0: (in dep2) class Foo
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
// FILE: main.kt
|
||||
package test
|
||||
|
||||
import dep2.*
|
||||
import dep1.*
|
||||
|
||||
/**
|
||||
* [<caret_1>Foo]
|
||||
*
|
||||
* [dep1.<caret_2>Foo]
|
||||
* [dep2.<caret_3>Foo]
|
||||
*/
|
||||
fun test() {}
|
||||
|
||||
// FILE: dep1.kt
|
||||
package dep1
|
||||
|
||||
class Foo
|
||||
|
||||
// FILE: dep2.kt
|
||||
package dep2
|
||||
|
||||
class Foo
|
||||
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
<caret_1> resolved to:
|
||||
0: (in dep1) class Foo
|
||||
1: (in dep2) class Foo
|
||||
|
||||
<caret_2> resolved to:
|
||||
0: (in dep1) class Foo
|
||||
|
||||
<caret_3> resolved to:
|
||||
0: (in dep2) class Foo
|
||||
Reference in New Issue
Block a user