mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
KT-18538 Unwrap fake override in ShortenReferences
- Fake override prevents reference shortener from shortening of static methods declared in the class bases when they are located not in direct parent of the class (for example, in grand- or grand-grand-parent) - The completion uses descriptor with unwrapped fake override when it performs the insertion. It leads to inserting the name of the base which actually contains the static method instead of the direct parent class. Now, when reference shortener compares unwrapped descriptors, this problem should be fixed during insertion handling Original commit: 2c12d26d281f43a6eb0b67c7154c42bc7f0120e7 GitOrigin-RevId: f990b3a2cded28a980436e37bf64d750698161c6
This commit is contained in:
committed by
intellij-monorepo-bot
parent
6e915e5314
commit
4b2b76ea0d
+3
-5
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.idea.completion.handlers.KotlinClassifierInsertHandl
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler
|
||||
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
|
||||
import org.jetbrains.kotlin.idea.core.completion.PackageLookupObject
|
||||
import org.jetbrains.kotlin.idea.core.unwrapIfFakeOverride
|
||||
import org.jetbrains.kotlin.idea.highlighter.dsl.DslHighlighterExtension
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
@@ -51,10 +52,7 @@ class BasicLookupElementFactory(
|
||||
includeClassTypeArguments: Boolean = true,
|
||||
parametersAndTypeGrayed: Boolean = false
|
||||
): LookupElement {
|
||||
val _descriptor = if (descriptor is CallableMemberDescriptor)
|
||||
DescriptorUtils.unwrapFakeOverride(descriptor)
|
||||
else
|
||||
descriptor
|
||||
val _descriptor = descriptor.unwrapIfFakeOverride()
|
||||
return createLookupElementUnwrappedDescriptor(_descriptor, qualifyNestedClasses, includeClassTypeArguments, parametersAndTypeGrayed)
|
||||
}
|
||||
|
||||
@@ -343,4 +341,4 @@ class BasicLookupElementFactory(
|
||||
presentation.icon = DefaultLookupItemRenderer.getRawIcon(this@withIconFromLookupObject, presentation.isReal)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-1
@@ -30,6 +30,10 @@ class CompletionMultiFileHandlerTest : KotlinCompletionTestCase() {
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testStaticMethodFromGrandParent() {
|
||||
doTest('\n', "StaticMethodFromGrandParent-1.java", "StaticMethodFromGrandParent-2.java")
|
||||
}
|
||||
|
||||
fun testTopLevelFunctionImport() {
|
||||
doTest()
|
||||
}
|
||||
@@ -113,8 +117,13 @@ class CompletionMultiFileHandlerTest : KotlinCompletionTestCase() {
|
||||
fun doTest(completionChar: Char = '\n', vararg extraFileNames: String, tailText: String? = null) {
|
||||
val fileName = getTestName(false)
|
||||
|
||||
val defaultFiles = listOf("$fileName-1.kt", "$fileName-2.kt")
|
||||
val filteredFiles = defaultFiles.filter { File(testDataPath, it).exists() }
|
||||
|
||||
require(filteredFiles.isNotEmpty()) { "At least one of $defaultFiles should exist!" }
|
||||
|
||||
configureByFiles(null, *extraFileNames)
|
||||
configureByFiles(null, "$fileName-1.kt", "$fileName-2.kt")
|
||||
configureByFiles(null, *filteredFiles.toTypedArray())
|
||||
complete(2)
|
||||
if (myItems != null) {
|
||||
val item = if (tailText == null)
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
public class Base extends GrandBase {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Inheritor : Base() {
|
||||
init {
|
||||
fooBa<caret>
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
public class GrandBase {
|
||||
public static void fooBar() {}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Inheritor : Base() {
|
||||
init {
|
||||
fooBar()
|
||||
}
|
||||
}
|
||||
@@ -552,7 +552,10 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
||||
// targetMatch == false, but shorten still can be preformed
|
||||
// TODO: Add possibility to check if descriptor from completion can't be resolved after shorten and not preform shorten than
|
||||
val resolvedCallsMatch = if (resolvedCall != null && resolvedCallWhenShort != null) {
|
||||
resolvedCall.resultingDescriptor.original == resolvedCallWhenShort.resultingDescriptor.original
|
||||
val originalCallDescriptor = resolvedCall.resultingDescriptor.original.unwrapIfFakeOverride()
|
||||
val shortenedCallDescriptor = resolvedCallWhenShort.resultingDescriptor.original.unwrapIfFakeOverride()
|
||||
|
||||
originalCallDescriptor == shortenedCallDescriptor
|
||||
} else {
|
||||
val resolvedCalls = selector.getCall(bindingContext)?.resolveCandidates(bindingContext, resolutionFacade) ?: emptyList()
|
||||
val callWhenShort = selectorAfterShortening.getCall(newContext)
|
||||
|
||||
@@ -141,3 +141,7 @@ fun <D : CallableMemberDescriptor> D.getDeepestSuperDeclarations(withThis: Boole
|
||||
|
||||
return overriddenDeclarations.filterNot(DescriptorUtils::isOverride)
|
||||
}
|
||||
|
||||
fun <T : DeclarationDescriptor> T.unwrapIfFakeOverride(): T {
|
||||
return if (this is CallableMemberDescriptor) DescriptorUtils.unwrapFakeOverride(this) else this
|
||||
}
|
||||
+2
-4
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.idea.analysis.analyzeInContext
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||
import org.jetbrains.kotlin.idea.codeInliner.CodeToInline
|
||||
import org.jetbrains.kotlin.idea.codeInliner.CodeToInlineBuilder
|
||||
import org.jetbrains.kotlin.idea.core.unwrapIfFakeOverride
|
||||
import org.jetbrains.kotlin.idea.project.findAnalyzerServices
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
@@ -43,10 +44,7 @@ object ReplaceWithAnnotationAnalyzer {
|
||||
resolutionFacade: ResolutionFacade,
|
||||
reformat: Boolean
|
||||
): CodeToInline? {
|
||||
val originalDescriptor = when (symbolDescriptor) {
|
||||
is CallableMemberDescriptor -> DescriptorUtils.unwrapFakeOverride(symbolDescriptor)
|
||||
else -> symbolDescriptor
|
||||
}.original
|
||||
val originalDescriptor = symbolDescriptor.unwrapIfFakeOverride().original
|
||||
return analyzeOriginal(annotation, originalDescriptor, resolutionFacade, reformat)
|
||||
}
|
||||
|
||||
|
||||
+10
@@ -284,6 +284,16 @@ public class ShortenRefsTestGenerated extends AbstractShortenRefsTest {
|
||||
runTest("testData/shortenRefs/java/innerClassOnDemandImport.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("redundantGrandParentClassQualifier.kt")
|
||||
public void testRedundantGrandParentClassQualifier() throws Exception {
|
||||
runTest("testData/shortenRefs/java/redundantGrandParentClassQualifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("redundantGrandParentClassQualifierAmbiguous.kt")
|
||||
public void testRedundantGrandParentClassQualifierAmbiguous() throws Exception {
|
||||
runTest("testData/shortenRefs/java/redundantGrandParentClassQualifierAmbiguous.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("staticClassNoImports.kt")
|
||||
public void testStaticClassNoImports() throws Exception {
|
||||
runTest("testData/shortenRefs/java/staticClassNoImports.kt");
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
public class Container {
|
||||
public static class GrandBase {
|
||||
public static void foo() {}
|
||||
}
|
||||
|
||||
public static class Base extends GrandBase {}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class C : Container.Base() {
|
||||
init {
|
||||
<selection>Container.GrandBase.foo()</selection>
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class C : Container.Base() {
|
||||
init {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
public class Container {
|
||||
public static class GrandBase {
|
||||
public static void foo() {}
|
||||
}
|
||||
|
||||
public static class Base extends GrandBase {
|
||||
public static void foo() {}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class C : Container.Base() {
|
||||
init {
|
||||
<selection>Container.GrandBase.foo()</selection>
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class C : Container.Base() {
|
||||
init {
|
||||
Container.GrandBase.foo()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user