[FIR] Move type parameter scope above member and static scopes in tower
This fixes a false positive TYPE_PARAMETER_IS_NOT_AN_EXPRESSION when a type parameter and some member, static or companion declaration have the same name and referred to inside a class. #KT-58028 Fixed
This commit is contained in:
committed by
Space Team
parent
7958a9debd
commit
bd9f36ad01
+6
@@ -26478,6 +26478,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionPropertyAndTypeParameter.kt")
|
||||
public void testCompanionPropertyAndTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("constructorVsCompanion.kt")
|
||||
public void testConstructorVsCompanion() throws Exception {
|
||||
|
||||
+6
@@ -26478,6 +26478,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionPropertyAndTypeParameter.kt")
|
||||
public void testCompanionPropertyAndTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("constructorVsCompanion.kt")
|
||||
public void testConstructorVsCompanion() throws Exception {
|
||||
|
||||
+6
@@ -26478,6 +26478,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionPropertyAndTypeParameter.kt")
|
||||
public void testCompanionPropertyAndTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("constructorVsCompanion.kt")
|
||||
public void testConstructorVsCompanion() throws Exception {
|
||||
|
||||
+6
@@ -26490,6 +26490,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionPropertyAndTypeParameter.kt")
|
||||
public void testCompanionPropertyAndTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("constructorVsCompanion.kt")
|
||||
public void testConstructorVsCompanion() throws Exception {
|
||||
|
||||
+32
-23
@@ -424,36 +424,45 @@ class BodyResolveContext(
|
||||
val towerElementsForClass = holder.collectTowerDataElementsForClass(owner, type)
|
||||
|
||||
val base = towerDataContext.addNonLocalTowerDataElements(towerElementsForClass.superClassesStaticsAndCompanionReceivers)
|
||||
val statics = base
|
||||
.addNonLocalScopeIfNotNull(towerElementsForClass.companionStaticScope)
|
||||
.addNonLocalScopeIfNotNull(towerElementsForClass.staticScope)
|
||||
|
||||
val companionReceiver = towerElementsForClass.companionReceiver
|
||||
val staticsAndCompanion = if (companionReceiver == null) statics else base
|
||||
.addReceiver(null, companionReceiver)
|
||||
.addNonLocalScopeIfNotNull(towerElementsForClass.companionStaticScope)
|
||||
.addNonLocalScopeIfNotNull(towerElementsForClass.staticScope)
|
||||
val statics = base
|
||||
.addNonLocalScopesIfNotNull(towerElementsForClass.companionStaticScope, towerElementsForClass.staticScope)
|
||||
|
||||
val staticsAndCompanion = when (val companionReceiver = towerElementsForClass.companionReceiver) {
|
||||
null -> statics
|
||||
else -> base
|
||||
.addReceiver(null, companionReceiver)
|
||||
.addNonLocalScopesIfNotNull(towerElementsForClass.companionStaticScope, towerElementsForClass.staticScope)
|
||||
}
|
||||
|
||||
val typeParameterScope = (owner as? FirRegularClass)?.typeParameterScope()
|
||||
|
||||
val forMembersResolution =
|
||||
// Type parameters must be inserted before all of staticsAndCompanion.
|
||||
// Optimization: Only rebuild all of staticsAndCompanion that's below type parameters if there are any type parameters.
|
||||
// Otherwise, reuse staticsAndCompanion.
|
||||
val forConstructorHeader = if (typeParameterScope != null) {
|
||||
towerDataContext
|
||||
.addNonLocalScope(typeParameterScope)
|
||||
.addNonLocalTowerDataElements(towerElementsForClass.superClassesStaticsAndCompanionReceivers)
|
||||
.run { towerElementsForClass.companionReceiver?.let { addReceiver(null, it) } ?: this }
|
||||
.addNonLocalScopesIfNotNull(towerElementsForClass.companionStaticScope, towerElementsForClass.staticScope)
|
||||
} else {
|
||||
staticsAndCompanion
|
||||
.addReceiver(labelName, towerElementsForClass.thisReceiver)
|
||||
.addContextReceiverGroup(towerElementsForClass.contextReceivers)
|
||||
.addNonLocalScopeIfNotNull(typeParameterScope)
|
||||
}
|
||||
|
||||
val scopeForConstructorHeader =
|
||||
staticsAndCompanion.addNonLocalScopeIfNotNull(typeParameterScope)
|
||||
val forMembersResolution = forConstructorHeader
|
||||
.addReceiver(labelName, towerElementsForClass.thisReceiver)
|
||||
.addContextReceiverGroup(towerElementsForClass.contextReceivers)
|
||||
|
||||
/*
|
||||
* Scope for enum entries is equal to initial scope for constructor header
|
||||
*
|
||||
* The only difference that we add value parameters to local scope for constructors
|
||||
* The only difference is that we add value parameters to local scope for constructors
|
||||
* and should not do this for enum entries
|
||||
*/
|
||||
|
||||
@Suppress("UnnecessaryVariable")
|
||||
val scopeForEnumEntries = scopeForConstructorHeader
|
||||
val scopeForEnumEntries = forConstructorHeader
|
||||
|
||||
val newTowerDataContextForStaticNestedClasses =
|
||||
if ((owner as? FirRegularClass)?.classKind?.isSingleton == true)
|
||||
@@ -470,14 +479,14 @@ class BodyResolveContext(
|
||||
}
|
||||
|
||||
val newContexts = FirRegularTowerDataContexts(
|
||||
forMembersResolution,
|
||||
regular = forMembersResolution,
|
||||
forClassHeaderAnnotations = base,
|
||||
newTowerDataContextForStaticNestedClasses,
|
||||
statics,
|
||||
scopeForConstructorHeader,
|
||||
scopeForEnumEntries,
|
||||
primaryConstructorPureParametersScope,
|
||||
primaryConstructorAllParametersScope
|
||||
forNestedClasses = newTowerDataContextForStaticNestedClasses,
|
||||
forCompanionObject = statics,
|
||||
forConstructorHeaders = forConstructorHeader,
|
||||
forEnumEntries = scopeForEnumEntries,
|
||||
primaryConstructorPureParametersScope = primaryConstructorPureParametersScope,
|
||||
primaryConstructorAllParametersScope = primaryConstructorAllParametersScope
|
||||
)
|
||||
|
||||
return withTowerDataContexts(newContexts) {
|
||||
|
||||
+24
@@ -202,6 +202,21 @@ class FirTowerDataContext private constructor(
|
||||
return addNonLocalScope(scope)
|
||||
}
|
||||
|
||||
// Optimized version for two parameters
|
||||
fun addNonLocalScopesIfNotNull(scope1: FirScope?, scope2: FirScope?): FirTowerDataContext {
|
||||
return if (scope1 != null) {
|
||||
if (scope2 != null) {
|
||||
addNonLocalScopeElements(listOf(scope1.asTowerDataElement(isLocal = false), scope2.asTowerDataElement(isLocal = false)))
|
||||
} else {
|
||||
addNonLocalScope(scope1)
|
||||
}
|
||||
} else if (scope2 != null) {
|
||||
addNonLocalScope(scope2)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
fun addNonLocalScope(scope: FirScope): FirTowerDataContext {
|
||||
val element = scope.asTowerDataElement(isLocal = false)
|
||||
return FirTowerDataContext(
|
||||
@@ -212,6 +227,15 @@ class FirTowerDataContext private constructor(
|
||||
)
|
||||
}
|
||||
|
||||
private fun addNonLocalScopeElements(elements: List<FirTowerDataElement>): FirTowerDataContext {
|
||||
return FirTowerDataContext(
|
||||
towerDataElements.addAll(elements),
|
||||
implicitReceiverStack,
|
||||
localScopes,
|
||||
nonLocalTowerDataElements.addAll(elements)
|
||||
)
|
||||
}
|
||||
|
||||
fun createSnapshot(): FirTowerDataContext {
|
||||
return FirTowerDataContext(
|
||||
towerDataElements.map(FirTowerDataElement::createSnapshot).toPersistentList(),
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// FIR_IDENTICAL
|
||||
// DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
open class Base(any: Any) {
|
||||
companion object {
|
||||
val test = 42L
|
||||
}
|
||||
}
|
||||
|
||||
class C1<test> : Base(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>test<!>) {
|
||||
companion object {
|
||||
val test = 12
|
||||
val some: Int = test
|
||||
}
|
||||
|
||||
val test = ""
|
||||
val some: String = test
|
||||
|
||||
fun f() {
|
||||
val test = 1.0
|
||||
val some: Double = test
|
||||
}
|
||||
}
|
||||
|
||||
class C2<test> : Base(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>test<!>) {
|
||||
companion object {
|
||||
val test = 12
|
||||
val some: Int = test
|
||||
}
|
||||
|
||||
val some: Int = test
|
||||
|
||||
fun f() {
|
||||
val test = 1.0
|
||||
val some: Double = test
|
||||
}
|
||||
}
|
||||
|
||||
class C3<test> : Base(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Long")!>test<!>) {
|
||||
val some: Long = test
|
||||
|
||||
fun f() {
|
||||
val test = 1.0
|
||||
val some: Double = test
|
||||
}
|
||||
}
|
||||
|
||||
class C4<test> {
|
||||
val some = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>test<!>
|
||||
|
||||
fun f() {
|
||||
val some = <!TYPE_PARAMETER_IS_NOT_AN_EXPRESSION!>test<!>
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
//ALLOW_AST_ACCESS
|
||||
// IGNORE_FIR_METADATA_LOADING_K2
|
||||
// Ignore reason: KT-58028
|
||||
package test
|
||||
|
||||
class ConstructorTypeParamClassObjectTypeConflict<test> {
|
||||
|
||||
Generated
+6
@@ -27262,6 +27262,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionPropertyAndTypeParameter.kt")
|
||||
public void testCompanionPropertyAndTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("constructorVsCompanion.kt")
|
||||
public void testConstructorVsCompanion() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user