FIR: Move constructor processing parts to a separate file
This commit is contained in:
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl
|
|||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol
|
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.SAM_PARAMETER_NAME
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
@@ -38,6 +37,7 @@ interface FirSamResolver : FirSessionComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val NULL_STUB = Any()
|
private val NULL_STUB = Any()
|
||||||
|
val SAM_PARAMETER_NAME = Name.identifier("block")
|
||||||
|
|
||||||
class FirSamResolverImpl(
|
class FirSamResolverImpl(
|
||||||
private val firSession: FirSession,
|
private val firSession: FirSession,
|
||||||
|
|||||||
+215
@@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* 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.resolve.calls
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirConstructorImpl
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
|
internal fun FirScope.processFunctionsAndConstructorsByName(
|
||||||
|
name: Name,
|
||||||
|
session: FirSession,
|
||||||
|
bodyResolveComponents: BodyResolveComponents,
|
||||||
|
processor: (FirCallableSymbol<*>) -> ProcessorAction
|
||||||
|
): ProcessorAction {
|
||||||
|
val matchedClassSymbol = getFirstClassifierOrNull(name) as? FirClassLikeSymbol<*>
|
||||||
|
|
||||||
|
if (processConstructors(
|
||||||
|
matchedClassSymbol,
|
||||||
|
processor,
|
||||||
|
session,
|
||||||
|
bodyResolveComponents.scopeSession,
|
||||||
|
name
|
||||||
|
).stop()
|
||||||
|
) {
|
||||||
|
return ProcessorAction.STOP
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processSyntheticConstructors(
|
||||||
|
matchedClassSymbol,
|
||||||
|
processor,
|
||||||
|
bodyResolveComponents
|
||||||
|
).stop()
|
||||||
|
) {
|
||||||
|
return ProcessorAction.STOP
|
||||||
|
}
|
||||||
|
|
||||||
|
return processFunctionsByName(name) {
|
||||||
|
if (it is FirConstructorSymbol) ProcessorAction.NEXT
|
||||||
|
else processor(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirScope.getFirstClassifierOrNull(name: Name): FirClassifierSymbol<*>? {
|
||||||
|
var result: FirClassifierSymbol<*>? = null
|
||||||
|
processClassifiersByName(name) {
|
||||||
|
result = it
|
||||||
|
ProcessorAction.STOP
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun finalExpansionName(symbol: FirTypeAliasSymbol, session: FirSession): Name? {
|
||||||
|
val expandedType = symbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>()
|
||||||
|
val typeAliasSymbol = expandedType.lookupTag.toSymbol(session)?.safeAs<FirTypeAliasSymbol>()
|
||||||
|
|
||||||
|
return if (typeAliasSymbol != null)
|
||||||
|
finalExpansionName(typeAliasSymbol, session)
|
||||||
|
else
|
||||||
|
expandedType.lookupTag.classId.shortClassName
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processSyntheticConstructors(
|
||||||
|
matchedSymbol: FirClassLikeSymbol<*>?,
|
||||||
|
processor: (FirFunctionSymbol<*>) -> ProcessorAction,
|
||||||
|
bodyResolveComponents: BodyResolveComponents
|
||||||
|
): ProcessorAction {
|
||||||
|
if (matchedSymbol == null) return ProcessorAction.NEXT
|
||||||
|
if (matchedSymbol !is FirRegularClassSymbol) return ProcessorAction.NEXT
|
||||||
|
|
||||||
|
val function = bodyResolveComponents.samResolver.getSamConstructor(matchedSymbol.fir) ?: return ProcessorAction.NEXT
|
||||||
|
|
||||||
|
return processor(function.symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processConstructors(
|
||||||
|
matchedSymbol: FirClassLikeSymbol<*>?,
|
||||||
|
processor: (FirFunctionSymbol<*>) -> ProcessorAction,
|
||||||
|
session: FirSession,
|
||||||
|
scopeSession: ScopeSession,
|
||||||
|
name: Name
|
||||||
|
): ProcessorAction {
|
||||||
|
try {
|
||||||
|
if (matchedSymbol != null) {
|
||||||
|
val scope = when (matchedSymbol) {
|
||||||
|
is FirTypeAliasSymbol -> {
|
||||||
|
val type = matchedSymbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>().fullyExpandedType(session)
|
||||||
|
val basicScope = type.scope(session, scopeSession)
|
||||||
|
|
||||||
|
if (basicScope != null && type.typeArguments.isNotEmpty()) {
|
||||||
|
prepareSubstitutingScopeForTypeAliasConstructors(
|
||||||
|
matchedSymbol, type, session, basicScope
|
||||||
|
) ?: return ProcessorAction.STOP
|
||||||
|
} else basicScope
|
||||||
|
}
|
||||||
|
is FirClassSymbol -> matchedSymbol.buildUseSiteMemberScope(session, scopeSession)
|
||||||
|
}
|
||||||
|
|
||||||
|
val constructorName = when (matchedSymbol) {
|
||||||
|
is FirTypeAliasSymbol -> finalExpansionName(matchedSymbol, session) ?: return ProcessorAction.NEXT
|
||||||
|
is FirClassSymbol -> name
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: why don't we use declared member scope at this point?
|
||||||
|
if (scope != null && scope.processFunctionsByName(
|
||||||
|
constructorName,
|
||||||
|
processor
|
||||||
|
) == ProcessorAction.STOP
|
||||||
|
) {
|
||||||
|
return ProcessorAction.STOP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ProcessorAction.NEXT
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
throw RuntimeException("While processing constructors", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TypeAliasConstructorsSubstitutingScope(
|
||||||
|
private val typeAliasSymbol: FirTypeAliasSymbol,
|
||||||
|
private val substitutor: ConeSubstitutor,
|
||||||
|
private val delegatingScope: FirScope
|
||||||
|
) : FirScope() {
|
||||||
|
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction {
|
||||||
|
return delegatingScope.processFunctionsByName(name) {
|
||||||
|
val toProcess = if (it is FirConstructorSymbol) {
|
||||||
|
it.fir.createTypeAliasConstructor(substitutor, typeAliasSymbol.fir.typeParameters).symbol
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
|
||||||
|
processor(toProcess)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun prepareSubstitutingScopeForTypeAliasConstructors(
|
||||||
|
typeAliasSymbol: FirTypeAliasSymbol,
|
||||||
|
expandedType: ConeClassLikeType,
|
||||||
|
session: FirSession,
|
||||||
|
delegatingScope: FirScope
|
||||||
|
): FirScope? {
|
||||||
|
val expandedClass = expandedType.lookupTag.toSymbol(session)?.fir as? FirRegularClass ?: return null
|
||||||
|
|
||||||
|
val resultingTypeArguments = expandedType.typeArguments.map {
|
||||||
|
// We don't know how to handle cases like yet
|
||||||
|
// typealias A = ArrayList<*>()
|
||||||
|
it as? ConeKotlinType ?: return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val substitutor = substitutorByMap(
|
||||||
|
expandedClass.typeParameters.map { it.symbol }.zip(resultingTypeArguments).toMap()
|
||||||
|
);
|
||||||
|
|
||||||
|
return TypeAliasConstructorsSubstitutingScope(typeAliasSymbol, substitutor, delegatingScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirConstructor.createTypeAliasConstructor(
|
||||||
|
substitutor: ConeSubstitutor,
|
||||||
|
typeParameters: List<FirTypeParameter>
|
||||||
|
): FirConstructor {
|
||||||
|
val newReturnTypeRef = returnTypeRef.substitute(substitutor)
|
||||||
|
|
||||||
|
val newParameterTypeRefs = valueParameters.map { valueParameter ->
|
||||||
|
valueParameter.returnTypeRef.substitute(substitutor)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newReturnTypeRef == null && newParameterTypeRefs.all { it == null }) return this
|
||||||
|
|
||||||
|
return FirConstructorImpl(
|
||||||
|
source, session, newReturnTypeRef ?: returnTypeRef, receiverTypeRef, status,
|
||||||
|
FirConstructorSymbol(symbol.callableId, overriddenSymbol = symbol)
|
||||||
|
).apply {
|
||||||
|
resolvePhase = this@createTypeAliasConstructor.resolvePhase
|
||||||
|
valueParameters += this@createTypeAliasConstructor.valueParameters.zip(
|
||||||
|
newParameterTypeRefs
|
||||||
|
) { valueParameter, newTypeRef ->
|
||||||
|
with(valueParameter) {
|
||||||
|
FirValueParameterImpl(
|
||||||
|
source,
|
||||||
|
session,
|
||||||
|
newTypeRef ?: returnTypeRef,
|
||||||
|
name,
|
||||||
|
FirVariableSymbol(valueParameter.symbol.callableId),
|
||||||
|
defaultValue,
|
||||||
|
isCrossinline,
|
||||||
|
isNoinline,
|
||||||
|
isVararg
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.typeParameters += typeParameters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirTypeRef.substitute(substitutor: ConeSubstitutor): FirResolvedTypeRef? =
|
||||||
|
coneTypeUnsafe<ConeKotlinType>()
|
||||||
|
.let(substitutor::substituteOrNull)
|
||||||
|
?.let { FirResolvedTypeRefImpl(source, it) }
|
||||||
@@ -8,26 +8,21 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirConstructorImpl
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirImportImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirImportImpl
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|
||||||
|
|
||||||
interface TowerScopeLevel {
|
interface TowerScopeLevel {
|
||||||
|
|
||||||
@@ -282,197 +277,3 @@ fun FirCallableDeclaration<*>.dispatchReceiverValue(session: FirSession): ClassD
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun FirCallableSymbol<*>.hasExtensionReceiver(): Boolean = this.fir.receiverTypeRef != null
|
private fun FirCallableSymbol<*>.hasExtensionReceiver(): Boolean = this.fir.receiverTypeRef != null
|
||||||
|
|
||||||
private fun FirScope.processFunctionsAndConstructorsByName(
|
|
||||||
name: Name,
|
|
||||||
session: FirSession,
|
|
||||||
bodyResolveComponents: BodyResolveComponents,
|
|
||||||
processor: (FirCallableSymbol<*>) -> ProcessorAction
|
|
||||||
): ProcessorAction {
|
|
||||||
val matchedClassSymbol = getFirstClassifierOrNull(name) as? FirClassLikeSymbol<*>
|
|
||||||
|
|
||||||
if (processConstructors(
|
|
||||||
matchedClassSymbol,
|
|
||||||
processor,
|
|
||||||
session,
|
|
||||||
bodyResolveComponents.scopeSession,
|
|
||||||
name
|
|
||||||
).stop()
|
|
||||||
) {
|
|
||||||
return ProcessorAction.STOP
|
|
||||||
}
|
|
||||||
|
|
||||||
if (processSyntheticConstructors(
|
|
||||||
matchedClassSymbol,
|
|
||||||
processor,
|
|
||||||
bodyResolveComponents
|
|
||||||
).stop()
|
|
||||||
) {
|
|
||||||
return ProcessorAction.STOP
|
|
||||||
}
|
|
||||||
|
|
||||||
return processFunctionsByName(name) {
|
|
||||||
if (it is FirConstructorSymbol) ProcessorAction.NEXT
|
|
||||||
else processor(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FirScope.getFirstClassifierOrNull(name: Name): FirClassifierSymbol<*>? {
|
|
||||||
var result: FirClassifierSymbol<*>? = null
|
|
||||||
processClassifiersByName(name) {
|
|
||||||
result = it
|
|
||||||
ProcessorAction.STOP
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun finalExpansionName(symbol: FirTypeAliasSymbol, session: FirSession): Name? {
|
|
||||||
val expandedType = symbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>()
|
|
||||||
val typeAliasSymbol = expandedType.lookupTag.toSymbol(session)?.safeAs<FirTypeAliasSymbol>()
|
|
||||||
|
|
||||||
return if (typeAliasSymbol != null)
|
|
||||||
finalExpansionName(typeAliasSymbol, session)
|
|
||||||
else
|
|
||||||
expandedType.lookupTag.classId.shortClassName
|
|
||||||
}
|
|
||||||
|
|
||||||
val SAM_PARAMETER_NAME = Name.identifier("block")
|
|
||||||
|
|
||||||
private fun processSyntheticConstructors(
|
|
||||||
matchedSymbol: FirClassLikeSymbol<*>?,
|
|
||||||
processor: (FirFunctionSymbol<*>) -> ProcessorAction,
|
|
||||||
bodyResolveComponents: BodyResolveComponents
|
|
||||||
): ProcessorAction {
|
|
||||||
if (matchedSymbol == null) return ProcessorAction.NEXT
|
|
||||||
if (matchedSymbol !is FirRegularClassSymbol) return ProcessorAction.NEXT
|
|
||||||
|
|
||||||
val function = bodyResolveComponents.samResolver.getSamConstructor(matchedSymbol.fir) ?: return ProcessorAction.NEXT
|
|
||||||
|
|
||||||
return processor(function.symbol)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun processConstructors(
|
|
||||||
matchedSymbol: FirClassLikeSymbol<*>?,
|
|
||||||
processor: (FirFunctionSymbol<*>) -> ProcessorAction,
|
|
||||||
session: FirSession,
|
|
||||||
scopeSession: ScopeSession,
|
|
||||||
name: Name
|
|
||||||
): ProcessorAction {
|
|
||||||
try {
|
|
||||||
if (matchedSymbol != null) {
|
|
||||||
val scope = when (matchedSymbol) {
|
|
||||||
is FirTypeAliasSymbol -> {
|
|
||||||
val type = matchedSymbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>().fullyExpandedType(session)
|
|
||||||
val basicScope = type.scope(session, scopeSession)
|
|
||||||
|
|
||||||
if (basicScope != null && type.typeArguments.isNotEmpty()) {
|
|
||||||
prepareSubstitutingScopeForTypeAliasConstructors(
|
|
||||||
matchedSymbol, type, session, basicScope
|
|
||||||
) ?: return ProcessorAction.STOP
|
|
||||||
} else basicScope
|
|
||||||
}
|
|
||||||
is FirClassSymbol -> matchedSymbol.buildUseSiteMemberScope(session, scopeSession)
|
|
||||||
}
|
|
||||||
|
|
||||||
val constructorName = when (matchedSymbol) {
|
|
||||||
is FirTypeAliasSymbol -> finalExpansionName(matchedSymbol, session) ?: return ProcessorAction.NEXT
|
|
||||||
is FirClassSymbol -> name
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: why don't we use declared member scope at this point?
|
|
||||||
if (scope != null && scope.processFunctionsByName(
|
|
||||||
constructorName,
|
|
||||||
processor
|
|
||||||
) == ProcessorAction.STOP
|
|
||||||
) {
|
|
||||||
return ProcessorAction.STOP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ProcessorAction.NEXT
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
throw RuntimeException("While processing constructors", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TypeAliasConstructorsSubstitutingScope(
|
|
||||||
private val typeAliasSymbol: FirTypeAliasSymbol,
|
|
||||||
private val substitutor: ConeSubstitutor,
|
|
||||||
private val delegatingScope: FirScope
|
|
||||||
) : FirScope() {
|
|
||||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction {
|
|
||||||
return delegatingScope.processFunctionsByName(name) {
|
|
||||||
val toProcess = if (it is FirConstructorSymbol) {
|
|
||||||
it.fir.createTypeAliasConstructor(substitutor, typeAliasSymbol.fir.typeParameters).symbol
|
|
||||||
} else {
|
|
||||||
it
|
|
||||||
}
|
|
||||||
|
|
||||||
processor(toProcess)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun prepareSubstitutingScopeForTypeAliasConstructors(
|
|
||||||
typeAliasSymbol: FirTypeAliasSymbol,
|
|
||||||
expandedType: ConeClassLikeType,
|
|
||||||
session: FirSession,
|
|
||||||
delegatingScope: FirScope
|
|
||||||
): FirScope? {
|
|
||||||
val expandedClass = expandedType.lookupTag.toSymbol(session)?.fir as? FirRegularClass ?: return null
|
|
||||||
|
|
||||||
val resultingTypeArguments = expandedType.typeArguments.map {
|
|
||||||
// We don't know how to handle cases like yet
|
|
||||||
// typealias A = ArrayList<*>()
|
|
||||||
it as? ConeKotlinType ?: return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val substitutor = substitutorByMap(
|
|
||||||
expandedClass.typeParameters.map { it.symbol }.zip(resultingTypeArguments).toMap()
|
|
||||||
);
|
|
||||||
|
|
||||||
return TypeAliasConstructorsSubstitutingScope(typeAliasSymbol, substitutor, delegatingScope)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FirConstructor.createTypeAliasConstructor(
|
|
||||||
substitutor: ConeSubstitutor,
|
|
||||||
typeParameters: List<FirTypeParameter>
|
|
||||||
): FirConstructor {
|
|
||||||
val newReturnTypeRef = returnTypeRef.substitute(substitutor)
|
|
||||||
|
|
||||||
val newParameterTypeRefs = valueParameters.map { valueParameter ->
|
|
||||||
valueParameter.returnTypeRef.substitute(substitutor)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newReturnTypeRef == null && newParameterTypeRefs.all { it == null }) return this
|
|
||||||
|
|
||||||
return FirConstructorImpl(
|
|
||||||
source, session, newReturnTypeRef ?: returnTypeRef, receiverTypeRef, status,
|
|
||||||
FirConstructorSymbol(symbol.callableId, overriddenSymbol = symbol)
|
|
||||||
).apply {
|
|
||||||
resolvePhase = this@createTypeAliasConstructor.resolvePhase
|
|
||||||
valueParameters += this@createTypeAliasConstructor.valueParameters.zip(
|
|
||||||
newParameterTypeRefs
|
|
||||||
) { valueParameter, newTypeRef ->
|
|
||||||
with(valueParameter) {
|
|
||||||
FirValueParameterImpl(
|
|
||||||
source,
|
|
||||||
session,
|
|
||||||
newTypeRef ?: returnTypeRef,
|
|
||||||
name,
|
|
||||||
FirVariableSymbol(valueParameter.symbol.callableId),
|
|
||||||
defaultValue,
|
|
||||||
isCrossinline,
|
|
||||||
isNoinline,
|
|
||||||
isVararg
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.typeParameters += typeParameters
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FirTypeRef.substitute(substitutor: ConeSubstitutor): FirResolvedTypeRef? =
|
|
||||||
coneTypeUnsafe<ConeKotlinType>()
|
|
||||||
.let(substitutor::substituteOrNull)
|
|
||||||
?.let { FirResolvedTypeRefImpl(source, it) }
|
|
||||||
|
|||||||
Reference in New Issue
Block a user