[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.types.ConeClassLikeType
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
sealed class FirSinceKotlinAccessibility {
@@ -65,7 +65,7 @@ private fun FirAnnotatedDeclaration.getOwnSinceKotlinVersion(session: FirSession
// TODO: use-site targeted annotations
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)
if (apiVersion != null) {
// 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.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.types.EnrichedProjectionKind
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
object FirClassVarianceChecker : FirClassChecker() {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -148,11 +148,11 @@ object FirClassVarianceChecker : FirClassChecker() {
val typeArgumentType = typeArgument.type ?: continue
val newVariance = when (TypeCheckingProcedure.getEffectiveProjectionKind(paramVariance, argVariance)!!) {
TypeCheckingProcedure.EnrichedProjectionKind.OUT -> variance
TypeCheckingProcedure.EnrichedProjectionKind.IN -> variance.opposite()
TypeCheckingProcedure.EnrichedProjectionKind.INV -> Variance.INVARIANT
TypeCheckingProcedure.EnrichedProjectionKind.STAR -> null // CONFLICTING_PROJECTION error was reported
val newVariance = when (EnrichedProjectionKind.getEffectiveProjectionKind(paramVariance, argVariance)) {
EnrichedProjectionKind.OUT -> variance
EnrichedProjectionKind.IN -> variance.opposite()
EnrichedProjectionKind.INV -> Variance.INVARIANT
EnrichedProjectionKind.STAR -> null // CONFLICTING_PROJECTION error was reported
}
if (newVariance != null) {
@@ -10,7 +10,6 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import javaslang.Function2
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.Returns
@@ -83,12 +82,15 @@ object FirOperatorModifierChecker : FirSimpleFunctionChecker() {
}
interface Check : Function2<CheckerContext, FirSimpleFunction, String?> {
override fun apply(t1: CheckerContext, t2: FirSimpleFunction): String? = check(t1, t2)
private interface Check : (CheckerContext, FirSimpleFunction) -> String? {
override fun invoke(p1: CheckerContext, p2: FirSimpleFunction): String? {
return check(p1, p2)
}
fun check(context: CheckerContext, function: FirSimpleFunction): String?
}
object Checks {
private object Checks {
fun simple(message: String, predicate: (FirSimpleFunction) -> Boolean) = object : Check {
override fun check(context: CheckerContext, function: FirSimpleFunction): String? = message.takeIf { !predicate(function) }
}
@@ -156,10 +158,10 @@ object Checks {
}
@OptIn(ExperimentalStdlibApi::class)
object OperatorFunctionChecks {
private object OperatorFunctionChecks {
//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(
SET,
@@ -218,4 +220,4 @@ object OperatorFunctionChecks {
private fun MutableList<Pair<Regex, List<Check>>>.checkFor(regex: Regex, vararg checks: Check) {
add(regex to checks.asList())
}
}
}
@@ -33,15 +33,13 @@ import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
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
object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
private val RESTRICTS_SUSPENSION_CLASS_ID =
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)
@@ -56,7 +54,7 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
if (reference is FirResolvedCallableReference) return
when (symbol) {
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
}
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.createTypeBinding
import org.jetbrains.kotlin.resolve.typeBinding.createTypeBindingForReturnType
import org.jetbrains.kotlin.types.EnrichedProjectionKind
import org.jetbrains.kotlin.types.KotlinType
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 newPosition = when (projectionKind) {
TypeCheckingProcedure.EnrichedProjectionKind.OUT -> position
TypeCheckingProcedure.EnrichedProjectionKind.IN -> position.opposite()
TypeCheckingProcedure.EnrichedProjectionKind.INV -> Variance.INVARIANT
TypeCheckingProcedure.EnrichedProjectionKind.STAR -> null // CONFLICTING_PROJECTION error was reported
EnrichedProjectionKind.OUT -> position
EnrichedProjectionKind.IN -> position.opposite()
EnrichedProjectionKind.INV -> Variance.INVARIANT
EnrichedProjectionKind.STAR -> null // CONFLICTING_PROJECTION error was reported
}
if (newPosition != null) {
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 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 }
@@ -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());
}
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(
@NotNull TypeParameterDescriptor typeParameter,
@NotNull TypeProjection typeArgument
@@ -166,26 +149,7 @@ public class TypeCheckingProcedure {
@NotNull Variance typeParameterVariance,
@NotNull Variance typeArgumentVariance
) {
Variance a = typeParameterVariance;
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);
return EnrichedProjectionKind.Companion.getEffectiveProjectionKind(typeParameterVariance, typeArgumentVariance);
}
public boolean isSubtypeOf(@NotNull KotlinType subtype, @NotNull KotlinType supertype) {