KTIJ-32202 [kotlin] Do not lock out conflicting symbols for the type positions

Locking in `java.lang.Deprecated` also led to locking out `kotlin.Deprecated`
alternative symbol.
This, in turn, led to adding explicit imports for everything from `kotlin.*`
package.

This seems like a wrong logic, but this will be dealt with later,
probably as a part of KTIJ-32231.

The current solution is to not lock out the `kotlin.Deprecated`
symbol for `KtUserType` positions (it includes annotation calls).
This logic is already present in K1 Mode's `OptimizedImportsBuilder`.

Also, add a muted testcase for KTIJ-32231 (doesn't work in both K1 and K2)

Also, add muting logic to the K1's `AbstractOptimizeImportsTest`

^KTIJ-32202 Fixed


(cherry picked from commit 89ce6287a44bd05b55cc6bbb3b01157bee30b41c)

IJ-CR-150012

GitOrigin-RevId: e4d004a7a10631afca474330c966a9332933d3da
This commit is contained in:
Roman Golyshev
2024-12-18 18:48:43 +00:00
committed by intellij-monorepo-bot
parent 6c3b9fa8f7
commit 49894bdce7
9 changed files with 93 additions and 4 deletions
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtImportDirective
import org.jetbrains.kotlin.psi.KtUserType
import org.jetbrains.kotlin.resolve.ImportPath
internal fun KaSession.buildOptimizedImports(
@@ -174,9 +175,16 @@ internal class OptimizedImportsBuilder(
val alternativeSymbols = alternativeUsedReference?.run { resolveToReferencedSymbols() }.orEmpty()
if (!areTargetsEqual(originalSymbols, alternativeSymbols)) {
val conflictingSymbols = originalSymbols + alternativeSymbols
val isTypePosition = originalReference.element.parent is KtUserType
for (conflictingSymbol in conflictingSymbols) {
val symbolsToLock = if (isTypePosition) {
originalSymbols
} else {
// TODO this can still lead to incorrect optimizations, see KTIJ-32231
originalSymbols + alternativeSymbols
}
for (conflictingSymbol in symbolsToLock) {
lockImportForSymbol(conflictingSymbol.run { toSymbolInfo() }, names)
}
}
@@ -219,6 +219,16 @@ public abstract class K2JvmOptimizeImportsTestGenerated extends AbstractK2JvmOpt
runTest("../../idea/tests/testData/editor/optimizeImports/jvm/FromCompanionObjectGeneric.kt");
}
@TestMetadata("JavaLangDeprecated_annotationPosition.kt")
public void testJavaLangDeprecated_annotationPosition() throws Exception {
runTest("../../idea/tests/testData/editor/optimizeImports/jvm/JavaLangDeprecated_annotationPosition.kt");
}
@TestMetadata("JavaLangDeprecated_expressionPosition.kt")
public void testJavaLangDeprecated_expressionPosition() throws Exception {
runTest("../../idea/tests/testData/editor/optimizeImports/jvm/JavaLangDeprecated_expressionPosition.kt");
}
@TestMetadata("JavaStaticField.kt")
public void testJavaStaticField() throws Exception {
runTest("../../idea/tests/testData/editor/optimizeImports/jvm/JavaStaticField.kt");
@@ -3,14 +3,23 @@
package org.jetbrains.kotlin.idea.imports
import com.intellij.testFramework.LightProjectDescriptor
import junit.framework.TestCase
import org.jetbrains.kotlin.AbstractImportsTest
import org.jetbrains.kotlin.idea.base.test.IgnoreTests
import org.jetbrains.kotlin.idea.test.KotlinStdJSProjectDescriptor
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.idea.base.test.InTextDirectivesUtils
abstract class AbstractOptimizeImportsTest : AbstractImportsTest() {
override fun doTest(unused: String) {
IgnoreTests.runTestIfNotDisabledByFileDirective(
dataFile().toPath(),
IgnoreTests.DIRECTIVES.IGNORE_K1,
".after",
test = { super.doTest(unused) }
)
}
override fun doTest(file: KtFile): String {
OptimizedImportsBuilder.testLog = StringBuilder()
try {
@@ -219,6 +219,16 @@ public abstract class JvmOptimizeImportsTestGenerated extends AbstractJvmOptimiz
runTest("testData/editor/optimizeImports/jvm/FromCompanionObjectGeneric.kt");
}
@TestMetadata("JavaLangDeprecated_annotationPosition.kt")
public void testJavaLangDeprecated_annotationPosition() throws Exception {
runTest("testData/editor/optimizeImports/jvm/JavaLangDeprecated_annotationPosition.kt");
}
@TestMetadata("JavaLangDeprecated_expressionPosition.kt")
public void testJavaLangDeprecated_expressionPosition() throws Exception {
runTest("testData/editor/optimizeImports/jvm/JavaLangDeprecated_expressionPosition.kt");
}
@TestMetadata("JavaStaticField.kt")
public void testJavaStaticField() throws Exception {
runTest("testData/editor/optimizeImports/jvm/JavaStaticField.kt");
@@ -0,0 +1,11 @@
package test
import java.lang.Deprecated
import kotlin.String
import kotlin.run
@Deprecated
fun test(): String {
return run { "" }
}
@@ -0,0 +1,8 @@
package test
import java.lang.Deprecated
@Deprecated
fun test(): String {
return run { "" }
}
@@ -0,0 +1,8 @@
Additional checking of reference Getter: run
Additional checking of reference KtSimpleNameReference: run
Additional checking of reference KtInvokeFunctionReference: run { "" }
Changed resolve type of KtSimpleNameReference: Deprecated
Trying to build import list again with import rules: +java.lang.Deprecated
Additional checking of reference Getter: run
Additional checking of reference KtSimpleNameReference: run
Additional checking of reference KtInvokeFunctionReference: run { "" }
@@ -0,0 +1,14 @@
// IGNORE_K1
// IGNORE_K2
// See KTIJ-32231
package test
import java.lang.Deprecated
import kotlin.String
import kotlin.run
fun test(): String {
Deprecated::class
return run { "" }
}
@@ -0,0 +1,11 @@
// IGNORE_K1
// IGNORE_K2
// See KTIJ-32231
package test
import java.lang.Deprecated
fun test(): String {
Deprecated::class
return run { "" }
}