[FIR] Remove all usages of classes and methods from FE 1.0 from FIR checkers

This commit is contained in:
Dmitriy Novozhilov
2021-09-09 10:16:58 +03:00
committed by TeamCityServer
parent 0260bf8767
commit 15b77045ee
8 changed files with 90 additions and 60 deletions
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.resolve.SINCE_KOTLIN_FQ_NAME import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.resolve.checkers.OptInNames import org.jetbrains.kotlin.resolve.checkers.OptInNames
sealed class FirSinceKotlinAccessibility { sealed class FirSinceKotlinAccessibility {
@@ -65,7 +65,7 @@ private fun FirAnnotatedDeclaration.getOwnSinceKotlinVersion(session: FirSession
// TODO: use-site targeted annotations // TODO: use-site targeted annotations
fun FirAnnotatedDeclaration.consider() { fun FirAnnotatedDeclaration.consider() {
val sinceKotlinSingleArgument = getAnnotationByFqName(SINCE_KOTLIN_FQ_NAME)?.arguments?.singleOrNull() val sinceKotlinSingleArgument = getAnnotationByClassId(StandardClassIds.SinceKotlin)?.arguments?.singleOrNull()
val apiVersion = ((sinceKotlinSingleArgument as? FirConstExpression<*>)?.value as? String)?.let(ApiVersion.Companion::parse) val apiVersion = ((sinceKotlinSingleArgument as? FirConstExpression<*>)?.value as? String)?.let(ApiVersion.Companion::parse)
if (apiVersion != null) { if (apiVersion != null) {
// TODO: combine wasExperimentalMarkerClasses in case of several associated declarations with the same maximal API version // TODO: combine wasExperimentalMarkerClasses in case of several associated declarations with the same maximal API version
@@ -18,8 +18,8 @@ import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.types.EnrichedProjectionKind
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
object FirClassVarianceChecker : FirClassChecker() { object FirClassVarianceChecker : FirClassChecker() {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -148,11 +148,11 @@ object FirClassVarianceChecker : FirClassChecker() {
val typeArgumentType = typeArgument.type ?: continue val typeArgumentType = typeArgument.type ?: continue
val newVariance = when (TypeCheckingProcedure.getEffectiveProjectionKind(paramVariance, argVariance)!!) { val newVariance = when (EnrichedProjectionKind.getEffectiveProjectionKind(paramVariance, argVariance)) {
TypeCheckingProcedure.EnrichedProjectionKind.OUT -> variance EnrichedProjectionKind.OUT -> variance
TypeCheckingProcedure.EnrichedProjectionKind.IN -> variance.opposite() EnrichedProjectionKind.IN -> variance.opposite()
TypeCheckingProcedure.EnrichedProjectionKind.INV -> Variance.INVARIANT EnrichedProjectionKind.INV -> Variance.INVARIANT
TypeCheckingProcedure.EnrichedProjectionKind.STAR -> null // CONFLICTING_PROJECTION error was reported EnrichedProjectionKind.STAR -> null // CONFLICTING_PROJECTION error was reported
} }
if (newVariance != null) { if (newVariance != null) {
@@ -10,7 +10,6 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import javaslang.Function2
import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.Returns import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.Returns
@@ -83,12 +82,15 @@ object FirOperatorModifierChecker : FirSimpleFunctionChecker() {
} }
interface Check : Function2<CheckerContext, FirSimpleFunction, String?> { private interface Check : (CheckerContext, FirSimpleFunction) -> String? {
override fun apply(t1: CheckerContext, t2: FirSimpleFunction): String? = check(t1, t2) override fun invoke(p1: CheckerContext, p2: FirSimpleFunction): String? {
return check(p1, p2)
}
fun check(context: CheckerContext, function: FirSimpleFunction): String? fun check(context: CheckerContext, function: FirSimpleFunction): String?
} }
object Checks { private object Checks {
fun simple(message: String, predicate: (FirSimpleFunction) -> Boolean) = object : Check { fun simple(message: String, predicate: (FirSimpleFunction) -> Boolean) = object : Check {
override fun check(context: CheckerContext, function: FirSimpleFunction): String? = message.takeIf { !predicate(function) } override fun check(context: CheckerContext, function: FirSimpleFunction): String? = message.takeIf { !predicate(function) }
} }
@@ -156,10 +158,10 @@ object Checks {
} }
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
object OperatorFunctionChecks { private object OperatorFunctionChecks {
//reimplementation of org.jetbrains.kotlin.util.OperatorChecks for FIR //reimplementation of org.jetbrains.kotlin.util.OperatorChecks for FIR
val checksByName: Map<Name, List<Check>> = buildMap<Name, List<Check>> { val checksByName: Map<Name, List<Check>> = buildMap {
checkFor(GET, memberOrExtension, ValueParametersCount.atLeast(1)) checkFor(GET, memberOrExtension, ValueParametersCount.atLeast(1))
checkFor( checkFor(
SET, SET,
@@ -33,15 +33,13 @@ import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.resolve.calls.checkers.COROUTINE_CONTEXT_FQ_NAME
import org.jetbrains.kotlin.serialization.deserialization.KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() { object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
private val RESTRICTS_SUSPENSION_CLASS_ID = private val RESTRICTS_SUSPENSION_CLASS_ID =
ClassId(StandardNames.COROUTINES_PACKAGE_FQ_NAME, Name.identifier("RestrictsSuspension")) ClassId(StandardNames.COROUTINES_PACKAGE_FQ_NAME, Name.identifier("RestrictsSuspension"))
private val BUILTIN_SUSPEND_NAME = KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME.shortName() private val BUILTIN_SUSPEND_NAME = StandardClassIds.suspend.callableName
internal val KOTLIN_SUSPEND_BUILT_IN_FUNCTION_CALLABLE_ID = CallableId(StandardClassIds.BASE_KOTLIN_PACKAGE, BUILTIN_SUSPEND_NAME) internal val KOTLIN_SUSPEND_BUILT_IN_FUNCTION_CALLABLE_ID = CallableId(StandardClassIds.BASE_KOTLIN_PACKAGE, BUILTIN_SUSPEND_NAME)
@@ -56,7 +54,7 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
if (reference is FirResolvedCallableReference) return if (reference is FirResolvedCallableReference) return
when (symbol) { when (symbol) {
is FirNamedFunctionSymbol -> if (!symbol.isSuspend) return is FirNamedFunctionSymbol -> if (!symbol.isSuspend) return
is FirPropertySymbol -> if (symbol.callableId.asSingleFqName() != COROUTINE_CONTEXT_FQ_NAME) return is FirPropertySymbol -> if (symbol.callableId != StandardClassIds.coroutineContext) return
else -> return else -> return
} }
val enclosingSuspendFunction = findEnclosingSuspendFunction(context) val enclosingSuspendFunction = findEnclosingSuspendFunction(context)
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.resolve.typeBinding.TypeBinding import org.jetbrains.kotlin.resolve.typeBinding.TypeBinding
import org.jetbrains.kotlin.resolve.typeBinding.createTypeBinding import org.jetbrains.kotlin.resolve.typeBinding.createTypeBinding
import org.jetbrains.kotlin.resolve.typeBinding.createTypeBindingForReturnType import org.jetbrains.kotlin.resolve.typeBinding.createTypeBindingForReturnType
import org.jetbrains.kotlin.types.EnrichedProjectionKind
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.Variance.* import org.jetbrains.kotlin.types.Variance.*
@@ -164,10 +165,10 @@ class VarianceCheckerCore(
val projectionKind = TypeCheckingProcedure.getEffectiveProjectionKind(argument.typeParameter!!, argument.projection)!! val projectionKind = TypeCheckingProcedure.getEffectiveProjectionKind(argument.typeParameter!!, argument.projection)!!
val newPosition = when (projectionKind) { val newPosition = when (projectionKind) {
TypeCheckingProcedure.EnrichedProjectionKind.OUT -> position EnrichedProjectionKind.OUT -> position
TypeCheckingProcedure.EnrichedProjectionKind.IN -> position.opposite() EnrichedProjectionKind.IN -> position.opposite()
TypeCheckingProcedure.EnrichedProjectionKind.INV -> Variance.INVARIANT EnrichedProjectionKind.INV -> Variance.INVARIANT
TypeCheckingProcedure.EnrichedProjectionKind.STAR -> null // CONFLICTING_PROJECTION error was reported EnrichedProjectionKind.STAR -> null // CONFLICTING_PROJECTION error was reported
} }
if (newPosition != null) { if (newPosition != null) {
noError = noError and argument.binding.checkTypePosition(containingType, newPosition) noError = noError and argument.binding.checkTypePosition(containingType, newPosition)
@@ -109,6 +109,11 @@ object StandardClassIds {
val EnhancedNullability = ClassId(FqName("kotlin.jvm.internal"), Name.identifier("EnhancedNullability")) val EnhancedNullability = ClassId(FqName("kotlin.jvm.internal"), Name.identifier("EnhancedNullability"))
val PublishedApi = "PublishedApi".baseId() val PublishedApi = "PublishedApi".baseId()
val SinceKotlin = "SinceKotlin".baseId()
val coroutineContext = CallableId(StandardNames.COROUTINES_PACKAGE_FQ_NAME, Name.identifier("coroutineContext"))
val suspend = CallableId(BASE_KOTLIN_PACKAGE, Name.identifier("suspend"))
} }
private fun <K, V> Map<K, V>.inverseMap() = entries.associate { (k, v) -> v to k } private fun <K, V> Map<K, V>.inverseMap() = entries.associate { (k, v) -> v to k }
@@ -0,0 +1,60 @@
/*
* Copyright 2010-2021 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.types
enum class EnrichedProjectionKind {
IN, OUT, INV, STAR;
companion object {
@JvmStatic
fun fromVariance(variance: Variance): EnrichedProjectionKind {
return when (variance) {
Variance.INVARIANT -> INV
Variance.IN_VARIANCE -> IN
Variance.OUT_VARIANCE -> OUT
}
}
// If class C<out T> then C<T> and C<out T> mean the same
// out * out = out
// out * in = *
// out * inv = out
//
// in * out = *
// in * in = in
// in * inv = in
//
// inv * out = out
// inv * in = out
// inv * inv = inv
fun getEffectiveProjectionKind(
typeParameterVariance: Variance,
typeArgumentVariance: Variance
): EnrichedProjectionKind {
var a = typeParameterVariance
var b = typeArgumentVariance
// If they are not both invariant, let's make b not invariant for sure
if (b === Variance.INVARIANT) {
val t = a
a = b
b = t
}
// Opposites yield STAR
if (a === Variance.IN_VARIANCE && b === Variance.OUT_VARIANCE) {
return STAR
}
return if (a === Variance.OUT_VARIANCE && b === Variance.IN_VARIANCE) {
STAR
} else fromVariance(b)
// If they are not opposite, return b, because b is either equal to a or b is in/out and a is inv
}
}
}
@@ -126,23 +126,6 @@ public class TypeCheckingProcedure {
&& isSubtypeOf(inflexibleType, FlexibleTypesKt.asFlexibleType(flexibleType).getUpperBound()); && isSubtypeOf(inflexibleType, FlexibleTypesKt.asFlexibleType(flexibleType).getUpperBound());
} }
public enum EnrichedProjectionKind {
IN, OUT, INV, STAR;
@NotNull
public static EnrichedProjectionKind fromVariance(@NotNull Variance variance) {
switch (variance) {
case INVARIANT:
return INV;
case IN_VARIANCE:
return IN;
case OUT_VARIANCE:
return OUT;
}
throw new IllegalStateException("Unknown variance");
}
}
public static EnrichedProjectionKind getEffectiveProjectionKind( public static EnrichedProjectionKind getEffectiveProjectionKind(
@NotNull TypeParameterDescriptor typeParameter, @NotNull TypeParameterDescriptor typeParameter,
@NotNull TypeProjection typeArgument @NotNull TypeProjection typeArgument
@@ -166,26 +149,7 @@ public class TypeCheckingProcedure {
@NotNull Variance typeParameterVariance, @NotNull Variance typeParameterVariance,
@NotNull Variance typeArgumentVariance @NotNull Variance typeArgumentVariance
) { ) {
Variance a = typeParameterVariance; return EnrichedProjectionKind.Companion.getEffectiveProjectionKind(typeParameterVariance, typeArgumentVariance);
Variance b = typeArgumentVariance;
// If they are not both invariant, let's make b not invariant for sure
if (b == INVARIANT) {
Variance t = a;
a = b;
b = t;
}
// Opposites yield STAR
if (a == IN_VARIANCE && b == OUT_VARIANCE) {
return EnrichedProjectionKind.STAR;
}
if (a == OUT_VARIANCE && b == IN_VARIANCE) {
return EnrichedProjectionKind.STAR;
}
// If they are not opposite, return b, because b is either equal to a or b is in/out and a is inv
return EnrichedProjectionKind.fromVariance(b);
} }
public boolean isSubtypeOf(@NotNull KotlinType subtype, @NotNull KotlinType supertype) { public boolean isSubtypeOf(@NotNull KotlinType subtype, @NotNull KotlinType supertype) {