FIR: Merge both synthetic type alias constructor kinds

This commit is contained in:
Denis Zharkov
2020-11-02 15:15:51 +03:00
parent f9aab77ce5
commit d58e66e79a
@@ -142,72 +142,6 @@ private fun FirTypeAliasSymbol.findSAMConstructorForTypeAlias(
).fir ).fir
} }
private fun processConstructors(
matchedSymbol: FirClassLikeSymbol<*>?,
substitutor: ConeSubstitutor,
processor: (FirFunctionSymbol<*>) -> Unit,
session: FirSession,
bodyResolveComponents: BodyResolveComponents,
includeInnerConstructors: Boolean
) {
try {
if (matchedSymbol != null) {
val scope = when (matchedSymbol) {
is FirTypeAliasSymbol -> {
matchedSymbol.ensureResolved(FirResolvePhase.TYPES, session)
val type = matchedSymbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>().fullyExpandedType(session)
val basicScope = type.scope(session, bodyResolveComponents.scopeSession, FakeOverrideTypeCalculator.DoNothing)
if (basicScope != null && type.typeArguments.isNotEmpty()) {
TypeAliasConstructorsSubstitutingScope(
matchedSymbol,
basicScope
)
} else basicScope
}
is FirClassSymbol ->
(matchedSymbol.fir as FirClass<*>).scopeForClass(
substitutor, session, bodyResolveComponents.scopeSession
)
}
//TODO: why don't we use declared member scope at this point?
scope?.processDeclaredConstructors {
if (includeInnerConstructors || !it.fir.isInner) {
val constructorSymbolToProcess =
prepareCopyConstructorForTypealiasNestedClass(matchedSymbol, it, session, bodyResolveComponents) ?: it
processor(constructorSymbolToProcess)
}
}
}
} catch (e: Throwable) {
throw RuntimeException("While processing constructors", e)
}
}
private class TypeAliasConstructorsSubstitutingScope(
private val typeAliasSymbol: FirTypeAliasSymbol,
private val delegatingScope: FirScope
) : FirScope() {
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
delegatingScope.processDeclaredConstructors { originalConstructorSymbol ->
val typeParameters = typeAliasSymbol.fir.typeParameters
if (typeParameters.isEmpty()) processor(originalConstructorSymbol)
else {
processor(
buildConstructorCopy(originalConstructorSymbol.fir) {
symbol = FirConstructorSymbol(originalConstructorSymbol.callableId, overriddenSymbol = originalConstructorSymbol)
origin = FirDeclarationOrigin.SubstitutionOverride
this.typeParameters += typeParameters.map { buildConstructedClassTypeParameterRef { symbol = it.symbol } }
}.symbol
)
}
}
}
}
private fun prepareSubstitutorForTypeAliasConstructors( private fun prepareSubstitutorForTypeAliasConstructors(
expandedType: ConeClassLikeType, expandedType: ConeClassLikeType,
session: FirSession session: FirSession
@@ -224,12 +158,73 @@ private fun prepareSubstitutorForTypeAliasConstructors(
) )
} }
private fun prepareCopyConstructorForTypealiasNestedClass( private fun processConstructors(
matchedSymbol: FirClassLikeSymbol<*>, matchedSymbol: FirClassLikeSymbol<*>?,
originalSymbol: FirConstructorSymbol, substitutor: ConeSubstitutor,
processor: (FirFunctionSymbol<*>) -> Unit,
session: FirSession, session: FirSession,
bodyResolveComponents: BodyResolveComponents, bodyResolveComponents: BodyResolveComponents,
): FirConstructorSymbol? { includeInnerConstructors: Boolean
) {
try {
if (matchedSymbol != null) {
val scope = when (matchedSymbol) {
is FirTypeAliasSymbol -> {
matchedSymbol.ensureResolved(FirResolvePhase.TYPES, session)
val type = matchedSymbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>().fullyExpandedType(session)
val basicScope = type.scope(session, bodyResolveComponents.scopeSession, FakeOverrideTypeCalculator.DoNothing)
val outerType = bodyResolveComponents.outerClassManager.outerType(type)
if (basicScope != null && (matchedSymbol.fir.typeParameters.isNotEmpty() || outerType != null)) {
TypeAliasConstructorsSubstitutingScope(
matchedSymbol,
basicScope,
outerType
)
} else basicScope
}
is FirClassSymbol ->
(matchedSymbol.fir as FirClass<*>).scopeForClass(
substitutor, session, bodyResolveComponents.scopeSession
)
}
//TODO: why don't we use declared member scope at this point?
scope?.processDeclaredConstructors {
if (includeInnerConstructors || !it.fir.isInner) {
processor(it)
}
}
}
} catch (e: Throwable) {
throw RuntimeException("While processing constructors", e)
}
}
private class TypeAliasConstructorsSubstitutingScope(
private val typeAliasSymbol: FirTypeAliasSymbol,
private val delegatingScope: FirScope,
private val outerType: ConeClassLikeType?,
) : FirScope() {
init {
require(outerType != null || typeAliasSymbol.fir.typeParameters.isNotEmpty())
}
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
delegatingScope.processDeclaredConstructors wrapper@{ originalConstructorSymbol ->
val typeParameters = typeAliasSymbol.fir.typeParameters
processor(
buildConstructorCopy(originalConstructorSymbol.fir) {
symbol = FirConstructorSymbol(originalConstructorSymbol.callableId)
origin = FirDeclarationOrigin.Synthetic
this.typeParameters.clear()
this.typeParameters += typeParameters.map { buildConstructedClassTypeParameterRef { symbol = it.symbol } }
if (outerType != null) {
// If the matched symbol is a type alias, and the expanded type is a nested class, e.g., // If the matched symbol is a type alias, and the expanded type is a nested class, e.g.,
// //
// class Outer { // class Outer {
@@ -246,25 +241,17 @@ private fun prepareCopyConstructorForTypealiasNestedClass(
// //
// fun Outer.OI(): OI = ... // fun Outer.OI(): OI = ...
// //
if (originalSymbol.callableId.classId?.isNestedClass == true && matchedSymbol is FirTypeAliasSymbol) { //
val innerTypeRef = originalSymbol.fir.returnTypeRef receiverTypeRef = originalConstructorSymbol.fir.returnTypeRef.withReplacedConeType(outerType)
val innerType = innerTypeRef.coneType.fullyExpandedType(session) as? ConeClassLikeType }
if (innerType != null) {
val outerType = bodyResolveComponents.outerClassManager.outerType(innerType)
if (outerType != null) {
val extCopy = buildConstructorCopy(originalSymbol.fir) {
origin = FirDeclarationOrigin.Synthetic
receiverTypeRef = innerTypeRef.withReplacedConeType(outerType)
symbol = FirConstructorSymbol(originalSymbol.callableId)
}.apply { }.apply {
originalConstructorIfTypeAlias = originalSymbol.fir originalConstructorIfTypeAlias = originalConstructorSymbol.fir
} }.symbol
return extCopy.symbol )
} }
} }
} }
return null
}
private object TypeAliasConstructorKey : FirDeclarationDataKey() private object TypeAliasConstructorKey : FirDeclarationDataKey()