[K2] Include Type Aliases in targets when resolving constructors

Refactoring and UX relies on type aliases being included in the result
when resolving constructor invocations.

This commit introduces a "fix-up" that checks whether a constructor
invocation _also_ matches a type declaration. If that declaration is
an alias, we inject that symbol into the resolution result.
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirSimpleNameReference.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirSimpleNameReference.kt
index 2261fcf..3803fbd 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirSimpleNameReference.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirSimpleNameReference.kt
@@ -7,11 +7,16 @@
 
 import com.intellij.psi.PsiElement
 import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
+import org.jetbrains.kotlin.analysis.api.components.buildClassType
 import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
+import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirConstructorSymbol
 import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirNamedClassOrObjectSymbol
 import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSyntheticJavaPropertySymbol
+import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirTypeAliasSymbol
 import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
 import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
+import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
+import org.jetbrains.kotlin.name.ClassId
 import org.jetbrains.kotlin.psi.*
 
 internal class KtFirSimpleNameReference(
@@ -27,6 +32,10 @@
             return ktConstructorCalleeExpression.parent is KtAnnotationEntry
         }
 
+    /**
+     * This fix-up needed to resolve annotation call into annotation
+     * constructor (but not into the annotation type).
+     */
     private fun KtAnalysisSession.fixUpAnnotationCallResolveToCtor(resultsToFix: Collection<KtSymbol>): Collection<KtSymbol> {
         if (resultsToFix.isEmpty() || !isAnnotationCall) return resultsToFix
 
@@ -37,11 +46,37 @@
         }
     }
 
+    /**
+     * This pass introduces additional symbols into the resolution result for
+     * constructor invocations that resolve via a type-alias. The type-alias
+     * needs to be included in the resolution result in order to support
+     * refactorings that rely on resolution (e.g. to find rename targets).
+     *
+     * We take the _name_ of the constructor, and attempt to resolve it as a
+     * type. If the declaration of that type is an alias, we include it in the
+     * result.
+     */
+    private fun KtAnalysisSession.includeTypeAliasesForConstructorCalls(resultsToFix: Collection<KtSymbol>): Collection<KtSymbol> {
+        return resultsToFix.flatMap { targetSymbol ->
+            if (targetSymbol !is KtFirConstructorSymbol) return@flatMap listOf(targetSymbol)
+            val name = expression.getReferencedName()
+            val fakeType = ClassId.fromString(name)
+            val classType = buildClassType(fakeType)
+            if (classType !is KtNonErrorClassType) return@flatMap listOf(targetSymbol)
+            if (classType.classSymbol is KtFirTypeAliasSymbol) {
+                return@flatMap listOf(targetSymbol, classType.classSymbol)
+            } else {
+                return@flatMap listOf(targetSymbol)
+            }
+        }
+    }
+
     override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
         check(this is KtFirAnalysisSession)
-        val results = FirReferenceResolveHelper.resolveSimpleNameReference(this@KtFirSimpleNameReference, this)
-        //This fix-up needed to resolve annotation call into annotation constructor (but not into the annotation type)
-        return fixUpAnnotationCallResolveToCtor(results)
+        var results = FirReferenceResolveHelper.resolveSimpleNameReference(this@KtFirSimpleNameReference, this)
+        results = fixUpAnnotationCallResolveToCtor(results)
+        results = includeTypeAliasesForConstructorCalls(results)
+        return results
     }
 
     override fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection<PsiElement> = with(analysisSession) {
diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSymbolByReferenceTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSymbolByReferenceTestGenerated.java
index 2eeb28f..48388e6 100644
--- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSymbolByReferenceTestGenerated.java
+++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSymbolByReferenceTestGenerated.java
@@ -53,6 +53,18 @@
     }
 
     @Test
+    @TestMetadata("chainOfTypeAliasesBottom.kt")
+    public void testChainOfTypeAliasesBottom() throws Exception {
+        runTest("analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesBottom.kt");
+    }
+
+    @Test
+    @TestMetadata("chainOfTypeAliasesTop.kt")
+    public void testChainOfTypeAliasesTop() throws Exception {
+        runTest("analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesTop.kt");
+    }
+
+    @Test
     @TestMetadata("constructorViaTypeAlias.kt")
     public void testConstructorViaTypeAlias() throws Exception {
         runTest("analysis/analysis-api/testData/symbols/symbolByReference/constructorViaTypeAlias.kt");
diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolByReferenceTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolByReferenceTest.kt
index 5d7c9eb..3c507db 100644
--- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolByReferenceTest.kt
+++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolByReferenceTest.kt
@@ -16,7 +16,7 @@
     override fun KtAnalysisSession.collectSymbols(ktFile: KtFile, testServices: TestServices): SymbolsData {
         val referenceExpression = testServices.expressionMarkerProvider.getElementOfTypeAtCaret<KtNameReferenceExpression>(ktFile)
         return SymbolsData(
-            listOfNotNull(referenceExpression.mainReference.resolveToSymbol())
+            referenceExpression.mainReference.resolveToSymbols().toList()
         )
     }
 }
\ No newline at end of file
diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSymbolByReferenceTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSymbolByReferenceTestGenerated.java
index 55e0485..624ecb0 100644
--- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSymbolByReferenceTestGenerated.java
+++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSymbolByReferenceTestGenerated.java
@@ -53,6 +53,18 @@
     }
 
     @Test
+    @TestMetadata("chainOfTypeAliasesBottom.kt")
+    public void testChainOfTypeAliasesBottom() throws Exception {
+        runTest("analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesBottom.kt");
+    }
+
+    @Test
+    @TestMetadata("chainOfTypeAliasesTop.kt")
+    public void testChainOfTypeAliasesTop() throws Exception {
+        runTest("analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesTop.kt");
+    }
+
+    @Test
     @TestMetadata("constructorViaTypeAlias.kt")
     public void testConstructorViaTypeAlias() throws Exception {
         runTest("analysis/analysis-api/testData/symbols/symbolByReference/constructorViaTypeAlias.kt");
diff --git a/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesBottom.kt b/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesBottom.kt
new file mode 100644
index 0000000..bb83a68
--- /dev/null
+++ b/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesBottom.kt
@@ -0,0 +1,10 @@
+// DO_NOT_CHECK_SYMBOL_RESTORE
+
+class A
+typealias B = A
+typealias C = B
+typealias D = C
+
+fun x() {
+    val a = <caret>D()
+}
diff --git a/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesBottom.pretty.txt b/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesBottom.pretty.txt
new file mode 100644
index 0000000..ea227f7
--- /dev/null
+++ b/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesBottom.pretty.txt
@@ -0,0 +1,3 @@
+constructor()
+
+typealias D = C
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesBottom.txt b/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesBottom.txt
new file mode 100644
index 0000000..958e849
--- /dev/null
+++ b/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesBottom.txt
@@ -0,0 +1,29 @@
+KtConstructorSymbol:
+  annotationsList: []
+  callableIdIfNonLocal: null
+  containingClassIdIfNonLocal: A
+  contextReceivers: []
+  hasStableParameterNames: true
+  isExtension: false
+  isPrimary: true
+  origin: SOURCE_MEMBER_GENERATED
+  receiverType: null
+  returnType: A
+  symbolKind: CLASS_MEMBER
+  typeParameters: []
+  valueParameters: []
+  visibility: Public
+  getContainingModule: KtSourceModule "Sources of main"
+  deprecationStatus: null
+
+KtTypeAliasSymbol:
+  annotationsList: []
+  classIdIfNonLocal: D
+  expandedType: C
+  name: D
+  origin: SOURCE
+  symbolKind: TOP_LEVEL
+  typeParameters: []
+  visibility: Public
+  getContainingModule: KtSourceModule "Sources of main"
+  deprecationStatus: null
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesTop.kt b/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesTop.kt
new file mode 100644
index 0000000..d7214e0
--- /dev/null
+++ b/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesTop.kt
@@ -0,0 +1,10 @@
+// DO_NOT_CHECK_SYMBOL_RESTORE
+
+class A
+typealias B = A
+typealias C = B
+typealias D = C
+
+fun x() {
+    val a = <caret>B()
+}
diff --git a/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesTop.pretty.txt b/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesTop.pretty.txt
new file mode 100644
index 0000000..81682ee
--- /dev/null
+++ b/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesTop.pretty.txt
@@ -0,0 +1,3 @@
+constructor()
+
+typealias B = A
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesTop.txt b/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesTop.txt
new file mode 100644
index 0000000..29f165b
--- /dev/null
+++ b/analysis/analysis-api/testData/symbols/symbolByReference/chainOfTypeAliasesTop.txt
@@ -0,0 +1,29 @@
+KtConstructorSymbol:
+  annotationsList: []
+  callableIdIfNonLocal: null
+  containingClassIdIfNonLocal: A
+  contextReceivers: []
+  hasStableParameterNames: true
+  isExtension: false
+  isPrimary: true
+  origin: SOURCE_MEMBER_GENERATED
+  receiverType: null
+  returnType: A
+  symbolKind: CLASS_MEMBER
+  typeParameters: []
+  valueParameters: []
+  visibility: Public
+  getContainingModule: KtSourceModule "Sources of main"
+  deprecationStatus: null
+
+KtTypeAliasSymbol:
+  annotationsList: []
+  classIdIfNonLocal: B
+  expandedType: A
+  name: B
+  origin: SOURCE
+  symbolKind: TOP_LEVEL
+  typeParameters: []
+  visibility: Public
+  getContainingModule: KtSourceModule "Sources of main"
+  deprecationStatus: null
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/symbols/symbolByReference/constructorViaTypeAlias.pretty.txt b/analysis/analysis-api/testData/symbols/symbolByReference/constructorViaTypeAlias.pretty.txt
index 20cbaa6..ee5d07f 100644
--- a/analysis/analysis-api/testData/symbols/symbolByReference/constructorViaTypeAlias.pretty.txt
+++ b/analysis/analysis-api/testData/symbols/symbolByReference/constructorViaTypeAlias.pretty.txt
@@ -1 +1,4 @@
 constructor(c: kotlin.collections.(Mutable)Collection<out (E!!..E?)>!)
+
+@kotlin.SinceKotlin(version = "1.1")
+typealias ArrayList<E> = java.util.ArrayList<E>
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/symbols/symbolByReference/constructorViaTypeAlias.txt b/analysis/analysis-api/testData/symbols/symbolByReference/constructorViaTypeAlias.txt
index 146b0c0..0851407 100644
--- a/analysis/analysis-api/testData/symbols/symbolByReference/constructorViaTypeAlias.txt
+++ b/analysis/analysis-api/testData/symbols/symbolByReference/constructorViaTypeAlias.txt
@@ -18,4 +18,21 @@
   ]
   visibility: Public
   getContainingModule: KtSdkModule "SDK jdk"
+  deprecationStatus: null
+
+KtTypeAliasSymbol:
+  annotationsList: [
+    kotlin/SinceKotlin(version = "1.1")
+      psi: null
+  ]
+  classIdIfNonLocal: kotlin/collections/ArrayList
+  expandedType: java/util/ArrayList<E>
+  name: ArrayList
+  origin: LIBRARY
+  symbolKind: TOP_LEVEL
+  typeParameters: [
+    KtTypeParameterSymbol(E)
+  ]
+  visibility: Public
+  getContainingModule: KtLibraryModule "Library kotlin-stdlib"
   deprecationStatus: null
\ No newline at end of file