diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt index 1ae417ca44d..a7ee3388e69 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt @@ -23,8 +23,6 @@ import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeImpl import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.compose -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName open class FirTypeResolveTransformer : FirTransformer() { override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { @@ -33,8 +31,6 @@ open class FirTypeResolveTransformer : FirTransformer() { } lateinit var scope: FirCompositeScope - lateinit var packageFqName: FqName - private var classLikeName: FqName = FqName.ROOT override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult { scope = FirCompositeScope( @@ -46,7 +42,6 @@ open class FirTypeResolveTransformer : FirTransformer() { FirDefaultStarImportingScope(file.session) ) ) - packageFqName = file.packageFqName return super.transformFile(file, data) } @@ -64,65 +59,74 @@ open class FirTypeResolveTransformer : FirTransformer() { } override fun transformClass(klass: FirClass, data: Nothing?): CompositeTransformResult { - classLikeName = classLikeName.child(klass.name) - val classId = ClassId(packageFqName, classLikeName, false) - scope = FirCompositeScope(mutableListOf(scope)) - scope.scopes += FirClassLikeTypeParameterScope(klass) - resolveSuperTypesAndExpansions(klass) + return withScopeCleanup { + klass.withTypeParametersScope { + resolveSuperTypesAndExpansions(klass) + val firProvider = FirProvider.getInstance(klass.session) + val classId = klass.symbol.classId + scope.scopes += FirNestedClassifierScope(classId, firProvider) + val companionObjects = klass.declarations.filterIsInstance().filter { it.isCompanion } + for (companionObject in companionObjects) { + scope.scopes += FirNestedClassifierScope(companionObject.symbol.classId, firProvider) + } - val firProvider = FirProvider.getInstance(klass.session) - scope.scopes += FirNestedClassifierScope(classId, firProvider) - val companionObjects = klass.declarations.filterIsInstance().filter { it.isCompanion } - for (companionObject in companionObjects) { - val companionId = ClassId(packageFqName, classLikeName.child(companionObject.name), false) - scope.scopes += FirNestedClassifierScope(companionId, firProvider) - } - - val superTypeScopes = lookupSuperTypes(klass).map { - val symbol = it.symbol - if (symbol is FirBasedSymbol<*>) { - FirNestedClassifierScope(symbol.classId, FirProvider.getInstance(symbol.fir.session)) - } else { - FirNestedClassifierScope(symbol.classId, FirSymbolProvider.getInstance(klass.session)) + lookupSuperTypes(klass).mapTo(scope.scopes) { + val symbol = it.symbol + if (symbol is FirBasedSymbol<*>) { + FirNestedClassifierScope(symbol.classId, FirProvider.getInstance(symbol.fir.session)) + } else { + FirNestedClassifierScope(symbol.classId, FirSymbolProvider.getInstance(klass.session)) + } + } + super.transformClass(klass, data) } } - scope.scopes.addAll(superTypeScopes) - val result = super.transformClass(klass, data) - scope = scope.scopes[0] as FirCompositeScope - classLikeName = classLikeName.parent() - - return result } override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Nothing?): CompositeTransformResult { - classLikeName = classLikeName.child(typeAlias.name) - if (typeAlias.typeParameters.isNotEmpty()) { - scope = FirCompositeScope(mutableListOf(scope)) - scope.scopes += FirClassLikeTypeParameterScope(typeAlias) + // TODO: Remove comment when KT-23742 fixed + // Warning: boxing inline class here () + return typeAlias.withTypeParametersScope { + resolveSuperTypesAndExpansions(typeAlias) + super.transformTypeAlias(typeAlias, data) } + } - resolveSuperTypesAndExpansions(typeAlias) - if (typeAlias.typeParameters.isNotEmpty()) { - scope = scope.scopes[0] as FirCompositeScope + private inline fun FirMemberDeclaration.withTypeParametersScope(crossinline l: () -> T): T { + val scopes = scope.scopes + if (typeParameters.isNotEmpty()) { + scopes += FirMemberTypeParameterScope(this) + } + val result = l() + if (typeParameters.isNotEmpty()) { + scopes.removeAt(scopes.lastIndex) + } + return result + } + + private inline fun withScopeCleanup(crossinline l: () -> T): T { + val scopeBefore = scope + val scopes = scope.scopes + val sizeBefore = scopes.size + val result = l() + scope = scopeBefore + assert(scopes.size >= sizeBefore) + scopes.subList(sizeBefore + 1, scopes.size).clear() + return result + } + + override fun transformProperty(property: FirProperty, data: Nothing?): CompositeTransformResult { + return property.withTypeParametersScope { + super.transformProperty(property, data) } - classLikeName = classLikeName.parent() - return super.transformTypeAlias(typeAlias, data) } override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Nothing?): CompositeTransformResult { - if (namedFunction.typeParameters.isNotEmpty()) { - scope = FirCompositeScope(mutableListOf(scope)) - scope.scopes += FirFunctionTypeParameterScope(namedFunction) + return namedFunction.withTypeParametersScope { + super.transformNamedFunction(namedFunction, data) } - - val result = super.transformNamedFunction(namedFunction, data) - if (namedFunction.typeParameters.isNotEmpty()) { - scope = scope.scopes[0] as FirCompositeScope - } - - return result } override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirFunctionTypeParameterScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirFunctionTypeParameterScope.kt deleted file mode 100644 index 5a371913512..00000000000 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirFunctionTypeParameterScope.kt +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license - * that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.fir.scopes.impl - -import org.jetbrains.kotlin.fir.declarations.FirNamedFunction -import org.jetbrains.kotlin.fir.scopes.FirTypeParameterScope - -class FirFunctionTypeParameterScope(function: FirNamedFunction) : FirTypeParameterScope { - override val typeParameters = function.typeParameters.groupBy { it.name } -} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassLikeTypeParameterScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirMemberTypeParameterScope.kt similarity index 65% rename from compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassLikeTypeParameterScope.kt rename to compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirMemberTypeParameterScope.kt index 018e709a513..8daa65c5110 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassLikeTypeParameterScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirMemberTypeParameterScope.kt @@ -8,6 +8,6 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.scopes.FirTypeParameterScope -class FirClassLikeTypeParameterScope(classLike: FirMemberDeclaration) : FirTypeParameterScope { - override val typeParameters = classLike.typeParameters.groupBy { it.name } +class FirMemberTypeParameterScope(callableMember: FirMemberDeclaration) : FirTypeParameterScope { + override val typeParameters = callableMember.typeParameters.groupBy { it.name } } \ No newline at end of file diff --git a/compiler/testData/fir/resolve/typeParameterInPropertyReceiver.kt b/compiler/testData/fir/resolve/typeParameterInPropertyReceiver.kt new file mode 100644 index 00000000000..5240fae691e --- /dev/null +++ b/compiler/testData/fir/resolve/typeParameterInPropertyReceiver.kt @@ -0,0 +1 @@ +val T.self: T get() = this diff --git a/compiler/testData/fir/resolve/typeParameterInPropertyReceiver.txt b/compiler/testData/fir/resolve/typeParameterInPropertyReceiver.txt new file mode 100644 index 00000000000..8d2b7fac2e4 --- /dev/null +++ b/compiler/testData/fir/resolve/typeParameterInPropertyReceiver.txt @@ -0,0 +1,5 @@ +FILE: typeParameterInPropertyReceiver.kt + public? final? property self R|T|.(val): R|T| + public? get(): R|error: Not supported: FirImplicitTypeImpl| { + STUB + } diff --git a/compiler/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java index 75194bbcf02..a0627911600 100644 --- a/compiler/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java @@ -104,6 +104,12 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase { runTest("compiler/testData/fir/resolve/typeAliasWithGeneric.kt"); } + @TestMetadata("typeParameterInPropertyReceiver.kt") + public void testTypeParameterInPropertyReceiver() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/typeParameterInPropertyReceiver.kt"); + doTest(fileName); + } + @TestMetadata("typeParameterVsNested.kt") public void testTypeParameterVsNested() throws Exception { runTest("compiler/testData/fir/resolve/typeParameterVsNested.kt");