[FIR] Split functions & constructors processing
This commit is contained in:
+1
-1
@@ -190,7 +190,7 @@ abstract class AbstractFirTypeEnhancementTest : KtUsefulTestCase() {
|
|||||||
for (declaration in javaClass.declarations) {
|
for (declaration in javaClass.declarations) {
|
||||||
if (declaration in renderedDeclarations) continue
|
if (declaration in renderedDeclarations) continue
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is FirJavaConstructor -> enhancementScope.processFunctionsByName(javaClass.name) { symbol ->
|
is FirJavaConstructor -> enhancementScope.processDeclaredConstructors { symbol ->
|
||||||
val enhanced = symbol.fir
|
val enhanced = symbol.fir
|
||||||
if (enhanced !in renderedDeclarations) {
|
if (enhanced !in renderedDeclarations) {
|
||||||
enhanced.accept(renderer, null)
|
enhanced.accept(renderer, null)
|
||||||
|
|||||||
+14
-5
@@ -82,9 +82,9 @@ class JavaClassEnhancementScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun enhance(
|
private fun enhance(
|
||||||
original: FirCallableSymbol<*>,
|
original: FirVariableSymbol<*>,
|
||||||
name: Name
|
name: Name
|
||||||
): FirCallableSymbol<*> {
|
): FirVariableSymbol<*> {
|
||||||
when (val firElement = original.fir) {
|
when (val firElement = original.fir) {
|
||||||
is FirField -> {
|
is FirField -> {
|
||||||
if (firElement.returnTypeRef !is FirJavaTypeRef) return original
|
if (firElement.returnTypeRef !is FirJavaTypeRef) return original
|
||||||
@@ -139,7 +139,7 @@ class JavaClassEnhancementScope(
|
|||||||
|
|
||||||
private fun enhance(
|
private fun enhance(
|
||||||
original: FirFunctionSymbol<*>,
|
original: FirFunctionSymbol<*>,
|
||||||
name: Name
|
name: Name?
|
||||||
): FirFunctionSymbol<*> {
|
): FirFunctionSymbol<*> {
|
||||||
val firMethod = original.fir
|
val firMethod = original.fir
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ class JavaClassEnhancementScope(
|
|||||||
private fun enhanceMethod(
|
private fun enhanceMethod(
|
||||||
firMethod: FirFunction<*>,
|
firMethod: FirFunction<*>,
|
||||||
methodId: CallableId,
|
methodId: CallableId,
|
||||||
name: Name
|
name: Name?
|
||||||
): FirFunctionSymbol<*> {
|
): FirFunctionSymbol<*> {
|
||||||
val memberContext = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, jsr305State, firMethod.annotations)
|
val memberContext = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, jsr305State, firMethod.annotations)
|
||||||
|
|
||||||
@@ -241,7 +241,7 @@ class JavaClassEnhancementScope(
|
|||||||
session = this@JavaClassEnhancementScope.session
|
session = this@JavaClassEnhancementScope.session
|
||||||
returnTypeRef = newReturnTypeRef
|
returnTypeRef = newReturnTypeRef
|
||||||
receiverTypeRef = newReceiverTypeRef
|
receiverTypeRef = newReceiverTypeRef
|
||||||
this.name = name
|
this.name = name!!
|
||||||
status = firMethod.status
|
status = firMethod.status
|
||||||
symbol = FirNamedFunctionSymbol(methodId)
|
symbol = FirNamedFunctionSymbol(methodId)
|
||||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||||
@@ -402,4 +402,13 @@ class JavaClassEnhancementScope(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
|
|
||||||
|
useSiteMemberScope.processDeclaredConstructors process@{ original ->
|
||||||
|
|
||||||
|
val function = enhancements.getOrPut(original) { enhance(original, name = null) }
|
||||||
|
processor(function as FirConstructorSymbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
|||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -17,11 +18,11 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
class JvmMappedScope(
|
class JvmMappedScope(
|
||||||
private val declaredMemberScope: FirScope,
|
private val declaredMemberScope: FirScope,
|
||||||
private val javaMappedClassUseSiteScope: FirScope,
|
private val javaMappedClassUseSiteScope: FirScope,
|
||||||
private val whiteListSignaturesByName: Map<Name, List<String>>
|
private val signatures: Signatures
|
||||||
) : FirScope() {
|
) : FirScope() {
|
||||||
|
|
||||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
|
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
|
||||||
val whiteListSignatures = whiteListSignaturesByName[name]
|
val whiteListSignatures = signatures.whiteListSignaturesByName[name]
|
||||||
?: return declaredMemberScope.processFunctionsByName(name, processor)
|
?: return declaredMemberScope.processFunctionsByName(name, processor)
|
||||||
javaMappedClassUseSiteScope.processFunctionsByName(name) { symbol ->
|
javaMappedClassUseSiteScope.processFunctionsByName(name) { symbol ->
|
||||||
val jvmSignature = symbol.fir.computeJvmDescriptor()
|
val jvmSignature = symbol.fir.computeJvmDescriptor()
|
||||||
@@ -36,6 +37,22 @@ class JvmMappedScope(
|
|||||||
declaredMemberScope.processFunctionsByName(name, processor)
|
declaredMemberScope.processFunctionsByName(name, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
|
val constructorBlackList = signatures.constructorBlackList
|
||||||
|
if (constructorBlackList.isNotEmpty()) {
|
||||||
|
javaMappedClassUseSiteScope.processDeclaredConstructors { symbol ->
|
||||||
|
val jvmSignature = symbol.fir.computeJvmDescriptor()
|
||||||
|
.replace("kotlin/Any", "java/lang/Object")
|
||||||
|
.replace("kotlin/String", "java/lang/String")
|
||||||
|
if (jvmSignature !in constructorBlackList) {
|
||||||
|
processor(symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declaredMemberScope.processDeclaredConstructors(processor)
|
||||||
|
}
|
||||||
|
|
||||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||||
declaredMemberScope.processPropertiesByName(name, processor)
|
declaredMemberScope.processPropertiesByName(name, processor)
|
||||||
}
|
}
|
||||||
@@ -45,15 +62,27 @@ class JvmMappedScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun prepareSignatures(klass: FirRegularClass): Map<Name, List<String>> {
|
data class Signatures(val whiteListSignaturesByName: Map<Name, Set<String>>, val constructorBlackList: Set<String>) {
|
||||||
|
fun isEmpty() = whiteListSignaturesByName.isEmpty() && constructorBlackList.isEmpty()
|
||||||
|
fun isNotEmpty() = !isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun prepareSignatures(klass: FirRegularClass): Signatures {
|
||||||
val signaturePrefix = klass.symbol.classId.toString()
|
val signaturePrefix = klass.symbol.classId.toString()
|
||||||
val filteredSignatures = JvmBuiltInsSettings.WHITE_LIST_METHOD_SIGNATURES.filter { signature ->
|
val whiteListSignaturesByName = mutableMapOf<Name, MutableSet<String>>()
|
||||||
|
JvmBuiltInsSettings.WHITE_LIST_METHOD_SIGNATURES.filter { signature ->
|
||||||
signature.startsWith(signaturePrefix)
|
signature.startsWith(signaturePrefix)
|
||||||
}.map { signature ->
|
}.map { signature ->
|
||||||
// +1 to delete dot before function name
|
// +1 to delete dot before function name
|
||||||
signature.substring(signaturePrefix.length + 1)
|
signature.substring(signaturePrefix.length + 1)
|
||||||
|
}.forEach {
|
||||||
|
whiteListSignaturesByName.getOrPut(Name.identifier(it.substringBefore("("))) { mutableSetOf() }.add(it)
|
||||||
}
|
}
|
||||||
return filteredSignatures.groupBy { Name.identifier(it.substringBefore("(")) }
|
|
||||||
|
val constructorBlackList = JvmBuiltInsSettings.BLACK_LIST_CONSTRUCTOR_SIGNATURES
|
||||||
|
.filter { it.startsWith(signaturePrefix) }
|
||||||
|
.mapTo(mutableSetOf()) { it.substring(signaturePrefix.length + 1) }
|
||||||
|
return Signatures(whiteListSignaturesByName, constructorBlackList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -308,12 +308,10 @@ class FirCallResolver(
|
|||||||
val candidateFactory = CandidateFactory(this, callInfo)
|
val candidateFactory = CandidateFactory(this, callInfo)
|
||||||
val candidates = mutableListOf<Candidate>()
|
val candidates = mutableListOf<Candidate>()
|
||||||
|
|
||||||
scope.processFunctionsByName(className) {
|
scope.processDeclaredConstructors {
|
||||||
if (it is FirConstructorSymbol) {
|
val candidate = candidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER)
|
||||||
val candidate = candidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER)
|
candidate.typeArgumentMapping = TypeArgumentMapping.Mapped(typeArguments)
|
||||||
candidate.typeArgumentMapping = TypeArgumentMapping.Mapped(typeArguments)
|
candidates += candidate
|
||||||
candidates += candidate
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return callResolver.selectDelegatingConstructorCall(delegatedConstructorCall, className, candidates)
|
return callResolver.selectDelegatingConstructorCall(delegatedConstructorCall, className, candidates)
|
||||||
}
|
}
|
||||||
|
|||||||
+73
-59
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
import com.intellij.openapi.progress.ProcessCanceledException
|
import com.intellij.openapi.progress.ProcessCanceledException
|
||||||
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.builder.buildConstructedClassTypeParameterRef
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildConstructor
|
import org.jetbrains.kotlin.fir.declarations.builder.buildConstructor
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
@@ -16,7 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
|||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.scopes.scope
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
@@ -24,6 +25,9 @@ import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
|
private operator fun <T> Pair<T, *>?.component1() = this?.first
|
||||||
|
private operator fun <T> Pair<*, T>?.component2() = this?.second
|
||||||
|
|
||||||
internal fun FirScope.processFunctionsAndConstructorsByName(
|
internal fun FirScope.processFunctionsAndConstructorsByName(
|
||||||
name: Name,
|
name: Name,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
@@ -32,34 +36,38 @@ internal fun FirScope.processFunctionsAndConstructorsByName(
|
|||||||
processor: (FirCallableSymbol<*>) -> Unit
|
processor: (FirCallableSymbol<*>) -> Unit
|
||||||
) {
|
) {
|
||||||
// TODO: Handle case with two or more accessible classifiers
|
// TODO: Handle case with two or more accessible classifiers
|
||||||
val matchedClassSymbol = getFirstClassifierOrNull(name) as? FirClassLikeSymbol<*>
|
val classifierInfo = getFirstClassifierOrNull(name)
|
||||||
|
if (classifierInfo != null) {
|
||||||
|
val (matchedClassifierSymbol, substitutor) = classifierInfo
|
||||||
|
val matchedClassSymbol = matchedClassifierSymbol as? FirClassLikeSymbol<*>
|
||||||
|
|
||||||
processConstructors(
|
|
||||||
matchedClassSymbol,
|
|
||||||
processor,
|
|
||||||
session,
|
|
||||||
bodyResolveComponents.scopeSession,
|
|
||||||
noInnerConstructors
|
|
||||||
)
|
|
||||||
|
|
||||||
processSyntheticConstructors(
|
processConstructors(
|
||||||
matchedClassSymbol,
|
matchedClassSymbol,
|
||||||
processor,
|
substitutor,
|
||||||
bodyResolveComponents
|
processor,
|
||||||
)
|
session,
|
||||||
|
bodyResolveComponents.scopeSession,
|
||||||
|
noInnerConstructors
|
||||||
|
)
|
||||||
|
|
||||||
|
processSyntheticConstructors(
|
||||||
|
matchedClassSymbol,
|
||||||
|
processor,
|
||||||
|
bodyResolveComponents
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
processFunctionsByName(name) {
|
processFunctionsByName(name) {
|
||||||
if (it !is FirConstructorSymbol) {
|
processor(it)
|
||||||
processor(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirScope.getFirstClassifierOrNull(name: Name): FirClassifierSymbol<*>? {
|
private fun FirScope.getFirstClassifierOrNull(name: Name): Pair<FirClassifierSymbol<*>, ConeSubstitutor>? {
|
||||||
var result: FirClassifierSymbol<*>? = null
|
var result: Pair<FirClassifierSymbol<*>, ConeSubstitutor>? = null
|
||||||
processClassifiersByName(name) {
|
processClassifiersByNameWithSubstitution(name) { symbol, substitution ->
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
result = it
|
result = symbol to substitution
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +135,7 @@ private fun FirTypeAliasSymbol.findSAMConstructorForTypeAlias(
|
|||||||
|
|
||||||
private fun processConstructors(
|
private fun processConstructors(
|
||||||
matchedSymbol: FirClassLikeSymbol<*>?,
|
matchedSymbol: FirClassLikeSymbol<*>?,
|
||||||
|
substitutor: ConeSubstitutor,
|
||||||
processor: (FirFunctionSymbol<*>) -> Unit,
|
processor: (FirFunctionSymbol<*>) -> Unit,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
@@ -145,18 +154,15 @@ private fun processConstructors(
|
|||||||
) ?: return
|
) ?: return
|
||||||
} else basicScope
|
} else basicScope
|
||||||
}
|
}
|
||||||
is FirClassSymbol -> (matchedSymbol.fir as FirClass<*>).unsubstitutedScope(session, scopeSession)
|
is FirClassSymbol ->
|
||||||
}
|
(matchedSymbol.fir as FirClass<*>).scope(
|
||||||
|
substitutor, session, scopeSession, false,
|
||||||
val constructorName = when (matchedSymbol) {
|
)
|
||||||
is FirTypeAliasSymbol -> finalExpansionName(matchedSymbol, session) ?: return
|
|
||||||
is FirRegularClassSymbol -> matchedSymbol.fir.name
|
|
||||||
else -> return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: why don't we use declared member scope at this point?
|
//TODO: why don't we use declared member scope at this point?
|
||||||
scope?.processFunctionsByName(constructorName) {
|
scope?.processDeclaredConstructors {
|
||||||
if (!noInner || (it as? FirConstructorSymbol)?.fir?.isInner != true) {
|
if (!noInner || !it.fir.isInner) {
|
||||||
processor(it)
|
processor(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,29 +175,37 @@ private fun processConstructors(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class TypeAliasConstructorsSubstitutingScope(
|
private class TypeAliasConstructorsSubstitutingScope(
|
||||||
private val typeAliasConstructorsSubstitutor: TypeAliasConstructorsSubstitutor<FirConstructor>,
|
private val typeAliasSymbol: FirTypeAliasSymbol,
|
||||||
|
private val copyFactory: ConstructorCopyFactory<FirConstructor>,
|
||||||
private val delegatingScope: FirScope
|
private val delegatingScope: FirScope
|
||||||
) : FirScope() {
|
) : FirScope() {
|
||||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
|
|
||||||
delegatingScope.processFunctionsByName(name) {
|
|
||||||
val toProcess = if (it is FirConstructorSymbol) {
|
|
||||||
typeAliasConstructorsSubstitutor.substitute(it.fir).symbol
|
|
||||||
} else {
|
|
||||||
it
|
|
||||||
}
|
|
||||||
|
|
||||||
processor(toProcess)
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
|
delegatingScope.processDeclaredConstructors {
|
||||||
|
|
||||||
|
val typeParameters = typeAliasSymbol.fir.typeParameters
|
||||||
|
if (typeParameters.isEmpty()) processor(it)
|
||||||
|
else {
|
||||||
|
processor(it.fir.copyFactory(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
typeParameters.map { buildConstructedClassTypeParameterRef { symbol = it.symbol } }
|
||||||
|
).symbol)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private typealias ConstructorCopyFactory2<F> =
|
||||||
|
F.(newReturnType: ConeKotlinType?, newValueParameterTypes: List<ConeKotlinType?>?, newTypeParameters: List<FirTypeParameter>) -> F
|
||||||
|
|
||||||
private typealias ConstructorCopyFactory<F> =
|
private typealias ConstructorCopyFactory<F> =
|
||||||
F.(newReturnType: ConeKotlinType?, newValueParameterTypes: List<ConeKotlinType?>, newTypeParameters: List<FirTypeParameter>) -> F
|
F.(newReturnType: ConeKotlinType?, newValueParameterTypes: List<ConeKotlinType?>?, newTypeParameters: List<FirTypeParameterRef>) -> F
|
||||||
|
|
||||||
private class TypeAliasConstructorsSubstitutor<F : FirFunction<F>>(
|
private class TypeAliasConstructorsSubstitutor<F : FirFunction<F>>(
|
||||||
private val typeAliasSymbol: FirTypeAliasSymbol,
|
private val typeAliasSymbol: FirTypeAliasSymbol,
|
||||||
private val substitutor: ConeSubstitutor,
|
private val substitutor: ConeSubstitutor,
|
||||||
private val copyFactory: ConstructorCopyFactory<F>
|
private val copyFactory: ConstructorCopyFactory2<F>
|
||||||
) {
|
) {
|
||||||
fun substitute(baseFunction: F): F {
|
fun substitute(baseFunction: F): F {
|
||||||
val typeParameters = typeAliasSymbol.fir.typeParameters
|
val typeParameters = typeAliasSymbol.fir.typeParameters
|
||||||
@@ -217,20 +231,16 @@ private fun prepareSubstitutingScopeForTypeAliasConstructors(
|
|||||||
session: FirSession,
|
session: FirSession,
|
||||||
delegatingScope: FirScope
|
delegatingScope: FirScope
|
||||||
): FirScope? {
|
): FirScope? {
|
||||||
val typeAliasConstructorsSubstitutor =
|
val copyFactory2: ConstructorCopyFactory<FirConstructor> = factory@ { newReturnType, newParameterTypes, newTypeParameters ->
|
||||||
prepareSubstitutorForTypeAliasConstructors<FirConstructor>(
|
buildConstructor {
|
||||||
typeAliasSymbol,
|
source = this@factory.source
|
||||||
expandedType,
|
this.session = session
|
||||||
session
|
returnTypeRef = this@factory.returnTypeRef.withReplacedConeType(newReturnType)
|
||||||
) factory@{ newReturnType, newParameterTypes, newTypeParameters ->
|
receiverTypeRef = this@factory.receiverTypeRef
|
||||||
buildConstructor {
|
status = this@factory.status
|
||||||
source = this@factory.source
|
symbol = FirConstructorSymbol(this@factory.symbol.callableId, overriddenSymbol = this@factory.symbol)
|
||||||
this.session = session
|
resolvePhase = this@factory.resolvePhase
|
||||||
returnTypeRef = this@factory.returnTypeRef.withReplacedConeType(newReturnType)
|
if (newParameterTypes != null) {
|
||||||
receiverTypeRef = this@factory.receiverTypeRef
|
|
||||||
status = this@factory.status
|
|
||||||
symbol = FirConstructorSymbol(this@factory.symbol.callableId, overriddenSymbol = this@factory.symbol)
|
|
||||||
resolvePhase = this@factory.resolvePhase
|
|
||||||
valueParameters +=
|
valueParameters +=
|
||||||
this@factory.valueParameters.zip(
|
this@factory.valueParameters.zip(
|
||||||
newParameterTypes
|
newParameterTypes
|
||||||
@@ -247,12 +257,16 @@ private fun prepareSubstitutingScopeForTypeAliasConstructors(
|
|||||||
isVararg = valueParameter.isVararg
|
isVararg = valueParameter.isVararg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.typeParameters += newTypeParameters
|
} else {
|
||||||
|
valueParameters += this@factory.valueParameters
|
||||||
}
|
}
|
||||||
} ?: return null
|
this.typeParameters += newTypeParameters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TypeAliasConstructorsSubstitutingScope(
|
return TypeAliasConstructorsSubstitutingScope(
|
||||||
typeAliasConstructorsSubstitutor,
|
typeAliasSymbol,
|
||||||
|
copyFactory2,
|
||||||
delegatingScope
|
delegatingScope
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -261,7 +275,7 @@ private fun <F : FirFunction<F>> prepareSubstitutorForTypeAliasConstructors(
|
|||||||
typeAliasSymbol: FirTypeAliasSymbol,
|
typeAliasSymbol: FirTypeAliasSymbol,
|
||||||
expandedType: ConeClassLikeType,
|
expandedType: ConeClassLikeType,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
copyFactory: ConstructorCopyFactory<F>
|
copyFactory: ConstructorCopyFactory2<F>
|
||||||
): TypeAliasConstructorsSubstitutor<F>? {
|
): TypeAliasConstructorsSubstitutor<F>? {
|
||||||
val expandedClass = expandedType.lookupTag.toSymbol(session)?.fir as? FirRegularClass ?: return null
|
val expandedClass = expandedType.lookupTag.toSymbol(session)?.fir as? FirRegularClass ?: return null
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -11,9 +11,6 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
|
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.FirValueParameterBuilder
|
import org.jetbrains.kotlin.fir.declarations.builder.FirValueParameterBuilder
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
|
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
|
||||||
@@ -123,4 +120,8 @@ abstract class AbstractFirUseSiteMemberScope(
|
|||||||
declaredMemberScope.processClassifiersByNameWithSubstitution(name, processor)
|
declaredMemberScope.processClassifiersByNameWithSubstitution(name, processor)
|
||||||
superTypesScope.processClassifiersByNameWithSubstitution(name, processor)
|
superTypesScope.processClassifiersByNameWithSubstitution(name, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
|
declaredMemberScope.processDeclaredConstructors(processor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-5
@@ -9,10 +9,7 @@ import org.jetbrains.kotlin.fir.declarations.*
|
|||||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
class FirClassDeclaredMemberScope(
|
class FirClassDeclaredMemberScope(
|
||||||
@@ -33,7 +30,7 @@ class FirClassDeclaredMemberScope(
|
|||||||
when (declaration) {
|
when (declaration) {
|
||||||
is FirCallableMemberDeclaration<*> -> {
|
is FirCallableMemberDeclaration<*> -> {
|
||||||
val name = when (declaration) {
|
val name = when (declaration) {
|
||||||
is FirConstructor -> if (klass is FirRegularClass) klass.name else continue@loop
|
is FirConstructor -> Name.special("<init>")
|
||||||
is FirVariable<*> -> declaration.name
|
is FirVariable<*> -> declaration.name
|
||||||
is FirSimpleFunction -> declaration.name
|
is FirSimpleFunction -> declaration.name
|
||||||
else -> continue@loop
|
else -> continue@loop
|
||||||
@@ -54,6 +51,15 @@ class FirClassDeclaredMemberScope(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
|
val symbols = callablesIndex[Name.special("<init>")] ?: return
|
||||||
|
for (symbol in symbols) {
|
||||||
|
if (symbol is FirConstructorSymbol) {
|
||||||
|
processor(symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||||
val symbols = callablesIndex[name] ?: emptyList()
|
val symbols = callablesIndex[name] ?: emptyList()
|
||||||
for (symbol in symbols) {
|
for (symbol in symbols) {
|
||||||
|
|||||||
+114
-15
@@ -40,6 +40,7 @@ class FirClassSubstitutionScope(
|
|||||||
) : FirScope() {
|
) : FirScope() {
|
||||||
|
|
||||||
private val fakeOverrideFunctions = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>()
|
private val fakeOverrideFunctions = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>()
|
||||||
|
private val fakeOverrideConstructors = mutableMapOf<FirConstructorSymbol, FirConstructorSymbol>()
|
||||||
private val fakeOverrideProperties = mutableMapOf<FirPropertySymbol, FirPropertySymbol>()
|
private val fakeOverrideProperties = mutableMapOf<FirPropertySymbol, FirPropertySymbol>()
|
||||||
private val fakeOverrideFields = mutableMapOf<FirFieldSymbol, FirFieldSymbol>()
|
private val fakeOverrideFields = mutableMapOf<FirFieldSymbol, FirFieldSymbol>()
|
||||||
private val fakeOverrideAccessors = mutableMapOf<FirAccessorSymbol, FirAccessorSymbol>()
|
private val fakeOverrideAccessors = mutableMapOf<FirAccessorSymbol, FirAccessorSymbol>()
|
||||||
@@ -127,35 +128,66 @@ class FirClassSubstitutionScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return createFakeOverrideFunction(
|
return createFakeOverrideFunction(
|
||||||
session, member, original, newReceiverType, newReturnType, newParameterTypes, newTypeParameters, derivedClassId
|
session,
|
||||||
|
member,
|
||||||
|
original,
|
||||||
|
newReceiverType,
|
||||||
|
newReturnType,
|
||||||
|
newParameterTypes,
|
||||||
|
newTypeParameters as List<FirTypeParameter>,
|
||||||
|
derivedClassId
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createFakeOverrideConstructor(original: FirConstructorSymbol): FirConstructorSymbol {
|
||||||
|
if (substitutor == ConeSubstitutor.Empty) return original
|
||||||
|
val constructor = original.fir
|
||||||
|
val (newTypeParameters, newSubstitutor) = createNewTypeParametersAndSubstitutor(constructor)
|
||||||
|
|
||||||
|
|
||||||
|
val returnType = constructor.returnTypeRef.coneTypeUnsafe<ConeKotlinType>()
|
||||||
|
val newReturnType = returnType.substitute(newSubstitutor)
|
||||||
|
|
||||||
|
val newParameterTypes = constructor.valueParameters.map {
|
||||||
|
it.returnTypeRef.coneTypeUnsafe<ConeKotlinType>().substitute(newSubstitutor)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newReturnType == null && newParameterTypes.all { it == null } && newTypeParameters === constructor.typeParameters) {
|
||||||
|
return original
|
||||||
|
}
|
||||||
|
return createFakeOverrideConstructor(FirConstructorSymbol(original.callableId, overriddenSymbol = original), session, constructor, null, newReturnType, newParameterTypes, newTypeParameters).symbol
|
||||||
|
}
|
||||||
|
|
||||||
// Returns a list of type parameters, and a substitutor that should be used for all other types
|
// Returns a list of type parameters, and a substitutor that should be used for all other types
|
||||||
private fun createNewTypeParametersAndSubstitutor(
|
private fun createNewTypeParametersAndSubstitutor(
|
||||||
member: FirCallableMemberDeclaration<*>
|
member: FirTypeParameterRefsOwner
|
||||||
): Pair<List<FirTypeParameter>, ConeSubstitutor> {
|
): Pair<List<FirTypeParameterRef>, ConeSubstitutor> {
|
||||||
if (member.typeParameters.isEmpty()) return Pair(member.typeParameters, substitutor)
|
if (member.typeParameters.isEmpty()) return Pair(member.typeParameters, substitutor)
|
||||||
val newTypeParameters = member.typeParameters.map { originalParameter ->
|
val newTypeParameters = member.typeParameters.map { typeParameter ->
|
||||||
|
if (typeParameter !is FirTypeParameter) return@map null
|
||||||
FirTypeParameterBuilder().apply {
|
FirTypeParameterBuilder().apply {
|
||||||
source = originalParameter.source
|
source = typeParameter.source
|
||||||
session = originalParameter.session
|
session = typeParameter.session
|
||||||
name = originalParameter.name
|
name = typeParameter.name
|
||||||
symbol = FirTypeParameterSymbol()
|
symbol = FirTypeParameterSymbol()
|
||||||
variance = originalParameter.variance
|
variance = typeParameter.variance
|
||||||
isReified = originalParameter.isReified
|
isReified = typeParameter.isReified
|
||||||
annotations += originalParameter.annotations
|
annotations += typeParameter.annotations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val substitutionMapForNewParameters = member.typeParameters.zip(newTypeParameters).map {
|
val substitutionMapForNewParameters = member.typeParameters.zip(newTypeParameters).mapNotNull { (original, new) ->
|
||||||
Pair(it.first.symbol, ConeTypeParameterTypeImpl(it.second.symbol.toLookupTag(), isNullable = false))
|
if (new != null)
|
||||||
|
Pair(original.symbol, ConeTypeParameterTypeImpl(new.symbol.toLookupTag(), isNullable = false))
|
||||||
|
else null
|
||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
val additionalSubstitutor = substitutorByMap(substitutionMapForNewParameters)
|
val additionalSubstitutor = substitutorByMap(substitutionMapForNewParameters)
|
||||||
|
|
||||||
for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(member.typeParameters)) {
|
for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(member.typeParameters)) {
|
||||||
for (boundTypeRef in oldTypeParameter.bounds) {
|
if (newTypeParameter == null) continue
|
||||||
|
val original = oldTypeParameter as FirTypeParameter
|
||||||
|
for (boundTypeRef in original.bounds) {
|
||||||
val typeForBound = boundTypeRef.coneTypeUnsafe<ConeKotlinType>()
|
val typeForBound = boundTypeRef.coneTypeUnsafe<ConeKotlinType>()
|
||||||
val substitutedBound = typeForBound.substitute()
|
val substitutedBound = typeForBound.substitute()
|
||||||
newTypeParameter.bounds +=
|
newTypeParameter.bounds +=
|
||||||
@@ -171,7 +203,10 @@ class FirClassSubstitutionScope(
|
|||||||
// While common Ir contracts expect them to be different
|
// While common Ir contracts expect them to be different
|
||||||
// if (!wereChangesInTypeParameters) return Pair(member.typeParameters, substitutor)
|
// if (!wereChangesInTypeParameters) return Pair(member.typeParameters, substitutor)
|
||||||
|
|
||||||
return Pair(newTypeParameters.map { it.build() }, ChainedSubstitutor(substitutor, additionalSubstitutor))
|
return Pair(
|
||||||
|
newTypeParameters.mapIndexed { index, builder -> builder?.build() ?: member.typeParameters[index] },
|
||||||
|
ChainedSubstitutor(substitutor, additionalSubstitutor)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createFakeOverrideProperty(original: FirPropertySymbol): FirPropertySymbol {
|
private fun createFakeOverrideProperty(original: FirPropertySymbol): FirPropertySymbol {
|
||||||
@@ -193,7 +228,16 @@ class FirClassSubstitutionScope(
|
|||||||
return original
|
return original
|
||||||
}
|
}
|
||||||
|
|
||||||
return createFakeOverrideProperty(session, member, original, newReceiverType, newReturnType, newTypeParameters, derivedClassId)
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return createFakeOverrideProperty(
|
||||||
|
session,
|
||||||
|
member,
|
||||||
|
original,
|
||||||
|
newReceiverType,
|
||||||
|
newReturnType,
|
||||||
|
newTypeParameters as List<FirTypeParameter>,
|
||||||
|
derivedClassId
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createFakeOverrideField(original: FirFieldSymbol): FirFieldSymbol {
|
private fun createFakeOverrideField(original: FirFieldSymbol): FirFieldSymbol {
|
||||||
@@ -369,6 +413,61 @@ class FirClassSubstitutionScope(
|
|||||||
delegateGetter = function
|
delegateGetter = function
|
||||||
}.symbol
|
}.symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createFakeOverrideConstructor(
|
||||||
|
fakeOverrideSymbol: FirConstructorSymbol,
|
||||||
|
session: FirSession,
|
||||||
|
baseConstructor: FirConstructor,
|
||||||
|
newReceiverType: ConeKotlinType? = null,
|
||||||
|
newReturnType: ConeKotlinType? = null,
|
||||||
|
newParameterTypes: List<ConeKotlinType?>? = null,
|
||||||
|
newTypeParameters: List<FirTypeParameterRef>? = null
|
||||||
|
): FirConstructor {
|
||||||
|
// TODO: consider using here some light-weight functions instead of pseudo-real FirMemberFunctionImpl
|
||||||
|
// As second alternative, we can invent some light-weight kind of FirRegularClass
|
||||||
|
return buildConstructor {
|
||||||
|
source = baseConstructor.source
|
||||||
|
this.session = session
|
||||||
|
returnTypeRef = baseConstructor.returnTypeRef.withReplacedReturnType(newReturnType)
|
||||||
|
receiverTypeRef = baseConstructor.receiverTypeRef?.withReplacedConeType(newReceiverType)
|
||||||
|
status = baseConstructor.status
|
||||||
|
symbol = fakeOverrideSymbol
|
||||||
|
annotations += baseConstructor.annotations
|
||||||
|
resolvePhase = baseConstructor.resolvePhase
|
||||||
|
valueParameters += baseConstructor.valueParameters.zip(
|
||||||
|
newParameterTypes ?: List(baseConstructor.valueParameters.size) { null }
|
||||||
|
) { valueParameter, newType ->
|
||||||
|
buildValueParameter {
|
||||||
|
source = valueParameter.source
|
||||||
|
this.session = session
|
||||||
|
returnTypeRef = valueParameter.returnTypeRef.withReplacedConeType(newType)
|
||||||
|
name = valueParameter.name
|
||||||
|
symbol = FirVariableSymbol(valueParameter.symbol.callableId)
|
||||||
|
defaultValue = valueParameter.defaultValue
|
||||||
|
isCrossinline = valueParameter.isCrossinline
|
||||||
|
isNoinline = valueParameter.isNoinline
|
||||||
|
isVararg = valueParameter.isVararg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Fix the hack for org.jetbrains.kotlin.fir.backend.Fir2IrVisitor.addFakeOverrides
|
||||||
|
// We might have added baseFunction.typeParameters in case new ones are null
|
||||||
|
// But it fails at org.jetbrains.kotlin.ir.AbstractIrTextTestCase.IrVerifier.elementsAreUniqueChecker
|
||||||
|
// because it shares the same declarations of type parameters between two different two functions
|
||||||
|
if (newTypeParameters != null) {
|
||||||
|
typeParameters += newTypeParameters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
|
useSiteMemberScope.processDeclaredConstructors process@{ original ->
|
||||||
|
|
||||||
|
val constructor = fakeOverrideConstructors.getOrPut(original) { createFakeOverrideConstructor(original) }
|
||||||
|
processor(constructor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.scopes
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -26,6 +27,10 @@ abstract class FirScope {
|
|||||||
name: Name,
|
name: Name,
|
||||||
processor: (FirVariableSymbol<*>) -> Unit
|
processor: (FirVariableSymbol<*>) -> Unit
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
open fun processDeclaredConstructors(
|
||||||
|
processor: (FirConstructorSymbol) -> Unit
|
||||||
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class ProcessorAction {
|
enum class ProcessorAction {
|
||||||
|
|||||||
Reference in New Issue
Block a user