[FIR] Split ResolveUtils.kt from :resolve to separate files
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirEffectiveVisibilityResolver
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirDeclaredMemberScopeProvider
|
||||
import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
|
||||
|
||||
val FirSession.firSymbolProvider: FirSymbolProvider by FirSession.sessionComponentAccessor()
|
||||
val FirSession.firProvider: FirProvider by FirSession.sessionComponentAccessor()
|
||||
val FirSession.correspondingSupertypesCache: FirCorrespondingSupertypesCache by FirSession.sessionComponentAccessor()
|
||||
val FirSession.declaredMemberScopeProvider: FirDeclaredMemberScopeProvider by FirSession.sessionComponentAccessor()
|
||||
val FirSession.qualifierResolver: FirQualifierResolver by FirSession.sessionComponentAccessor()
|
||||
val FirSession.typeResolver: FirTypeResolver by FirSession.sessionComponentAccessor()
|
||||
val FirSession.effectiveVisibilityResolver: FirEffectiveVisibilityResolver by FirSession.sessionComponentAccessor()
|
||||
@@ -21,9 +21,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.*
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirDeclaredMemberScopeProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
@@ -31,147 +29,10 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
inline fun <K, V, VA : V> MutableMap<K, V>.getOrPut(key: K, defaultValue: (K) -> VA, postCompute: (VA) -> Unit): V {
|
||||
val value = get(key)
|
||||
return if (value == null) {
|
||||
val answer = defaultValue(key)
|
||||
put(key, answer)
|
||||
postCompute(answer)
|
||||
answer
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
val FirSession.firSymbolProvider: FirSymbolProvider by FirSession.sessionComponentAccessor()
|
||||
val FirSession.firProvider: FirProvider by FirSession.sessionComponentAccessor()
|
||||
val FirSession.correspondingSupertypesCache: FirCorrespondingSupertypesCache by FirSession.sessionComponentAccessor()
|
||||
val FirSession.declaredMemberScopeProvider: FirDeclaredMemberScopeProvider by FirSession.sessionComponentAccessor()
|
||||
val FirSession.qualifierResolver: FirQualifierResolver by FirSession.sessionComponentAccessor()
|
||||
val FirSession.typeResolver: FirTypeResolver by FirSession.sessionComponentAccessor()
|
||||
val FirSession.effectiveVisibilityResolver: FirEffectiveVisibilityResolver by FirSession.sessionComponentAccessor()
|
||||
|
||||
fun ConeClassLikeType.fullyExpandedType(
|
||||
useSiteSession: FirSession,
|
||||
expandedConeType: (FirTypeAlias) -> ConeClassLikeType? = FirTypeAlias::expandedConeType,
|
||||
): ConeClassLikeType {
|
||||
if (this is ConeClassLikeTypeImpl) {
|
||||
val expandedTypeAndSession = cachedExpandedType
|
||||
if (expandedTypeAndSession != null && expandedTypeAndSession.first === useSiteSession) {
|
||||
return expandedTypeAndSession.second
|
||||
}
|
||||
|
||||
val computedExpandedType = fullyExpandedTypeNoCache(useSiteSession, expandedConeType)
|
||||
cachedExpandedType = Pair(useSiteSession, computedExpandedType)
|
||||
return computedExpandedType
|
||||
}
|
||||
|
||||
return fullyExpandedTypeNoCache(useSiteSession, expandedConeType)
|
||||
}
|
||||
|
||||
fun ConeKotlinType.fullyExpandedType(
|
||||
useSiteSession: FirSession
|
||||
): ConeKotlinType = when (this) {
|
||||
is ConeFlexibleType ->
|
||||
ConeFlexibleType(lowerBound.fullyExpandedType(useSiteSession), upperBound.fullyExpandedType(useSiteSession))
|
||||
is ConeClassLikeType -> fullyExpandedType(useSiteSession)
|
||||
else -> this
|
||||
}
|
||||
|
||||
private fun ConeClassLikeType.fullyExpandedTypeNoCache(
|
||||
useSiteSession: FirSession,
|
||||
expandedConeType: (FirTypeAlias) -> ConeClassLikeType?,
|
||||
): ConeClassLikeType {
|
||||
val directExpansionType = directExpansionType(useSiteSession, expandedConeType) ?: return this
|
||||
return directExpansionType.fullyExpandedType(useSiteSession, expandedConeType)
|
||||
}
|
||||
|
||||
fun ConeClassLikeType.directExpansionType(
|
||||
useSiteSession: FirSession,
|
||||
expandedConeType: (FirTypeAlias) -> ConeClassLikeType? = FirTypeAlias::expandedConeType,
|
||||
): ConeClassLikeType? {
|
||||
val typeAliasSymbol = lookupTag.toSymbol(useSiteSession) as? FirTypeAliasSymbol ?: return null
|
||||
val typeAlias = typeAliasSymbol.fir
|
||||
|
||||
val resultType = expandedConeType(typeAlias)?.applyNullabilityFrom(this) ?: return null
|
||||
|
||||
if (resultType.typeArguments.isEmpty()) return resultType
|
||||
return mapTypeAliasArguments(typeAlias, this, resultType) as? ConeClassLikeType
|
||||
}
|
||||
|
||||
private fun ConeClassLikeType.applyNullabilityFrom(abbreviation: ConeClassLikeType): ConeClassLikeType {
|
||||
if (abbreviation.isMarkedNullable) return withNullability(ConeNullability.NULLABLE)
|
||||
return this
|
||||
}
|
||||
|
||||
private fun mapTypeAliasArguments(
|
||||
typeAlias: FirTypeAlias,
|
||||
abbreviatedType: ConeClassLikeType,
|
||||
resultingType: ConeClassLikeType,
|
||||
): ConeKotlinType {
|
||||
val typeAliasMap = typeAlias.typeParameters.map { it.symbol }.zip(abbreviatedType.typeArguments).toMap()
|
||||
|
||||
val substitutor = object : AbstractConeSubstitutor() {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun substituteArgument(projection: ConeTypeProjection): ConeTypeProjection? {
|
||||
val type = (projection as? ConeKotlinTypeProjection)?.type ?: return null
|
||||
val symbol = (type as? ConeTypeParameterType)?.lookupTag?.toSymbol() ?: return super.substituteArgument(projection)
|
||||
val mappedProjection = typeAliasMap[symbol] ?: return super.substituteArgument(projection)
|
||||
val mappedType = (mappedProjection as? ConeKotlinTypeProjection)?.type ?: return mappedProjection
|
||||
|
||||
@Suppress("MoveVariableDeclarationIntoWhen")
|
||||
val resultingKind = mappedProjection.kind + projection.kind
|
||||
return when (resultingKind) {
|
||||
ProjectionKind.STAR -> ConeStarProjection
|
||||
ProjectionKind.IN -> ConeKotlinTypeProjectionIn(mappedType)
|
||||
ProjectionKind.OUT -> ConeKotlinTypeProjectionOut(mappedType)
|
||||
ProjectionKind.INVARIANT -> mappedType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return substitutor.substituteOrSelf(resultingType)
|
||||
}
|
||||
|
||||
fun FirClassifierSymbol<*>.constructType(
|
||||
typeArguments: Array<ConeTypeProjection>,
|
||||
isNullable: Boolean,
|
||||
attributes: ConeAttributes = ConeAttributes.Empty
|
||||
): ConeLookupTagBasedType {
|
||||
return when (this) {
|
||||
is FirTypeParameterSymbol -> {
|
||||
ConeTypeParameterTypeImpl(this.toLookupTag(), isNullable, attributes)
|
||||
}
|
||||
is FirClassSymbol -> {
|
||||
val errorTypeRef = typeArguments.find {
|
||||
it is ConeClassErrorType
|
||||
}
|
||||
if (errorTypeRef is ConeClassErrorType) {
|
||||
ConeClassErrorType(errorTypeRef.diagnostic)
|
||||
} else {
|
||||
ConeClassLikeTypeImpl(this.toLookupTag(), typeArguments, isNullable, attributes)
|
||||
}
|
||||
}
|
||||
is FirTypeAliasSymbol -> {
|
||||
ConeClassLikeTypeImpl(
|
||||
this.toLookupTag(),
|
||||
typeArguments = typeArguments,
|
||||
isNullable = isNullable,
|
||||
attributes = attributes
|
||||
)
|
||||
}
|
||||
else -> error("!")
|
||||
}
|
||||
}
|
||||
|
||||
fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> =
|
||||
asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray()
|
||||
|
||||
@@ -391,26 +252,26 @@ fun BodyResolveComponents.transformQualifiedAccessUsingSmartcastInfo(qualifiedAc
|
||||
}
|
||||
}
|
||||
|
||||
fun CallableId.isInvoke() =
|
||||
fun CallableId.isInvoke(): Boolean =
|
||||
isKFunctionInvoke()
|
||||
|| callableName.asString() == "invoke"
|
||||
&& className?.asString()?.startsWith("Function") == true
|
||||
&& packageName == StandardNames.BUILT_INS_PACKAGE_FQ_NAME
|
||||
|
||||
fun CallableId.isKFunctionInvoke() =
|
||||
fun CallableId.isKFunctionInvoke(): Boolean =
|
||||
callableName.asString() == "invoke"
|
||||
&& className?.asString()?.startsWith("KFunction") == true
|
||||
&& packageName.asString() == "kotlin.reflect"
|
||||
|
||||
fun CallableId.isIteratorNext() =
|
||||
fun CallableId.isIteratorNext(): Boolean =
|
||||
callableName.asString() == "next" && className?.asString()?.endsWith("Iterator") == true
|
||||
&& packageName.asString() == "kotlin.collections"
|
||||
|
||||
fun CallableId.isIteratorHasNext() =
|
||||
fun CallableId.isIteratorHasNext(): Boolean =
|
||||
callableName.asString() == "hasNext" && className?.asString()?.endsWith("Iterator") == true
|
||||
&& packageName.asString() == "kotlin.collections"
|
||||
|
||||
fun CallableId.isIterator() =
|
||||
fun CallableId.isIterator(): Boolean =
|
||||
callableName.asString() == "iterator" && packageName.asString() == "kotlin.collections"
|
||||
|
||||
fun FirAnnotationCall.fqName(session: FirSession): FqName? {
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
||||
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
|
||||
fun ConeClassLikeType.fullyExpandedType(
|
||||
useSiteSession: FirSession,
|
||||
expandedConeType: (FirTypeAlias) -> ConeClassLikeType? = FirTypeAlias::expandedConeType,
|
||||
): ConeClassLikeType {
|
||||
if (this is ConeClassLikeTypeImpl) {
|
||||
val expandedTypeAndSession = cachedExpandedType
|
||||
if (expandedTypeAndSession != null && expandedTypeAndSession.first === useSiteSession) {
|
||||
return expandedTypeAndSession.second
|
||||
}
|
||||
|
||||
val computedExpandedType = fullyExpandedTypeNoCache(useSiteSession, expandedConeType)
|
||||
cachedExpandedType = Pair(useSiteSession, computedExpandedType)
|
||||
return computedExpandedType
|
||||
}
|
||||
|
||||
return fullyExpandedTypeNoCache(useSiteSession, expandedConeType)
|
||||
}
|
||||
|
||||
fun ConeKotlinType.fullyExpandedType(
|
||||
useSiteSession: FirSession
|
||||
): ConeKotlinType = when (this) {
|
||||
is ConeFlexibleType ->
|
||||
ConeFlexibleType(lowerBound.fullyExpandedType(useSiteSession), upperBound.fullyExpandedType(useSiteSession))
|
||||
is ConeClassLikeType -> fullyExpandedType(useSiteSession)
|
||||
else -> this
|
||||
}
|
||||
|
||||
private fun ConeClassLikeType.fullyExpandedTypeNoCache(
|
||||
useSiteSession: FirSession,
|
||||
expandedConeType: (FirTypeAlias) -> ConeClassLikeType?,
|
||||
): ConeClassLikeType {
|
||||
val directExpansionType = directExpansionType(useSiteSession, expandedConeType) ?: return this
|
||||
return directExpansionType.fullyExpandedType(useSiteSession, expandedConeType)
|
||||
}
|
||||
|
||||
fun ConeClassLikeType.directExpansionType(
|
||||
useSiteSession: FirSession,
|
||||
expandedConeType: (FirTypeAlias) -> ConeClassLikeType? = FirTypeAlias::expandedConeType,
|
||||
): ConeClassLikeType? {
|
||||
val typeAliasSymbol = lookupTag.toSymbol(useSiteSession) as? FirTypeAliasSymbol ?: return null
|
||||
val typeAlias = typeAliasSymbol.fir
|
||||
|
||||
val resultType = expandedConeType(typeAlias)?.applyNullabilityFrom(this) ?: return null
|
||||
|
||||
if (resultType.typeArguments.isEmpty()) return resultType
|
||||
return mapTypeAliasArguments(typeAlias, this, resultType) as? ConeClassLikeType
|
||||
}
|
||||
|
||||
private fun ConeClassLikeType.applyNullabilityFrom(abbreviation: ConeClassLikeType): ConeClassLikeType {
|
||||
if (abbreviation.isMarkedNullable) return withNullability(ConeNullability.NULLABLE)
|
||||
return this
|
||||
}
|
||||
|
||||
private fun mapTypeAliasArguments(
|
||||
typeAlias: FirTypeAlias,
|
||||
abbreviatedType: ConeClassLikeType,
|
||||
resultingType: ConeClassLikeType,
|
||||
): ConeKotlinType {
|
||||
val typeAliasMap = typeAlias.typeParameters.map { it.symbol }.zip(abbreviatedType.typeArguments).toMap()
|
||||
|
||||
val substitutor = object : AbstractConeSubstitutor() {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun substituteArgument(projection: ConeTypeProjection): ConeTypeProjection? {
|
||||
val type = (projection as? ConeKotlinTypeProjection)?.type ?: return null
|
||||
val symbol = (type as? ConeTypeParameterType)?.lookupTag?.toSymbol() ?: return super.substituteArgument(projection)
|
||||
val mappedProjection = typeAliasMap[symbol] ?: return super.substituteArgument(projection)
|
||||
val mappedType = (mappedProjection as? ConeKotlinTypeProjection)?.type ?: return mappedProjection
|
||||
|
||||
@Suppress("MoveVariableDeclarationIntoWhen")
|
||||
val resultingKind = mappedProjection.kind + projection.kind
|
||||
return when (resultingKind) {
|
||||
ProjectionKind.STAR -> ConeStarProjection
|
||||
ProjectionKind.IN -> ConeKotlinTypeProjectionIn(mappedType)
|
||||
ProjectionKind.OUT -> ConeKotlinTypeProjectionOut(mappedType)
|
||||
ProjectionKind.INVARIANT -> mappedType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return substitutor.substituteOrSelf(resultingType)
|
||||
}
|
||||
+1
-1
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.fir.deserialization.FirBuiltinAnnotationDeserializer
|
||||
import org.jetbrains.kotlin.fir.deserialization.FirConstDeserializer
|
||||
import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext
|
||||
import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.getOrPut
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
|
||||
@@ -44,6 +43,7 @@ import org.jetbrains.kotlin.serialization.deserialization.getName
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.getOrPut
|
||||
import java.io.InputStream
|
||||
|
||||
class FirBuiltinSymbolProvider(session: FirSession, val kotlinScopeProvider: KotlinScopeProvider) : FirSymbolProvider(session) {
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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
|
||||
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeAttributes
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
||||
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeProjection
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
|
||||
fun FirClassifierSymbol<*>.constructType(
|
||||
typeArguments: Array<ConeTypeProjection>,
|
||||
isNullable: Boolean,
|
||||
attributes: ConeAttributes = ConeAttributes.Empty
|
||||
): ConeLookupTagBasedType {
|
||||
return when (this) {
|
||||
is FirTypeParameterSymbol -> {
|
||||
ConeTypeParameterTypeImpl(this.toLookupTag(), isNullable, attributes)
|
||||
}
|
||||
is FirClassSymbol -> {
|
||||
val errorTypeRef = typeArguments.find {
|
||||
it is ConeClassErrorType
|
||||
}
|
||||
if (errorTypeRef is ConeClassErrorType) {
|
||||
ConeClassErrorType(errorTypeRef.diagnostic)
|
||||
} else {
|
||||
ConeClassLikeTypeImpl(this.toLookupTag(), typeArguments, isNullable, attributes)
|
||||
}
|
||||
}
|
||||
is FirTypeAliasSymbol -> {
|
||||
ConeClassLikeTypeImpl(
|
||||
this.toLookupTag(),
|
||||
typeArguments = typeArguments,
|
||||
isNullable = isNullable,
|
||||
attributes = attributes
|
||||
)
|
||||
}
|
||||
else -> error("!")
|
||||
}
|
||||
}
|
||||
@@ -177,3 +177,15 @@ inline fun <T, R> Collection<T>.foldMap(transform: (T) -> R, operation: (R, R) -
|
||||
fun <E> MutableList<E>.trimToSize(newSize: Int) {
|
||||
subList(newSize, size).clear()
|
||||
}
|
||||
|
||||
inline fun <K, V, VA : V> MutableMap<K, V>.getOrPut(key: K, defaultValue: (K) -> VA, postCompute: (VA) -> Unit): V {
|
||||
val value = get(key)
|
||||
return if (value == null) {
|
||||
val answer = defaultValue(key)
|
||||
put(key, answer)
|
||||
postCompute(answer)
|
||||
answer
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user