From 25ae12fe0737e41659f2cc85e839463f76b34560 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Wed, 21 Mar 2018 18:30:28 +0300 Subject: [PATCH] FIR: implement early type alias expansion --- .../descriptors/FirTypeResolveTransformer.kt | 34 ++++++-- .../kotlin/fir/resolve/FirProvider.kt | 3 +- .../fir/resolve/FirQualifierResolver.kt | 5 +- .../kotlin/fir/resolve/FirTypeResolver.kt | 5 ++ .../fir/resolve/impl/FirProviderImpl.kt | 4 +- .../resolve/impl/FirQualifierResolverImpl.kt | 48 ++-------- .../fir/resolve/impl/FirTypeResolverImpl.kt | 87 ++++++++++++++++--- .../org/jetbrains/kotlin/fir/FirRenderer.kt | 2 + .../resolve/multifile/TypeAliasExpansion.1.kt | 7 ++ .../resolve/multifile/TypeAliasExpansion.kt | 7 ++ .../resolve/multifile/TypeAliasExpansion.txt | 3 + compiler/testData/fir/resolve/simpleClass.txt | 18 ++-- .../fir/resolve/typeAliasWithGeneric.kt | 4 +- .../fir/resolve/typeAliasWithGeneric.txt | 2 +- .../kotlin/fir/AbstractFirResolveTestCase.kt | 42 ++++++--- .../fir/FirResolveTestCaseGenerated.java | 6 ++ 16 files changed, 187 insertions(+), 90 deletions(-) create mode 100644 compiler/testData/fir/resolve/multifile/TypeAliasExpansion.1.kt create mode 100644 compiler/testData/fir/resolve/multifile/TypeAliasExpansion.kt create mode 100644 compiler/testData/fir/resolve/multifile/TypeAliasExpansion.txt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/descriptors/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/descriptors/FirTypeResolveTransformer.kt index e198ee52651..a773e9e6e5e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/descriptors/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/descriptors/FirTypeResolveTransformer.kt @@ -8,9 +8,12 @@ package org.jetbrains.kotlin.descriptors import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.FirProvider import org.jetbrains.kotlin.fir.resolve.FirTypeResolver import org.jetbrains.kotlin.fir.scopes.impl.* +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.ConeSymbol import org.jetbrains.kotlin.fir.transformSingle import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeImpl @@ -21,8 +24,6 @@ import org.jetbrains.kotlin.fir.visitors.compose import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName -fun FirElement.render(): String = buildString { this@render.accept(FirRenderer(this)) } - class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransformer() { override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { return if (superTypesOnly) { @@ -94,11 +95,15 @@ class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransf override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult { val typeResolver = FirTypeResolver.getInstance(type.session) - type.transformChildren(this, data) + type.transformChildren(this, null) + return transformType(type, typeResolver.resolveType(type, scope)) + } + + private fun transformType(type: FirType, resolvedType: ConeKotlinType): CompositeTransformResult { return FirResolvedTypeImpl( type.session, type.psi, - typeResolver.resolveType(type, scope), + resolvedType, false, type.annotations ).compose() @@ -109,16 +114,27 @@ class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransf } + override fun transformTypeProjectionWithVariance( + typeProjectionWithVariance: FirTypeProjectionWithVariance, + data: Nothing? + ): CompositeTransformResult { + typeProjectionWithVariance.transformChildren(this, data) + return typeProjectionWithVariance.compose() + } + private inner class SuperTypeResolver : FirTransformer() { override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { return element.compose() } override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult { - val transformedType = this@FirTypeResolveTransformer.transformType(type, data).single as FirResolvedType + val typeResolver = FirTypeResolver.getInstance(type.session) + val symbol = typeResolver.resolveToSymbol(type, scope) + val myTransformer = this@FirTypeResolveTransformer - val classId = (transformedType.type as? ConeClassLikeType)?.symbol?.classId ?: return transformedType.compose() - val firProvider = FirProvider.getInstance(transformedType.session) + if (type !is FirUserType) return myTransformer.transformType(type, data) + val classId = (symbol as? ConeClassLikeSymbol)?.classId ?: return myTransformer.transformType(type, data) + val firProvider = FirProvider.getInstance(type.session) val classes = generateSequence(classId) { it.outerClassId }.toList() @@ -132,7 +148,9 @@ class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransf firProvider.getFirClassifierByFqName(it)!!.transformSingle(transformer, data) } - return transformedType.compose() + + type.transformChildren(myTransformer, null) + return myTransformer.transformType(type, typeResolver.resolveUserType(type, symbol, scope)) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirProvider.kt index 1a812cd087c..16b8c120873 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirProvider.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration +import org.jetbrains.kotlin.fir.declarations.FirNamedDeclaration import org.jetbrains.kotlin.fir.service import org.jetbrains.kotlin.fir.symbols.ConeSymbol import org.jetbrains.kotlin.name.ClassId @@ -18,7 +19,7 @@ interface FirProvider { fun getFirClassifierContainerFile(fqName: ClassId): FirFile - fun getFirClassifierBySymbol(symbol: ConeSymbol): FirMemberDeclaration? + fun getFirClassifierBySymbol(symbol: ConeSymbol): FirNamedDeclaration? companion object { fun getInstance(session: FirSession): FirProvider = session.service() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirQualifierResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirQualifierResolver.kt index d4dd3708d29..c60b05e2adf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirQualifierResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirQualifierResolver.kt @@ -7,15 +7,16 @@ package org.jetbrains.kotlin.fir.resolve import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.service +import org.jetbrains.kotlin.fir.symbols.ConeSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirQualifierPart import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName interface FirQualifierResolver { - fun resolveTypeWithPrefix(parts: List, prefix: ClassId): ConeKotlinType? + fun resolveSymbolWithPrefix(parts: List, prefix: ClassId): ConeSymbol? - fun resolveType(parts: List): ConeKotlinType? + fun resolveSymbol(parts: List): ConeSymbol? companion object { fun getInstance(session: FirSession): FirQualifierResolver = session.service() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirTypeResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirTypeResolver.kt index a1a51618ab7..7ba080e9110 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirTypeResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirTypeResolver.kt @@ -8,14 +8,19 @@ package org.jetbrains.kotlin.fir.resolve import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.service +import org.jetbrains.kotlin.fir.symbols.ConeSymbol import org.jetbrains.kotlin.fir.types.FirType import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.FirUserType interface FirTypeResolver { fun resolveType(type: FirType, scope: FirScope): ConeKotlinType + fun resolveToSymbol(type: FirType, scope: FirScope): ConeSymbol? companion object { fun getInstance(session: FirSession): FirTypeResolver = session.service() } + + fun resolveUserType(type: FirUserType, symbol: ConeSymbol?, scope: FirScope): ConeKotlinType } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirProviderImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirProviderImpl.kt index 3b0b4954af7..c8d191065f1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirProviderImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirProviderImpl.kt @@ -17,9 +17,9 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName class FirProviderImpl(val session: FirSession) : FirProvider { - override fun getFirClassifierBySymbol(symbol: ConeSymbol): FirMemberDeclaration? { + override fun getFirClassifierBySymbol(symbol: ConeSymbol): FirNamedDeclaration? { return when(symbol) { - is FirBasedSymbol<*> -> symbol.fir as? FirMemberDeclaration + is FirBasedSymbol<*> -> symbol.fir as? FirNamedDeclaration is ConeClassLikeSymbol -> getFirClassifierByFqName(symbol.classId) else -> error("!") } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirQualifierResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirQualifierResolverImpl.kt index f3014c66311..8ca171c071c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirQualifierResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirQualifierResolverImpl.kt @@ -11,6 +11,8 @@ import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirTypeAlias import org.jetbrains.kotlin.fir.resolve.FirProvider import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.ConeSymbol import org.jetbrains.kotlin.fir.symbols.toSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.* @@ -20,43 +22,7 @@ import org.jetbrains.kotlin.types.Variance class FirQualifierResolverImpl(val session: FirSession) : FirQualifierResolver { - private fun List.toTypeProjections() = flatMap { - it.typeArguments.map { - when (it) { - is FirStarProjection -> StarProjection - is FirTypeProjectionWithVariance -> { - val type = (it.type as FirResolvedType).type - when (it.variance) { - Variance.INVARIANT -> type - Variance.IN_VARIANCE -> ConeKotlinTypeProjectionInImpl(type) - Variance.OUT_VARIANCE -> ConeKotlinTypeProjectionOutImpl(type) - } - } - else -> error("!") - } - } - } - - private fun FirMemberDeclaration.toConeKotlinType(fqName: ClassId, parts: List): ConeKotlinType? { - return when (this) { - is FirClass -> { - ConeClassTypeImpl(fqName.toSymbol(), parts.toTypeProjections()) - } - is FirTypeAlias -> { - val expansion = expandedType.coneTypeSafe() - ?: return ConeKotlinErrorType("Couldn't resolve expansion") - - ConeAbbreviatedTypeImpl( - abbreviationSymbol = fqName.toSymbol(), - typeArguments = parts.toTypeProjections(), - directExpansion = expansion - ) - } - else -> error("!") - } - } - - override fun resolveTypeWithPrefix(parts: List, prefix: ClassId): ConeKotlinType? { + override fun resolveSymbolWithPrefix(parts: List, prefix: ClassId): ConeSymbol? { val firProvider = FirProvider.getInstance(session) val fqName = ClassId( @@ -64,12 +30,12 @@ class FirQualifierResolverImpl(val session: FirSession) : FirQualifierResolver { parts.drop(1).fold(prefix.relativeClassName) { prefix, suffix -> prefix.child(suffix.name) }, false ) - val foundClassifier = firProvider.getFirClassifierByFqName(fqName) + firProvider.getFirClassifierByFqName(fqName) ?: return null - return foundClassifier?.toConeKotlinType(fqName, parts) + return ConeClassLikeSymbol(fqName) } - override fun resolveType(parts: List): ConeKotlinType? { + override fun resolveSymbol(parts: List): ConeSymbol? { val firProvider = FirProvider.getInstance(session) if (parts.isNotEmpty()) { @@ -84,7 +50,7 @@ class FirQualifierResolverImpl(val session: FirSession) : FirQualifierResolver { val foundClassifier = firProvider.getFirClassifierByFqName(fqName) if (foundClassifier != null) { - return foundClassifier.toConeKotlinType(fqName, parts) + return ConeClassLikeSymbol(fqName) } } return null diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt index d0910dbe8ab..0973c3ef45a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt @@ -5,40 +5,107 @@ package org.jetbrains.kotlin.fir.resolve.impl +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirClass +import org.jetbrains.kotlin.fir.declarations.FirTypeAlias +import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.render +import org.jetbrains.kotlin.fir.resolve.FirProvider import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver import org.jetbrains.kotlin.fir.resolve.FirTypeResolver import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.ConeSymbol import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.fir.types.impl.ConeKotlinErrorType -import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl +import org.jetbrains.kotlin.fir.types.impl.* +import org.jetbrains.kotlin.types.Variance class FirTypeResolverImpl : FirTypeResolver { - override fun resolveType(type: FirType, scope: FirScope): ConeKotlinType { + + + private fun List.toTypeProjections() = flatMap { + it.typeArguments.map { + when (it) { + is FirStarProjection -> StarProjection + is FirTypeProjectionWithVariance -> { + val type = (it.type as FirResolvedType).type + when (it.variance) { + Variance.INVARIANT -> type + Variance.IN_VARIANCE -> ConeKotlinTypeProjectionInImpl(type) + Variance.OUT_VARIANCE -> ConeKotlinTypeProjectionOutImpl(type) + } + } + else -> error("!") + } + } + } + + private fun ConeSymbol.toConeKotlinType(parts: List, session: FirSession): ConeKotlinType? { + val firProvider = FirProvider.getInstance(session) + val fir = firProvider.getFirClassifierBySymbol(this) ?: return null + return when (fir) { + is FirTypeParameter -> { + ConeTypeParameterTypeImpl(this as ConeTypeParameterSymbol) + } + is FirClass -> { + ConeClassTypeImpl(this as ConeClassLikeSymbol, parts.toTypeProjections()) + } + is FirTypeAlias -> { + val coneTypeSafe = fir.expandedType.coneTypeSafe() + val expansion = if (coneTypeSafe != null) coneTypeSafe else { + return ConeKotlinErrorType("Couldn't resolve expansion") + } + + ConeAbbreviatedTypeImpl( + abbreviationSymbol = this as ConeClassLikeSymbol, + typeArguments = parts.toTypeProjections(), + directExpansion = expansion + ) + } + else -> error("!") + } + } + + override fun resolveToSymbol(type: FirType, scope: FirScope): ConeSymbol? { return when (type) { - is FirResolvedType -> type.type + is FirResolvedType -> type.coneTypeSafe()?.symbol is FirUserType -> { val qualifierResolver = FirQualifierResolver.getInstance(type.session) - var resolvedType: ConeKotlinType? = null + var resolvedSymbol: ConeSymbol? = null scope.processClassifiersByName(type.qualifier.first().name) { symbol -> - resolvedType = when (symbol) { + resolvedSymbol = when (symbol) { is ConeClassLikeSymbol -> { - qualifierResolver.resolveTypeWithPrefix(type.qualifier, symbol.classId) + qualifierResolver.resolveSymbolWithPrefix(type.qualifier, symbol.classId) } is ConeTypeParameterSymbol -> { assert(type.qualifier.size == 1) - ConeTypeParameterTypeImpl(symbol) + symbol } else -> error("!") } - resolvedType == null + resolvedSymbol == null } // TODO: Imports - resolvedType ?: qualifierResolver.resolveType(type.qualifier) ?: ConeKotlinErrorType("Failed to resolve qualified type") + resolvedSymbol ?: qualifierResolver.resolveSymbol(type.qualifier) + } + else -> null + } + } + + override fun resolveUserType(type: FirUserType, symbol: ConeSymbol?, scope: FirScope): ConeKotlinType { + symbol ?: return ConeKotlinErrorType("Symbol not found") + return symbol.toConeKotlinType(type.qualifier, type.session) ?: ConeKotlinErrorType("Failed to resolve qualified type") + } + + override fun resolveType(type: FirType, scope: FirScope): ConeKotlinType { + return when (type) { + is FirResolvedType -> type.type + is FirUserType -> { + resolveUserType(type, resolveToSymbol(type, scope), scope) } is FirErrorType -> { ConeKotlinErrorType(type.reason) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt index 4db6af88a39..c3a787dfc86 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt @@ -18,6 +18,8 @@ import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.utils.Printer +fun FirElement.render(): String = buildString { this@render.accept(FirRenderer(this)) } + class FirRenderer(builder: StringBuilder) : FirVisitorVoid() { private val printer = Printer(builder) diff --git a/compiler/testData/fir/resolve/multifile/TypeAliasExpansion.1.kt b/compiler/testData/fir/resolve/multifile/TypeAliasExpansion.1.kt new file mode 100644 index 00000000000..0921428ea16 --- /dev/null +++ b/compiler/testData/fir/resolve/multifile/TypeAliasExpansion.1.kt @@ -0,0 +1,7 @@ +package b + +class A + +typealias TA = A + +// analyzePriority: 1 \ No newline at end of file diff --git a/compiler/testData/fir/resolve/multifile/TypeAliasExpansion.kt b/compiler/testData/fir/resolve/multifile/TypeAliasExpansion.kt new file mode 100644 index 00000000000..589540900d7 --- /dev/null +++ b/compiler/testData/fir/resolve/multifile/TypeAliasExpansion.kt @@ -0,0 +1,7 @@ +package a + +import b.TA + +class MyClass : TA + +// analyzePriority: 0 \ No newline at end of file diff --git a/compiler/testData/fir/resolve/multifile/TypeAliasExpansion.txt b/compiler/testData/fir/resolve/multifile/TypeAliasExpansion.txt new file mode 100644 index 00000000000..3e8f5c625e0 --- /dev/null +++ b/compiler/testData/fir/resolve/multifile/TypeAliasExpansion.txt @@ -0,0 +1,3 @@ +FILE: TypeAliasExpansion.kt + (resolved) public? final class MyClass() : R/b/TA = b/A/ { + } diff --git a/compiler/testData/fir/resolve/simpleClass.txt b/compiler/testData/fir/resolve/simpleClass.txt index 0c4c10a086f..f8e9a08e8d5 100644 --- a/compiler/testData/fir/resolve/simpleClass.txt +++ b/compiler/testData/fir/resolve/simpleClass.txt @@ -1,27 +1,27 @@ FILE: simpleClass.kt (resolved) public? abstract interface SomeInterface() { - public? final? function foo(x: R/error: Failed to resolve qualified type/, y: R/error: Failed to resolve qualified type/): R/error: Failed to resolve qualified type/ + public? final? function foo(x: R/error: Symbol not found/, y: R/error: Symbol not found/): R/error: Symbol not found/ - public? final? property bar(val): R/error: Failed to resolve qualified type/ - public? get(): R/error: Failed to resolve qualified type/ + public? final? property bar(val): R/error: Symbol not found/ + public? get(): R/error: Symbol not found/ } (resolved) public? final class SomeClass() : R/SomeInterface/ { private final? property baz(val): R/error: Not supported: FirImplicitTypeImpl/ = STUB public? get(): R/error: Not supported: FirImplicitTypeImpl/ - public? open? override function foo(x: R/error: Failed to resolve qualified type/, y: R/error: Failed to resolve qualified type/): R/error: Failed to resolve qualified type/ { + public? open? override function foo(x: R/error: Symbol not found/, y: R/error: Symbol not found/): R/error: Symbol not found/ { } - public? open? override property bar(var): R/error: Failed to resolve qualified type/ + public? open? override property bar(var): R/error: Symbol not found/ public? get(): R/error: Not supported: FirImplicitTypeImpl/ { STUB } - public? set(value: R/error: Failed to resolve qualified type/): R/error: Not supported: FirImplicitTypeImpl/ { + public? set(value: R/error: Symbol not found/): R/error: Not supported: FirImplicitTypeImpl/ { } - public? final? property fau(var): R/error: Failed to resolve qualified type/ - public? get(): R/error: Failed to resolve qualified type/ - public? set(value: R/error: Failed to resolve qualified type/): R/kotlin/Unit/ + public? final? property fau(var): R/error: Symbol not found/ + public? get(): R/error: Symbol not found/ + public? set(value: R/error: Symbol not found/): R/kotlin/Unit/ } diff --git a/compiler/testData/fir/resolve/typeAliasWithGeneric.kt b/compiler/testData/fir/resolve/typeAliasWithGeneric.kt index c9c9eadadb0..c948c80b7c9 100644 --- a/compiler/testData/fir/resolve/typeAliasWithGeneric.kt +++ b/compiler/testData/fir/resolve/typeAliasWithGeneric.kt @@ -2,6 +2,6 @@ open class A interface B -typealias C = B - class D : C + +typealias C = B diff --git a/compiler/testData/fir/resolve/typeAliasWithGeneric.txt b/compiler/testData/fir/resolve/typeAliasWithGeneric.txt index a0076e68841..abce0826692 100644 --- a/compiler/testData/fir/resolve/typeAliasWithGeneric.txt +++ b/compiler/testData/fir/resolve/typeAliasWithGeneric.txt @@ -3,6 +3,6 @@ FILE: typeAliasWithGeneric.kt } (resolved) <(resolved) S, (resolved) T : R/A/> public? abstract interface B() { } - (resolved) <(resolved) T> public? final typealias C = R/B/ (resolved) public? final class D() : R/C = B/ { } + (resolved) <(resolved) T> public? final typealias C = R/B/ diff --git a/compiler/tests/org/jetbrains/kotlin/fir/AbstractFirResolveTestCase.kt b/compiler/tests/org/jetbrains/kotlin/fir/AbstractFirResolveTestCase.kt index e4b3252fa4f..7d721c28af7 100644 --- a/compiler/tests/org/jetbrains/kotlin/fir/AbstractFirResolveTestCase.kt +++ b/compiler/tests/org/jetbrains/kotlin/fir/AbstractFirResolveTestCase.kt @@ -8,12 +8,14 @@ package org.jetbrains.kotlin.fir import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.descriptors.FirTotalResolveTransformer import org.jetbrains.kotlin.fir.builder.RawFirBuilder +import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.resolve.FirProvider import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver import org.jetbrains.kotlin.fir.resolve.FirTypeResolver import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl import org.jetbrains.kotlin.fir.resolve.impl.FirQualifierResolverImpl import org.jetbrains.kotlin.fir.resolve.impl.FirTypeResolverImpl +import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestWithEnvironment @@ -24,20 +26,7 @@ abstract class AbstractFirResolveTestCase : KotlinTestWithEnvironment() { return createEnvironmentWithMockJdk(ConfigurationKind.JDK_NO_RUNTIME) } - fun doTest(path: String) { - val file = File(path) - - val allFiles = listOf(file) + file.parentFile.listFiles { sibling -> - sibling.name.removePrefix(file.nameWithoutExtension).removeSuffix(file.extension).matches("\\.[0-9]+\\.".toRegex()) - } - - - val ktFiles = allFiles.map { - val text = KotlinTestUtils.doLoadFile(it) - KotlinTestUtils.createFile(it.name, text, project) - - } - + fun doCreateAndProcessFir(ktFiles: List): List { val session = object : FirSessionBase() { init { registerComponent(FirProvider::class, FirProviderImpl(this)) @@ -57,6 +46,31 @@ abstract class AbstractFirResolveTestCase : KotlinTestWithEnvironment() { transformer.processFiles(it) } + return firFiles + } + + + fun doTest(path: String) { + val file = File(path) + + val allFiles = listOf(file) + file.parentFile.listFiles { sibling -> + sibling.name.removePrefix(file.nameWithoutExtension).removeSuffix(file.extension).matches("\\.[0-9]+\\.".toRegex()) + } + + val ktFiles = + allFiles.map { + val text = KotlinTestUtils.doLoadFile(it) + it.name to text + } + .sortedBy { (_, text) -> + KotlinTestUtils.parseDirectives(text)["analyzePriority"]?.toInt() + } + .map { (name, text) -> + KotlinTestUtils.createFile(name, text, project) + } + + val firFiles = doCreateAndProcessFir(ktFiles) + val firFileDump = StringBuilder().also { firFiles.first().accept(FirRenderer(it), null) }.toString() val expectedPath = path.replace(".kt", ".txt") KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump) diff --git a/compiler/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java index f2a41ffa05e..de0ba72c81f 100644 --- a/compiler/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java @@ -110,5 +110,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/multifile/simpleImportOuter.kt"); doTest(fileName); } + + @TestMetadata("TypeAliasExpansion.kt") + public void testTypeAliasExpansion() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/multifile/TypeAliasExpansion.kt"); + doTest(fileName); + } } }