mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
KTIJ-25346 [kotlin] Handle typealiased constructors in K2 Import Optimizer
Currently, due to KTIJ-26098, if the constructor is invoked via the typealias, the reference resolves directly to the constructed class, and not to the typealias. This prevented `UsedReferencesCollector` from properly recognizing such references. To handle this, we resolve the type explicitly when we see constructor calls by using code fragments. This works because type references work fine with typealiases (compared to constructor references). Also, add an explicit test for currently incorrect optimization of `kotlin.concurrent.Volatile` import. ^KTIJ-25346 Fixed GitOrigin-RevId: f531c00cba6d7e6687a45ae06aa9ac85a92262a3
This commit is contained in:
committed by
intellij-monorepo-bot
parent
03019cbc52
commit
c6391f929b
@@ -7,6 +7,8 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analysis.api.KaSession
|
||||
import org.jetbrains.kotlin.analysis.api.resolution.*
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaType
|
||||
import org.jetbrains.kotlin.analysis.api.types.symbol
|
||||
import org.jetbrains.kotlin.idea.references.KDocReference
|
||||
import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
@@ -123,7 +125,11 @@ internal class UsedReferencesCollector(private val file: KtFile) {
|
||||
(target as? KaNamedClassSymbol)?.containingSymbol
|
||||
}
|
||||
|
||||
target is KaConstructorSymbol -> target.containingSymbol
|
||||
target is KaConstructorSymbol -> {
|
||||
val targetClass = target.containingSymbol as? KaClassLikeSymbol
|
||||
|
||||
targetClass?.let { resolveTypeAliasedConstructorReference(reference, it) } ?: targetClass
|
||||
}
|
||||
|
||||
else -> target
|
||||
}
|
||||
@@ -160,6 +166,35 @@ internal class UsedReferencesCollector(private val file: KtFile) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a [reference] pointing to a typealiased constructor call like `FooAlias()`,
|
||||
* and [expandedClassSymbol] pointing to the expanded class `Foo`.
|
||||
*
|
||||
* Returns a `FooAlias` typealias symbol if it is resolvable at this position, and `null` otherwise.
|
||||
*
|
||||
* This is a workaround function until KTIJ-26098 is fixed.
|
||||
*/
|
||||
private fun KaSession.resolveTypeAliasedConstructorReference(
|
||||
reference: KtReference,
|
||||
expandedClassSymbol: KaClassLikeSymbol,
|
||||
): KaClassLikeSymbol? {
|
||||
val referencedType = resolveReferencedType(reference) ?: return null
|
||||
if (referencedType.symbol != expandedClassSymbol) return null
|
||||
|
||||
val typealiasType = referencedType.abbreviation ?: return null
|
||||
|
||||
return typealiasType.symbol
|
||||
}
|
||||
|
||||
private fun KaSession.resolveReferencedType(reference: KtReference): KaType? {
|
||||
val originalReferenceName = reference.resolvesByNames.singleOrNull() ?: return null
|
||||
|
||||
val psiFactory = KtPsiFactory.contextual(reference.element)
|
||||
val psiType = psiFactory.createTypeCodeFragment(originalReferenceName.asString(), context = reference.element).getContentElement()
|
||||
|
||||
return psiType?.type
|
||||
}
|
||||
|
||||
private fun collectImportAliases(file: KtFile): Map<FqName, List<Name>> = if (file.hasImportAlias()) {
|
||||
file.importDirectives
|
||||
.asSequence()
|
||||
|
||||
@@ -284,6 +284,11 @@ public abstract class FirJvmOptimizeImportsTestGenerated extends AbstractFirJvmO
|
||||
runTest("../../idea/tests/testData/editor/optimizeImports/jvm/TypeAliasVsUnderlyingClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasedConstructor_annotation_volatile.kt")
|
||||
public void testTypeAliasedConstructor_annotation_volatile() throws Exception {
|
||||
runTest("../../idea/tests/testData/editor/optimizeImports/jvm/TypeAliasedConstructor_annotation_volatile.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UnusedImports.kt")
|
||||
public void testUnusedImports() throws Exception {
|
||||
runTest("../../idea/tests/testData/editor/optimizeImports/jvm/UnusedImports.kt");
|
||||
@@ -779,6 +784,21 @@ public abstract class FirJvmOptimizeImportsTestGenerated extends AbstractFirJvmO
|
||||
runTest("../../idea/tests/testData/editor/optimizeImports/common/TwoConstructors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasedConstructor.kt")
|
||||
public void testTypeAliasedConstructor() throws Exception {
|
||||
runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasedConstructor_annotation.kt")
|
||||
public void testTypeAliasedConstructor_annotation() throws Exception {
|
||||
runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_annotation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasedConstructor_sameName.kt")
|
||||
public void testTypeAliasedConstructor_sameName() throws Exception {
|
||||
runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_sameName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UnresolvedImport.kt")
|
||||
public void testUnresolvedImport() throws Exception {
|
||||
runTest("../../idea/tests/testData/editor/optimizeImports/common/UnresolvedImport.kt");
|
||||
|
||||
@@ -521,6 +521,21 @@ public abstract class JsOptimizeImportsTestGenerated extends AbstractJsOptimizeI
|
||||
runTest("testData/editor/optimizeImports/common/TwoConstructors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasedConstructor.kt")
|
||||
public void testTypeAliasedConstructor() throws Exception {
|
||||
runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasedConstructor_annotation.kt")
|
||||
public void testTypeAliasedConstructor_annotation() throws Exception {
|
||||
runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_annotation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasedConstructor_sameName.kt")
|
||||
public void testTypeAliasedConstructor_sameName() throws Exception {
|
||||
runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_sameName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UnresolvedImport.kt")
|
||||
public void testUnresolvedImport() throws Exception {
|
||||
runTest("testData/editor/optimizeImports/common/UnresolvedImport.kt");
|
||||
|
||||
@@ -284,6 +284,11 @@ public abstract class JvmOptimizeImportsTestGenerated extends AbstractJvmOptimiz
|
||||
runTest("testData/editor/optimizeImports/jvm/TypeAliasVsUnderlyingClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasedConstructor_annotation_volatile.kt")
|
||||
public void testTypeAliasedConstructor_annotation_volatile() throws Exception {
|
||||
runTest("testData/editor/optimizeImports/jvm/TypeAliasedConstructor_annotation_volatile.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UnusedImports.kt")
|
||||
public void testUnusedImports() throws Exception {
|
||||
runTest("testData/editor/optimizeImports/jvm/UnusedImports.kt");
|
||||
@@ -784,6 +789,21 @@ public abstract class JvmOptimizeImportsTestGenerated extends AbstractJvmOptimiz
|
||||
runTest("testData/editor/optimizeImports/common/TwoConstructors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasedConstructor.kt")
|
||||
public void testTypeAliasedConstructor() throws Exception {
|
||||
runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasedConstructor_annotation.kt")
|
||||
public void testTypeAliasedConstructor_annotation() throws Exception {
|
||||
runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_annotation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAliasedConstructor_sameName.kt")
|
||||
public void testTypeAliasedConstructor_sameName() throws Exception {
|
||||
runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_sameName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UnresolvedImport.kt")
|
||||
public void testUnresolvedImport() throws Exception {
|
||||
runTest("testData/editor/optimizeImports/common/UnresolvedImport.kt");
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package dependency
|
||||
|
||||
class Foo
|
||||
|
||||
typealias TypeAliasedFoo = Foo
|
||||
@@ -0,0 +1,8 @@
|
||||
package test
|
||||
|
||||
import dependency.Foo
|
||||
import dependency.TypeAliasedFoo
|
||||
|
||||
fun usage() {
|
||||
TypeAliasedFoo()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
import dependency.TypeAliasedFoo
|
||||
|
||||
fun usage() {
|
||||
TypeAliasedFoo()
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package dependency
|
||||
|
||||
annotation class Foo
|
||||
|
||||
typealias TypeAliasedFoo = Foo
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
import dependency.Foo
|
||||
import dependency.TypeAliasedFoo
|
||||
|
||||
@TypeAliasedFoo
|
||||
fun usage() {}
|
||||
@@ -0,0 +1,6 @@
|
||||
package test
|
||||
|
||||
import dependency.TypeAliasedFoo
|
||||
|
||||
@TypeAliasedFoo
|
||||
fun usage() {}
|
||||
@@ -0,0 +1,3 @@
|
||||
package dependency1
|
||||
|
||||
typealias Foo = dependency2.Foo
|
||||
@@ -0,0 +1,3 @@
|
||||
package dependency2
|
||||
|
||||
class Foo
|
||||
@@ -0,0 +1,8 @@
|
||||
package test
|
||||
|
||||
import dependency1.Foo
|
||||
import dependency2.*
|
||||
|
||||
fun usage() {
|
||||
Foo()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
import dependency1.Foo
|
||||
|
||||
fun usage() {
|
||||
Foo()
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
Additional checking of reference Getter: Foo
|
||||
Additional checking of reference KtSimpleNameReference: Foo
|
||||
Additional checking of reference KtInvokeFunctionReference: Foo()
|
||||
@@ -0,0 +1,9 @@
|
||||
// IGNORE_K2
|
||||
package test
|
||||
|
||||
import kotlin.concurrent.Volatile
|
||||
|
||||
class Foo {
|
||||
@Volatile
|
||||
var property: Int = 10
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// IGNORE_K2
|
||||
package test
|
||||
|
||||
import kotlin.concurrent.Volatile
|
||||
|
||||
class Foo {
|
||||
@Volatile
|
||||
var property: Int = 10
|
||||
}
|
||||
Reference in New Issue
Block a user