[FIR] Split ResolveUtils.kt from :resolve to separate files

This commit is contained in:
Dmitriy Novozhilov
2020-08-28 11:32:15 +03:00
parent 6ace4164ff
commit ca031f7ace
6 changed files with 186 additions and 145 deletions
@@ -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)
}
@@ -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
}
}