diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/MainSessionComponents.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/MainSessionComponents.kt new file mode 100644 index 00000000000..04f2ea1f08c --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/MainSessionComponents.kt @@ -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() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index 097a27f36c1..d38d9436d35 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -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 MutableMap.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, - 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.toTypeProjections(): Array = 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? { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/TypeExpansionUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/TypeExpansionUtils.kt new file mode 100644 index 00000000000..5e446b4ed85 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/TypeExpansionUtils.kt @@ -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) +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt index 93b43d1c0ff..208560e418e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt @@ -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) { diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/resolve/TreeResolveUtils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/resolve/TreeResolveUtils.kt new file mode 100644 index 00000000000..bab010fe8b2 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/resolve/TreeResolveUtils.kt @@ -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, + 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("!") + } +} diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt index 174b5d5bf13..01f3d7bf302 100644 --- a/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt +++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt @@ -177,3 +177,15 @@ inline fun Collection.foldMap(transform: (T) -> R, operation: (R, R) - fun MutableList.trimToSize(newSize: Int) { subList(newSize, size).clear() } + +inline fun MutableMap.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 + } +}