[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");
|
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
|
@Test
|
||||||
@TestMetadata("constructorVsCompanion.kt")
|
@TestMetadata("constructorVsCompanion.kt")
|
||||||
public void testConstructorVsCompanion() throws Exception {
|
public void testConstructorVsCompanion() throws Exception {
|
||||||
|
|||||||
+6
@@ -26478,6 +26478,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
|||||||
runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt");
|
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
|
@Test
|
||||||
@TestMetadata("constructorVsCompanion.kt")
|
@TestMetadata("constructorVsCompanion.kt")
|
||||||
public void testConstructorVsCompanion() throws Exception {
|
public void testConstructorVsCompanion() throws Exception {
|
||||||
|
|||||||
+6
@@ -26478,6 +26478,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
|||||||
runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt");
|
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
|
@Test
|
||||||
@TestMetadata("constructorVsCompanion.kt")
|
@TestMetadata("constructorVsCompanion.kt")
|
||||||
public void testConstructorVsCompanion() throws Exception {
|
public void testConstructorVsCompanion() throws Exception {
|
||||||
|
|||||||
+6
@@ -26490,6 +26490,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt");
|
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
|
@Test
|
||||||
@TestMetadata("constructorVsCompanion.kt")
|
@TestMetadata("constructorVsCompanion.kt")
|
||||||
public void testConstructorVsCompanion() throws Exception {
|
public void testConstructorVsCompanion() throws Exception {
|
||||||
|
|||||||
+32
-23
@@ -424,36 +424,45 @@ class BodyResolveContext(
|
|||||||
val towerElementsForClass = holder.collectTowerDataElementsForClass(owner, type)
|
val towerElementsForClass = holder.collectTowerDataElementsForClass(owner, type)
|
||||||
|
|
||||||
val base = towerDataContext.addNonLocalTowerDataElements(towerElementsForClass.superClassesStaticsAndCompanionReceivers)
|
val base = towerDataContext.addNonLocalTowerDataElements(towerElementsForClass.superClassesStaticsAndCompanionReceivers)
|
||||||
val statics = base
|
|
||||||
.addNonLocalScopeIfNotNull(towerElementsForClass.companionStaticScope)
|
|
||||||
.addNonLocalScopeIfNotNull(towerElementsForClass.staticScope)
|
|
||||||
|
|
||||||
val companionReceiver = towerElementsForClass.companionReceiver
|
val statics = base
|
||||||
val staticsAndCompanion = if (companionReceiver == null) statics else base
|
.addNonLocalScopesIfNotNull(towerElementsForClass.companionStaticScope, towerElementsForClass.staticScope)
|
||||||
.addReceiver(null, companionReceiver)
|
|
||||||
.addNonLocalScopeIfNotNull(towerElementsForClass.companionStaticScope)
|
val staticsAndCompanion = when (val companionReceiver = towerElementsForClass.companionReceiver) {
|
||||||
.addNonLocalScopeIfNotNull(towerElementsForClass.staticScope)
|
null -> statics
|
||||||
|
else -> base
|
||||||
|
.addReceiver(null, companionReceiver)
|
||||||
|
.addNonLocalScopesIfNotNull(towerElementsForClass.companionStaticScope, towerElementsForClass.staticScope)
|
||||||
|
}
|
||||||
|
|
||||||
val typeParameterScope = (owner as? FirRegularClass)?.typeParameterScope()
|
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
|
staticsAndCompanion
|
||||||
.addReceiver(labelName, towerElementsForClass.thisReceiver)
|
}
|
||||||
.addContextReceiverGroup(towerElementsForClass.contextReceivers)
|
|
||||||
.addNonLocalScopeIfNotNull(typeParameterScope)
|
|
||||||
|
|
||||||
val scopeForConstructorHeader =
|
val forMembersResolution = forConstructorHeader
|
||||||
staticsAndCompanion.addNonLocalScopeIfNotNull(typeParameterScope)
|
.addReceiver(labelName, towerElementsForClass.thisReceiver)
|
||||||
|
.addContextReceiverGroup(towerElementsForClass.contextReceivers)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scope for enum entries is equal to initial scope for constructor header
|
* 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
|
* and should not do this for enum entries
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Suppress("UnnecessaryVariable")
|
@Suppress("UnnecessaryVariable")
|
||||||
val scopeForEnumEntries = scopeForConstructorHeader
|
val scopeForEnumEntries = forConstructorHeader
|
||||||
|
|
||||||
val newTowerDataContextForStaticNestedClasses =
|
val newTowerDataContextForStaticNestedClasses =
|
||||||
if ((owner as? FirRegularClass)?.classKind?.isSingleton == true)
|
if ((owner as? FirRegularClass)?.classKind?.isSingleton == true)
|
||||||
@@ -470,14 +479,14 @@ class BodyResolveContext(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val newContexts = FirRegularTowerDataContexts(
|
val newContexts = FirRegularTowerDataContexts(
|
||||||
forMembersResolution,
|
regular = forMembersResolution,
|
||||||
forClassHeaderAnnotations = base,
|
forClassHeaderAnnotations = base,
|
||||||
newTowerDataContextForStaticNestedClasses,
|
forNestedClasses = newTowerDataContextForStaticNestedClasses,
|
||||||
statics,
|
forCompanionObject = statics,
|
||||||
scopeForConstructorHeader,
|
forConstructorHeaders = forConstructorHeader,
|
||||||
scopeForEnumEntries,
|
forEnumEntries = scopeForEnumEntries,
|
||||||
primaryConstructorPureParametersScope,
|
primaryConstructorPureParametersScope = primaryConstructorPureParametersScope,
|
||||||
primaryConstructorAllParametersScope
|
primaryConstructorAllParametersScope = primaryConstructorAllParametersScope
|
||||||
)
|
)
|
||||||
|
|
||||||
return withTowerDataContexts(newContexts) {
|
return withTowerDataContexts(newContexts) {
|
||||||
|
|||||||
+24
@@ -202,6 +202,21 @@ class FirTowerDataContext private constructor(
|
|||||||
return addNonLocalScope(scope)
|
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 {
|
fun addNonLocalScope(scope: FirScope): FirTowerDataContext {
|
||||||
val element = scope.asTowerDataElement(isLocal = false)
|
val element = scope.asTowerDataElement(isLocal = false)
|
||||||
return FirTowerDataContext(
|
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 {
|
fun createSnapshot(): FirTowerDataContext {
|
||||||
return FirTowerDataContext(
|
return FirTowerDataContext(
|
||||||
towerDataElements.map(FirTowerDataElement::createSnapshot).toPersistentList(),
|
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
|
//ALLOW_AST_ACCESS
|
||||||
// IGNORE_FIR_METADATA_LOADING_K2
|
|
||||||
// Ignore reason: KT-58028
|
|
||||||
package test
|
package test
|
||||||
|
|
||||||
class ConstructorTypeParamClassObjectTypeConflict<test> {
|
class ConstructorTypeParamClassObjectTypeConflict<test> {
|
||||||
|
|||||||
Generated
+6
@@ -27262,6 +27262,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt");
|
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
|
@Test
|
||||||
@TestMetadata("constructorVsCompanion.kt")
|
@TestMetadata("constructorVsCompanion.kt")
|
||||||
public void testConstructorVsCompanion() throws Exception {
|
public void testConstructorVsCompanion() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user