[JS FIR] Fix review comments
This commit is contained in:
committed by
Space Team
parent
08d158f901
commit
e61a11f0a3
@@ -11,7 +11,7 @@ dependencies {
|
|||||||
api(project(":compiler:fir:checkers"))
|
api(project(":compiler:fir:checkers"))
|
||||||
|
|
||||||
// FE checks for modules use ModuleKind
|
// FE checks for modules use ModuleKind
|
||||||
// This dependency can be removed when we stop supporting PLANE and UMD module systems
|
// This dependency can be removed when we stop supporting PLAIN and UMD module systems
|
||||||
implementation(project(":js:js.serializer"))
|
implementation(project(":js:js.serializer"))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+2
-5
@@ -157,10 +157,7 @@ internal fun FirClass.superClassNotAny(session: FirSession) = superConeTypes
|
|||||||
.filterNot { it.isAny || it.isNullableAny }
|
.filterNot { it.isAny || it.isNullableAny }
|
||||||
.find { it.toSymbol(session)?.classKind == ClassKind.CLASS }
|
.find { it.toSymbol(session)?.classKind == ClassKind.CLASS }
|
||||||
|
|
||||||
internal fun getRootDeclarationSymbol(symbol: FirBasedSymbol<*>, session: FirSession): FirBasedSymbol<*> {
|
internal fun getRootClassLikeSymbolOrSelf(symbol: FirBasedSymbol<*>, session: FirSession): FirBasedSymbol<*> {
|
||||||
return generateSequence(symbol) { it.getContainingClassSymbol(session) }.last()
|
return symbol.getContainingClassSymbol(session)?.let { getRootClassLikeSymbolOrSelf(it, session) } ?: symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun isTopLevelSymbol(symbol: FirBasedSymbol<*>, session: FirSession): Boolean {
|
|
||||||
return symbol.getContainingClassSymbol(session) == null
|
|
||||||
}
|
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ internal fun checkJsModuleUsage(
|
|||||||
val moduleKind = context.session.jsModuleKind
|
val moduleKind = context.session.jsModuleKind
|
||||||
|
|
||||||
val calleeSession = callee.moduleData.session
|
val calleeSession = callee.moduleData.session
|
||||||
val calleeRoot = getRootDeclarationSymbol(callee, calleeSession)
|
val calleeRoot = getRootClassLikeSymbolOrSelf(callee, calleeSession)
|
||||||
val calleeContainingFile = calleeRoot.getContainingFile(calleeSession)
|
val calleeContainingFile = calleeRoot.getContainingFile(calleeSession)
|
||||||
|
|
||||||
val callToModule = calleeRoot.getAnnotationStringParameter(JsStandardClassIds.Annotations.JsModule, calleeSession) != null ||
|
val callToModule = calleeRoot.getAnnotationStringParameter(JsStandardClassIds.Annotations.JsModule, calleeSession) != null ||
|
||||||
|
|||||||
+6
-13
@@ -9,15 +9,12 @@ import org.jetbrains.kotlin.AbstractKtSourceElement
|
|||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
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.expression.FirQualifiedAccessExpressionChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessExpressionChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.analysis.js.checkers.checkJsModuleUsage
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.checkJsModuleUsage
|
||||||
import org.jetbrains.kotlin.fir.analysis.js.checkers.isTopLevelSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeProjectionWithVariance
|
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeOrNull
|
|
||||||
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
|
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
|
||||||
|
|
||||||
object FirJsModuleQualifiedAccessChecker : FirQualifiedAccessExpressionChecker() {
|
object FirJsModuleQualifiedAccessChecker : FirQualifiedAccessExpressionChecker() {
|
||||||
@@ -34,7 +31,7 @@ object FirJsModuleQualifiedAccessChecker : FirQualifiedAccessExpressionChecker()
|
|||||||
expression: FirQualifiedAccessExpression
|
expression: FirQualifiedAccessExpression
|
||||||
): List<Pair<FirBasedSymbol<*>, AbstractKtSourceElement?>> {
|
): List<Pair<FirBasedSymbol<*>, AbstractKtSourceElement?>> {
|
||||||
val calleeSymbol = expression.calleeReference.toResolvedBaseSymbol()
|
val calleeSymbol = expression.calleeReference.toResolvedBaseSymbol()
|
||||||
if (calleeSymbol != null && isTopLevelSymbol(calleeSymbol, calleeSymbol.moduleData.session)) {
|
if (calleeSymbol != null && calleeSymbol.getContainingClassSymbol(calleeSymbol.moduleData.session) == null) {
|
||||||
return listOf(calleeSymbol to expression.calleeReference.source)
|
return listOf(calleeSymbol to expression.calleeReference.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,14 +50,10 @@ object FirJsModuleQualifiedAccessChecker : FirQualifiedAccessExpressionChecker()
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkReifiedTypeParameters(expr: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
private fun checkReifiedTypeParameters(expr: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val functionSymbol = (expr as? FirFunctionCall)?.calleeReference?.toResolvedFunctionSymbol() ?: return
|
(expr as? FirFunctionCall)?.forAllReifiedTypeParameters { type, typeArgument ->
|
||||||
for ((typeParameterSymbol, typeArgument) in functionSymbol.typeParameterSymbols.zip(expr.typeArguments)) {
|
val typeArgumentClass = type.toRegularClassSymbol(context.session) ?: return@forAllReifiedTypeParameters
|
||||||
if (typeParameterSymbol.isReified) {
|
val source = typeArgument.source ?: expr.calleeReference.source ?: expr.source
|
||||||
val type = (typeArgument as? FirTypeProjectionWithVariance)?.typeRef?.coneTypeOrNull ?: continue
|
checkJsModuleUsage(typeArgumentClass, context, reporter, source)
|
||||||
val typeArgumentClass = type.toRegularClassSymbol(context.session) ?: continue
|
|
||||||
val source = typeArgument.source ?: expr.calleeReference.source ?: expr.source
|
|
||||||
checkJsModuleUsage(typeArgumentClass, context, reporter, source)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-17
@@ -12,28 +12,21 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChec
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
|
||||||
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeInterface
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeInterface
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedFunctionSymbol
|
import org.jetbrains.kotlin.fir.expressions.forAllReifiedTypeParameters
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeProjectionWithVariance
|
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeOrNull
|
|
||||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
import org.jetbrains.kotlin.fir.types.toSymbol
|
||||||
|
|
||||||
object FirJsReifiedExternalChecker : FirFunctionCallChecker() {
|
object FirJsReifiedExternalChecker : FirFunctionCallChecker() {
|
||||||
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val functionSymbol = expression.calleeReference.toResolvedFunctionSymbol() ?: return
|
expression.forAllReifiedTypeParameters { type, typeArgument ->
|
||||||
for ((typeParameterSymbol, typeArgument) in functionSymbol.typeParameterSymbols.zip(expression.typeArguments)) {
|
val typeSymbol = type.toSymbol(context.session)
|
||||||
if (typeParameterSymbol.isReified) {
|
if (typeSymbol?.isNativeInterface(context) == true) {
|
||||||
val type = (typeArgument as? FirTypeProjectionWithVariance)?.typeRef?.coneTypeOrNull ?: continue
|
reporter.reportOn(
|
||||||
val typeSymbol = type.toSymbol(context.session) ?: continue
|
typeArgument.source ?: expression.source,
|
||||||
if (typeSymbol.isNativeInterface(context)) {
|
FirJsErrors.EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT,
|
||||||
reporter.reportOn(
|
type,
|
||||||
typeArgument.source ?: expression.source,
|
context
|
||||||
FirJsErrors.EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT,
|
)
|
||||||
type,
|
|
||||||
context
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-21
@@ -28,35 +28,28 @@ object FirCastOperatorsChecker : FirTypeOperatorCallChecker() {
|
|||||||
val conversionTypeRef = expression.conversionTypeRef
|
val conversionTypeRef = expression.conversionTypeRef
|
||||||
val targetType = conversionTypeRef.coneType.fullyExpandedType(session)
|
val targetType = conversionTypeRef.coneType.fullyExpandedType(session)
|
||||||
|
|
||||||
|
if (expression.operation in FirOperation.TYPES && targetType is ConeDynamicType) {
|
||||||
|
reporter.reportOn(conversionTypeRef.source, FirErrors.DYNAMIC_NOT_ALLOWED, context)
|
||||||
|
}
|
||||||
|
|
||||||
val isSafeAs = expression.operation == FirOperation.SAFE_AS
|
val isSafeAs = expression.operation == FirOperation.SAFE_AS
|
||||||
if (expression.operation == FirOperation.AS || isSafeAs) {
|
if (expression.operation == FirOperation.AS || isSafeAs) {
|
||||||
if (targetType is ConeDynamicType) {
|
val castType = checkCasting(actualType, targetType, isSafeAs, context)
|
||||||
reporter.reportOn(conversionTypeRef.source, FirErrors.DYNAMIC_NOT_ALLOWED, context)
|
if (castType == CastingType.Impossible) {
|
||||||
} else {
|
if (context.languageVersionSettings.supportsFeature(LanguageFeature.EnableDfaWarningsInK2)) {
|
||||||
val castType = checkCasting(actualType, targetType, isSafeAs, context)
|
reporter.reportOn(expression.source, FirErrors.CAST_NEVER_SUCCEEDS, context)
|
||||||
if (castType == CastingType.Impossible) {
|
|
||||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.EnableDfaWarningsInK2)) {
|
|
||||||
reporter.reportOn(expression.source, FirErrors.CAST_NEVER_SUCCEEDS, context)
|
|
||||||
}
|
|
||||||
} else if (castType == CastingType.Always) {
|
|
||||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.EnableDfaWarningsInK2)) {
|
|
||||||
reporter.reportOn(expression.source, FirErrors.USELESS_CAST, context)
|
|
||||||
}
|
|
||||||
} else if (isCastErased(actualType, targetType, context)) {
|
|
||||||
reporter.reportOn(expression.source, FirErrors.UNCHECKED_CAST, actualType, targetType, context)
|
|
||||||
}
|
}
|
||||||
|
} else if (castType == CastingType.Always) {
|
||||||
|
if (context.languageVersionSettings.supportsFeature(LanguageFeature.EnableDfaWarningsInK2)) {
|
||||||
|
reporter.reportOn(expression.source, FirErrors.USELESS_CAST, context)
|
||||||
|
}
|
||||||
|
} else if (isCastErased(actualType, targetType, context)) {
|
||||||
|
reporter.reportOn(expression.source, FirErrors.UNCHECKED_CAST, actualType, targetType, context)
|
||||||
}
|
}
|
||||||
} else if (expression.operation == FirOperation.IS) {
|
} else if (expression.operation == FirOperation.IS) {
|
||||||
if (targetType is ConeDynamicType) {
|
|
||||||
reporter.reportOn(conversionTypeRef.source, FirErrors.DYNAMIC_NOT_ALLOWED, context)
|
|
||||||
}
|
|
||||||
if (!context.isContractBody && isCastErased(actualType, targetType, context)) {
|
if (!context.isContractBody && isCastErased(actualType, targetType, context)) {
|
||||||
reporter.reportOn(conversionTypeRef.source, FirErrors.CANNOT_CHECK_FOR_ERASED, targetType, context)
|
reporter.reportOn(conversionTypeRef.source, FirErrors.CANNOT_CHECK_FOR_ERASED, targetType, context)
|
||||||
}
|
}
|
||||||
} else if (expression.operation == FirOperation.NOT_IS) {
|
|
||||||
if (targetType is ConeDynamicType) {
|
|
||||||
reporter.reportOn(conversionTypeRef.source, FirErrors.DYNAMIC_NOT_ALLOWED, context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
|
|||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
||||||
import org.jetbrains.kotlin.fir.references.*
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
import org.jetbrains.kotlin.fir.visitors.TransformData
|
import org.jetbrains.kotlin.fir.visitors.TransformData
|
||||||
@@ -177,3 +176,14 @@ val FirQualifiedAccessExpression.allReceiverExpressions: List<FirExpression>
|
|||||||
addIfNotNull(extensionReceiver)
|
addIfNotNull(extensionReceiver)
|
||||||
addAll(contextReceiverArguments)
|
addAll(contextReceiverArguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun FirFunctionCall.forAllReifiedTypeParameters(block: (ConeKotlinType, FirTypeProjectionWithVariance) -> Unit) {
|
||||||
|
val functionSymbol = calleeReference.toResolvedFunctionSymbol() ?: return
|
||||||
|
|
||||||
|
for ((typeParameterSymbol, typeArgument) in functionSymbol.typeParameterSymbols.zip(typeArguments)) {
|
||||||
|
if (typeParameterSymbol.isReified && typeArgument is FirTypeProjectionWithVariance) {
|
||||||
|
val type = typeArgument.typeRef.coneTypeOrNull ?: continue
|
||||||
|
block(type, typeArgument)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user