[Wasm] Move external RTT checkers to web.common and reuse in Wasm
#KT-56849
This commit is contained in:
committed by
Space Team
parent
d219d5380b
commit
cf3b293072
-11
@@ -93,14 +93,6 @@ object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") {
|
|||||||
val NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
val NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||||
parameter<ConeKotlinType>("type")
|
parameter<ConeKotlinType>("type")
|
||||||
}
|
}
|
||||||
val CANNOT_CHECK_FOR_EXTERNAL_INTERFACE by error<KtElement> {
|
|
||||||
parameter<ConeKotlinType>("targetType")
|
|
||||||
}
|
|
||||||
val UNCHECKED_CAST_TO_EXTERNAL_INTERFACE by warning<KtElement> {
|
|
||||||
parameter<ConeKotlinType>("sourceType")
|
|
||||||
parameter<ConeKotlinType>("targetType")
|
|
||||||
}
|
|
||||||
val EXTERNAL_INTERFACE_AS_CLASS_LITERAL by error<KtElement>()
|
|
||||||
val JS_EXTERNAL_INHERITORS_ONLY by error<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
val JS_EXTERNAL_INHERITORS_ONLY by error<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||||
parameter<FirClassLikeSymbol<*>>("parent")
|
parameter<FirClassLikeSymbol<*>>("parent")
|
||||||
parameter<FirClassLikeSymbol<*>>("kid")
|
parameter<FirClassLikeSymbol<*>>("kid")
|
||||||
@@ -108,9 +100,6 @@ object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") {
|
|||||||
val JS_EXTERNAL_ARGUMENT by error<KtExpression>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
val JS_EXTERNAL_ARGUMENT by error<KtExpression>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||||
parameter<ConeKotlinType>("argType")
|
parameter<ConeKotlinType>("argType")
|
||||||
}
|
}
|
||||||
val EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
|
||||||
parameter<ConeKotlinType>("typeArgument")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val EXPORT by object : DiagnosticGroup("Export") {
|
val EXPORT by object : DiagnosticGroup("Export") {
|
||||||
|
|||||||
+12
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.checkers.generator.diagnostics
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticList
|
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticList
|
||||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.PositioningStrategy
|
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.PositioningStrategy
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.util.PrivateForInline
|
import org.jetbrains.kotlin.util.PrivateForInline
|
||||||
|
|
||||||
@@ -32,6 +33,17 @@ object WEB_COMMON_DIAGNOSTICS_LIST : DiagnosticList("FirWebCommonErrors") {
|
|||||||
val WRONG_BODY_OF_EXTERNAL_DECLARATION by error<KtElement>()
|
val WRONG_BODY_OF_EXTERNAL_DECLARATION by error<KtElement>()
|
||||||
val WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION by error<KtElement>()
|
val WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION by error<KtElement>()
|
||||||
val WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER by error<KtElement>()
|
val WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER by error<KtElement>()
|
||||||
|
val CANNOT_CHECK_FOR_EXTERNAL_INTERFACE by error<KtElement> {
|
||||||
|
parameter<ConeKotlinType>("targetType")
|
||||||
|
}
|
||||||
|
val UNCHECKED_CAST_TO_EXTERNAL_INTERFACE by warning<KtElement> {
|
||||||
|
parameter<ConeKotlinType>("sourceType")
|
||||||
|
parameter<ConeKotlinType>("targetType")
|
||||||
|
}
|
||||||
|
val EXTERNAL_INTERFACE_AS_CLASS_LITERAL by error<KtElement>()
|
||||||
|
val EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||||
|
parameter<ConeKotlinType>("typeArgument")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val EXPORT by object : DiagnosticGroup("Export") {
|
val EXPORT by object : DiagnosticGroup("Export") {
|
||||||
|
|||||||
-4
@@ -67,12 +67,8 @@ object FirJsErrors {
|
|||||||
val INLINE_CLASS_IN_EXTERNAL_DECLARATION by error0<KtElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val INLINE_CLASS_IN_EXTERNAL_DECLARATION by error0<KtElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
val EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION by error0<KtElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION by error0<KtElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
val NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE by error1<KtElement, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE by error1<KtElement, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
val CANNOT_CHECK_FOR_EXTERNAL_INTERFACE by error1<KtElement, ConeKotlinType>()
|
|
||||||
val UNCHECKED_CAST_TO_EXTERNAL_INTERFACE by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
|
|
||||||
val EXTERNAL_INTERFACE_AS_CLASS_LITERAL by error0<KtElement>()
|
|
||||||
val JS_EXTERNAL_INHERITORS_ONLY by error2<KtDeclaration, FirClassLikeSymbol<*>, FirClassLikeSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val JS_EXTERNAL_INHERITORS_ONLY by error2<KtDeclaration, FirClassLikeSymbol<*>, FirClassLikeSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
val JS_EXTERNAL_ARGUMENT by error1<KtExpression, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val JS_EXTERNAL_ARGUMENT by error1<KtExpression, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
val EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT by error1<KtElement, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
|
||||||
|
|
||||||
// Export
|
// Export
|
||||||
val WRONG_EXPORTED_DECLARATION by error1<KtElement, String>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val WRONG_EXPORTED_DECLARATION by error1<KtElement, String>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
|||||||
-21
@@ -14,13 +14,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.CALL_FROM_UM
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.CALL_TO_DEFINED_EXTERNALLY_FROM_NON_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.CALL_TO_DEFINED_EXTERNALLY_FROM_NON_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.CANNOT_CHECK_FOR_EXTERNAL_INTERFACE
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.DELEGATION_BY_DYNAMIC
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.DELEGATION_BY_DYNAMIC
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.ENUM_CLASS_IN_EXTERNAL_DECLARATION_WARNING
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.ENUM_CLASS_IN_EXTERNAL_DECLARATION_WARNING
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_ENUM_ENTRY_WITH_BODY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_ENUM_ENTRY_WITH_BODY
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_INTERFACE_AS_CLASS_LITERAL
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.IMPLEMENTING_FUNCTION_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.IMPLEMENTING_FUNCTION_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.INLINE_CLASS_IN_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.INLINE_CLASS_IN_EXTERNAL_DECLARATION
|
||||||
@@ -55,7 +52,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.PROPERTY_DEL
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.RUNTIME_ANNOTATION_NOT_SUPPORTED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.RUNTIME_ANNOTATION_NOT_SUPPORTED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.RUNTIME_ANNOTATION_ON_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.RUNTIME_ANNOTATION_ON_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.SPREAD_OPERATOR_IN_DYNAMIC_CALL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.SPREAD_OPERATOR_IN_DYNAMIC_CALL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.UNCHECKED_CAST_TO_EXTERNAL_INTERFACE
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_EXPORTED_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_EXPORTED_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_MULTIPLE_INHERITANCE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_MULTIPLE_INHERITANCE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_OPERATION_WITH_DYNAMIC
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_OPERATION_WITH_DYNAMIC
|
||||||
@@ -155,11 +151,6 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
"Expected argument with external type, but type ''{0}'' is non-external.",
|
"Expected argument with external type, but type ''{0}'' is non-external.",
|
||||||
FirDiagnosticRenderers.RENDER_TYPE
|
FirDiagnosticRenderers.RENDER_TYPE
|
||||||
)
|
)
|
||||||
map.put(
|
|
||||||
EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT,
|
|
||||||
"Cannot pass external interface ''{0}'' for reified type parameter.",
|
|
||||||
FirDiagnosticRenderers.RENDER_TYPE
|
|
||||||
)
|
|
||||||
map.put(JS_NAME_PROHIBITED_FOR_EXTENSION_PROPERTY, "'@JsName' is prohibited for extension properties.")
|
map.put(JS_NAME_PROHIBITED_FOR_EXTENSION_PROPERTY, "'@JsName' is prohibited for extension properties.")
|
||||||
map.put(
|
map.put(
|
||||||
JS_BUILTIN_NAME_CLASH,
|
JS_BUILTIN_NAME_CLASH,
|
||||||
@@ -186,18 +177,6 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
map.put(JS_NAME_PROHIBITED_FOR_OVERRIDE, "'@JsName' is prohibited for overridden members.")
|
map.put(JS_NAME_PROHIBITED_FOR_OVERRIDE, "'@JsName' is prohibited for overridden members.")
|
||||||
map.put(JS_NAME_ON_PRIMARY_CONSTRUCTOR_PROHIBITED, "'@JsName' annotation is prohibited for primary constructors.")
|
map.put(JS_NAME_ON_PRIMARY_CONSTRUCTOR_PROHIBITED, "'@JsName' annotation is prohibited for primary constructors.")
|
||||||
map.put(JS_NAME_ON_ACCESSOR_AND_PROPERTY, "'@JsName' can be either on a property or its accessors, not both of them.")
|
map.put(JS_NAME_ON_ACCESSOR_AND_PROPERTY, "'@JsName' can be either on a property or its accessors, not both of them.")
|
||||||
map.put(
|
|
||||||
CANNOT_CHECK_FOR_EXTERNAL_INTERFACE,
|
|
||||||
"Cannot check for external interface: ''{0}''",
|
|
||||||
FirDiagnosticRenderers.RENDER_TYPE,
|
|
||||||
)
|
|
||||||
map.put(
|
|
||||||
UNCHECKED_CAST_TO_EXTERNAL_INTERFACE,
|
|
||||||
"Unchecked cast to external interface: ''{0}'' to ''{1}''.",
|
|
||||||
FirDiagnosticRenderers.RENDER_TYPE,
|
|
||||||
FirDiagnosticRenderers.RENDER_TYPE,
|
|
||||||
)
|
|
||||||
map.put(EXTERNAL_INTERFACE_AS_CLASS_LITERAL, "Cannot refer to external interface from class literal.")
|
|
||||||
map.put(WRONG_EXPORTED_DECLARATION, "Declaration of such kind ({0}) cannot be exported to JavaScript.", CommonRenderers.STRING)
|
map.put(WRONG_EXPORTED_DECLARATION, "Declaration of such kind ({0}) cannot be exported to JavaScript.", CommonRenderers.STRING)
|
||||||
map.put(
|
map.put(
|
||||||
NON_EXPORTABLE_TYPE,
|
NON_EXPORTABLE_TYPE,
|
||||||
|
|||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.analysis.js.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.FirAbstractWebCheckerUtils
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
|
||||||
|
object FirJsWebCheckerUtils : FirAbstractWebCheckerUtils() {
|
||||||
|
override fun isNativeOrExternalInterface(symbol: FirBasedSymbol<*>, session: FirSession): Boolean {
|
||||||
|
return symbol.isNativeInterface(session)
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-58
@@ -5,62 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.js.checkers.expression
|
package org.jetbrains.kotlin.fir.analysis.js.checkers.expression
|
||||||
|
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.FirJsWebCheckerUtils
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.expression.FirAbstractNativeRttiChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionChecker
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeInterface
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
|
||||||
import org.jetbrains.kotlin.fir.types.resolvedType
|
|
||||||
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
|
|
||||||
|
|
||||||
object FirJsNativeRttiChecker : FirBasicExpressionChecker() {
|
object FirJsNativeRttiChecker : FirAbstractNativeRttiChecker(FirJsWebCheckerUtils)
|
||||||
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
|
||||||
when (expression) {
|
|
||||||
is FirGetClassCall -> checkGetClassCall(expression, context, reporter)
|
|
||||||
is FirTypeOperatorCall -> checkTypeOperatorCall(expression, context, reporter)
|
|
||||||
else -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkGetClassCall(expression: FirGetClassCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
|
||||||
val declarationToCheck = expression.argument.resolvedType.toRegularClassSymbol(context.session) ?: return
|
|
||||||
|
|
||||||
if (expression.arguments.firstOrNull() !is FirResolvedQualifier) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (declarationToCheck.isNativeInterface(context)) {
|
|
||||||
reporter.reportOn(expression.source, FirJsErrors.EXTERNAL_INTERFACE_AS_CLASS_LITERAL, context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkTypeOperatorCall(expression: FirTypeOperatorCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
|
||||||
val targetTypeRef = expression.conversionTypeRef
|
|
||||||
val declarationToCheck = targetTypeRef.toRegularClassSymbol(context.session) ?: return
|
|
||||||
|
|
||||||
if (!declarationToCheck.isNativeInterface(context)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
when (expression.operation) {
|
|
||||||
FirOperation.AS, FirOperation.SAFE_AS -> reporter.reportOn(
|
|
||||||
expression.source,
|
|
||||||
FirJsErrors.UNCHECKED_CAST_TO_EXTERNAL_INTERFACE,
|
|
||||||
expression.argument.resolvedType,
|
|
||||||
targetTypeRef.coneType,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
FirOperation.IS, FirOperation.NOT_IS -> reporter.reportOn(
|
|
||||||
expression.source,
|
|
||||||
FirJsErrors.CANNOT_CHECK_FOR_EXTERNAL_INTERFACE,
|
|
||||||
targetTypeRef.coneType,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
else -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+3
-24
@@ -5,28 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.js.checkers.expression
|
package org.jetbrains.kotlin.fir.analysis.js.checkers.expression
|
||||||
|
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.FirJsWebCheckerUtils
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.expression.FirAbstractReifiedExternalChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChecker
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeInterface
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.forAllReifiedTypeParameters
|
|
||||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
|
||||||
|
|
||||||
object FirJsReifiedExternalChecker : FirFunctionCallChecker() {
|
object FirJsReifiedExternalChecker : FirAbstractReifiedExternalChecker(FirJsWebCheckerUtils)
|
||||||
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
|
||||||
expression.forAllReifiedTypeParameters { type, typeArgument ->
|
|
||||||
val typeSymbol = type.toSymbol(context.session)
|
|
||||||
if (typeSymbol?.isNativeInterface(context) == true) {
|
|
||||||
reporter.reportOn(
|
|
||||||
typeArgument.source ?: expression.source,
|
|
||||||
FirJsErrors.EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT,
|
|
||||||
type,
|
|
||||||
context
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.analysis.wasm.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.FirAbstractWebCheckerUtils
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.isEffectivelyExternal
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
|
|
||||||
|
object FirWasmWebCheckerUtils : FirAbstractWebCheckerUtils() {
|
||||||
|
@OptIn(SymbolInternals::class)
|
||||||
|
override fun isNativeOrExternalInterface(symbol: FirBasedSymbol<*>, session: FirSession): Boolean =
|
||||||
|
symbol.isEffectivelyExternal(session) && (symbol.fir as? FirClass)?.isInterface == true
|
||||||
|
}
|
||||||
+4
@@ -7,7 +7,9 @@ package org.jetbrains.kotlin.fir.analysis.wasm.checkers
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.*
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.wasm.checkers.expression.FirWasmDefinedExternallyCallChecker
|
import org.jetbrains.kotlin.fir.analysis.wasm.checkers.expression.FirWasmDefinedExternallyCallChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.wasm.checkers.expression.FirWasmExternalRttiChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.wasm.checkers.expression.FirWasmJsCodeCallChecker
|
import org.jetbrains.kotlin.fir.analysis.wasm.checkers.expression.FirWasmJsCodeCallChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.wasm.checkers.expression.FirWasmReifiedExternalChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.expression.FirJsCodeConstantArgumentChecker
|
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.expression.FirJsCodeConstantArgumentChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.expression.FirJsQualifierChecker
|
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.expression.FirJsQualifierChecker
|
||||||
|
|
||||||
@@ -20,11 +22,13 @@ object WasmExpressionCheckers : ExpressionCheckers() {
|
|||||||
override val basicExpressionCheckers: Set<FirBasicExpressionChecker>
|
override val basicExpressionCheckers: Set<FirBasicExpressionChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirWasmDefinedExternallyCallChecker,
|
FirWasmDefinedExternallyCallChecker,
|
||||||
|
FirWasmExternalRttiChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val functionCallCheckers: Set<FirFunctionCallChecker>
|
override val functionCallCheckers: Set<FirFunctionCallChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirJsCodeConstantArgumentChecker,
|
FirJsCodeConstantArgumentChecker,
|
||||||
FirWasmJsCodeCallChecker,
|
FirWasmJsCodeCallChecker,
|
||||||
|
FirWasmReifiedExternalChecker
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.analysis.wasm.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.wasm.checkers.FirWasmWebCheckerUtils
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.expression.FirAbstractNativeRttiChecker
|
||||||
|
|
||||||
|
object FirWasmExternalRttiChecker : FirAbstractNativeRttiChecker(FirWasmWebCheckerUtils)
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.analysis.wasm.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.wasm.checkers.FirWasmWebCheckerUtils
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.expression.FirAbstractReifiedExternalChecker
|
||||||
|
|
||||||
|
object FirWasmReifiedExternalChecker : FirAbstractReifiedExternalChecker(FirWasmWebCheckerUtils)
|
||||||
+5
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.diagnostics.*
|
|||||||
import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies
|
import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.psi.KtAnonymousInitializer
|
import org.jetbrains.kotlin.psi.KtAnonymousInitializer
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
@@ -35,6 +36,10 @@ object FirWebCommonErrors {
|
|||||||
val WRONG_BODY_OF_EXTERNAL_DECLARATION by error0<KtElement>()
|
val WRONG_BODY_OF_EXTERNAL_DECLARATION by error0<KtElement>()
|
||||||
val WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION by error0<KtElement>()
|
val WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION by error0<KtElement>()
|
||||||
val WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER by error0<KtElement>()
|
val WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER by error0<KtElement>()
|
||||||
|
val CANNOT_CHECK_FOR_EXTERNAL_INTERFACE by error1<KtElement, ConeKotlinType>()
|
||||||
|
val UNCHECKED_CAST_TO_EXTERNAL_INTERFACE by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
|
||||||
|
val EXTERNAL_INTERFACE_AS_CLASS_LITERAL by error0<KtElement>()
|
||||||
|
val EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT by error1<KtElement, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
|
||||||
// Export
|
// Export
|
||||||
val NESTED_JS_EXPORT by error0<KtElement>()
|
val NESTED_JS_EXPORT by error0<KtElement>()
|
||||||
|
|||||||
+23
@@ -8,16 +8,21 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics.web.common
|
|||||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
|
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
|
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers
|
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.CANNOT_CHECK_FOR_EXTERNAL_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.EXTERNAL_ANONYMOUS_INITIALIZER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.EXTERNAL_ANONYMOUS_INITIALIZER
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.EXTERNAL_DELEGATED_CONSTRUCTOR_CALL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.EXTERNAL_DELEGATED_CONSTRUCTOR_CALL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.EXTERNAL_DELEGATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.EXTERNAL_DELEGATION
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.EXTERNAL_INTERFACE_AS_CLASS_LITERAL
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.INLINE_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.INLINE_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.JSCODE_ARGUMENT_NON_CONST_EXPRESSION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.JSCODE_ARGUMENT_NON_CONST_EXPRESSION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.NESTED_CLASS_IN_EXTERNAL_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.NESTED_CLASS_IN_EXTERNAL_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.NESTED_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.NESTED_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.NESTED_JS_EXPORT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.NESTED_JS_EXPORT
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.NON_ABSTRACT_MEMBER_OF_EXTERNAL_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.NON_ABSTRACT_MEMBER_OF_EXTERNAL_INTERFACE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.UNCHECKED_CAST_TO_EXTERNAL_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.WRONG_BODY_OF_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.WRONG_BODY_OF_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.WRONG_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors.WRONG_EXTERNAL_DECLARATION
|
||||||
@@ -49,6 +54,24 @@ object FirWebCommonErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER,
|
WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER,
|
||||||
"Wrong default value for parameter of external function. Must be ' = definedExternally'."
|
"Wrong default value for parameter of external function. Must be ' = definedExternally'."
|
||||||
)
|
)
|
||||||
|
map.put(
|
||||||
|
CANNOT_CHECK_FOR_EXTERNAL_INTERFACE,
|
||||||
|
"Cannot check for external interface: ''{0}''",
|
||||||
|
FirDiagnosticRenderers.RENDER_TYPE,
|
||||||
|
)
|
||||||
|
map.put(
|
||||||
|
UNCHECKED_CAST_TO_EXTERNAL_INTERFACE,
|
||||||
|
"Unchecked cast to external interface: ''{0}'' to ''{1}''.",
|
||||||
|
FirDiagnosticRenderers.RENDER_TYPE,
|
||||||
|
FirDiagnosticRenderers.RENDER_TYPE,
|
||||||
|
)
|
||||||
|
map.put(EXTERNAL_INTERFACE_AS_CLASS_LITERAL, "Cannot refer to external interface from class literal.")
|
||||||
|
map.put(
|
||||||
|
EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT,
|
||||||
|
"Cannot pass external interface ''{0}'' for reified type parameter.",
|
||||||
|
FirDiagnosticRenderers.RENDER_TYPE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
map.put(NESTED_JS_EXPORT, "'@JsExport' is only allowed on files and top-level declarations.")
|
map.put(NESTED_JS_EXPORT, "'@JsExport' is only allowed on files and top-level declarations.")
|
||||||
|
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.analysis.web.common.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
|
||||||
|
abstract class FirAbstractWebCheckerUtils {
|
||||||
|
abstract fun isNativeOrExternalInterface(symbol: FirBasedSymbol<*>, session: FirSession): Boolean
|
||||||
|
}
|
||||||
+68
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.analysis.web.common.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.FirAbstractWebCheckerUtils
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
|
import org.jetbrains.kotlin.fir.types.resolvedType
|
||||||
|
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
|
||||||
|
|
||||||
|
abstract class FirAbstractNativeRttiChecker(
|
||||||
|
private val webCheckerUtils: FirAbstractWebCheckerUtils
|
||||||
|
) : FirBasicExpressionChecker() {
|
||||||
|
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
when (expression) {
|
||||||
|
is FirGetClassCall -> checkGetClassCall(expression, context, reporter)
|
||||||
|
is FirTypeOperatorCall -> checkTypeOperatorCall(expression, context, reporter)
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkGetClassCall(expression: FirGetClassCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
val declarationToCheck = expression.argument.resolvedType.toRegularClassSymbol(context.session) ?: return
|
||||||
|
|
||||||
|
if (expression.arguments.firstOrNull() !is FirResolvedQualifier) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (webCheckerUtils.isNativeOrExternalInterface(declarationToCheck, context.session)) {
|
||||||
|
reporter.reportOn(expression.source, FirWebCommonErrors.EXTERNAL_INTERFACE_AS_CLASS_LITERAL, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkTypeOperatorCall(expression: FirTypeOperatorCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
val targetTypeRef = expression.conversionTypeRef
|
||||||
|
val declarationToCheck = targetTypeRef.toRegularClassSymbol(context.session) ?: return
|
||||||
|
|
||||||
|
if (!webCheckerUtils.isNativeOrExternalInterface(declarationToCheck, context.session)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
when (expression.operation) {
|
||||||
|
FirOperation.AS, FirOperation.SAFE_AS -> reporter.reportOn(
|
||||||
|
expression.source,
|
||||||
|
FirWebCommonErrors.UNCHECKED_CAST_TO_EXTERNAL_INTERFACE,
|
||||||
|
expression.argument.resolvedType,
|
||||||
|
targetTypeRef.coneType,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
FirOperation.IS, FirOperation.NOT_IS -> reporter.reportOn(
|
||||||
|
expression.source,
|
||||||
|
FirWebCommonErrors.CANNOT_CHECK_FOR_EXTERNAL_INTERFACE,
|
||||||
|
targetTypeRef.coneType,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.analysis.web.common.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErrors
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.FirAbstractWebCheckerUtils
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.forAllReifiedTypeParameters
|
||||||
|
import org.jetbrains.kotlin.fir.types.toSymbol
|
||||||
|
|
||||||
|
abstract class FirAbstractReifiedExternalChecker(
|
||||||
|
private val webCheckerUtils: FirAbstractWebCheckerUtils
|
||||||
|
) : FirFunctionCallChecker() {
|
||||||
|
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
expression.forAllReifiedTypeParameters { type, typeArgument ->
|
||||||
|
val typeSymbol = type.toSymbol(context.session)
|
||||||
|
if (typeSymbol != null && webCheckerUtils.isNativeOrExternalInterface(typeSymbol, context.session)) {
|
||||||
|
reporter.reportOn(
|
||||||
|
typeArgument.source ?: expression.source,
|
||||||
|
FirWebCommonErrors.EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT,
|
||||||
|
type,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -628,11 +628,8 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
|
|||||||
"INLINE_CLASS_IN_EXTERNAL_DECLARATION",
|
"INLINE_CLASS_IN_EXTERNAL_DECLARATION",
|
||||||
"EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION",
|
"EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION",
|
||||||
"NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE",
|
"NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE",
|
||||||
"CANNOT_CHECK_FOR_EXTERNAL_INTERFACE",
|
|
||||||
"EXTERNAL_INTERFACE_AS_CLASS_LITERAL",
|
|
||||||
"JS_EXTERNAL_INHERITORS_ONLY",
|
"JS_EXTERNAL_INHERITORS_ONLY",
|
||||||
"JS_EXTERNAL_ARGUMENT",
|
"JS_EXTERNAL_ARGUMENT",
|
||||||
"EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT",
|
|
||||||
"WRONG_EXPORTED_DECLARATION",
|
"WRONG_EXPORTED_DECLARATION",
|
||||||
"NESTED_JS_EXPORT",
|
"NESTED_JS_EXPORT",
|
||||||
"DELEGATION_BY_DYNAMIC",
|
"DELEGATION_BY_DYNAMIC",
|
||||||
@@ -676,6 +673,9 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
|
|||||||
"WRONG_BODY_OF_EXTERNAL_DECLARATION",
|
"WRONG_BODY_OF_EXTERNAL_DECLARATION",
|
||||||
"WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION",
|
"WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION",
|
||||||
"WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER",
|
"WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER",
|
||||||
|
"CANNOT_CHECK_FOR_EXTERNAL_INTERFACE",
|
||||||
|
"EXTERNAL_INTERFACE_AS_CLASS_LITERAL",
|
||||||
|
"EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT",
|
||||||
"JSCODE_ARGUMENT_NON_CONST_EXPRESSION",
|
"JSCODE_ARGUMENT_NON_CONST_EXPRESSION",
|
||||||
"SYNTAX",
|
"SYNTAX",
|
||||||
)
|
)
|
||||||
|
|||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// DIAGNOSTICS: +UNCHECKED_CAST_TO_EXTERNAL_INTERFACE
|
||||||
|
|
||||||
|
external interface I
|
||||||
|
|
||||||
|
fun box(a: Any, b: Any): Pair<I, I?> {
|
||||||
|
return Pair(<!UNCHECKED_CAST_TO_EXTERNAL_INTERFACE!>a as I<!>, <!UNCHECKED_CAST_TO_EXTERNAL_INTERFACE!>b as? I<!>)
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
external interface I
|
||||||
|
|
||||||
|
fun box(a: Any, b: Any): Boolean {
|
||||||
|
return <!CANNOT_CHECK_FOR_EXTERNAL_INTERFACE!>a is I<!> && <!CANNOT_CHECK_FOR_EXTERNAL_INTERFACE!>b !is I<!>
|
||||||
|
}
|
||||||
Vendored
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
inline fun <reified T> foo(x: T) {
|
||||||
|
println(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
external interface I
|
||||||
|
|
||||||
|
external class C : I
|
||||||
|
|
||||||
|
operator inline fun <reified T> C.plus(other: T) = this
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
foo(C())
|
||||||
|
|
||||||
|
val c: I = C()
|
||||||
|
<!EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT!>foo(c)<!>
|
||||||
|
foo<<!EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT!>I<!>>(C())
|
||||||
|
|
||||||
|
<!EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT!>C() + c<!>
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
external interface I
|
||||||
|
|
||||||
|
typealias TA = I
|
||||||
|
fun box() {
|
||||||
|
println(<!EXTERNAL_INTERFACE_AS_CLASS_LITERAL!>I::class<!>)
|
||||||
|
println(<!EXTERNAL_INTERFACE_AS_CLASS_LITERAL!>TA::class<!>)
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
external interface I
|
||||||
|
|
||||||
|
external interface J
|
||||||
|
|
||||||
|
fun box(a: Any) = when (a) {
|
||||||
|
<!CANNOT_CHECK_FOR_EXTERNAL_INTERFACE!>is I<!> -> 0
|
||||||
|
<!CANNOT_CHECK_FOR_EXTERNAL_INTERFACE!>!is J<!> -> 1
|
||||||
|
else -> 2
|
||||||
|
}
|
||||||
+40
@@ -128,6 +128,46 @@ public class DiagnosticsFirWasmTestGenerated extends AbstractDiagnosticsFirWasmT
|
|||||||
public void testWrongQualifier() throws Exception {
|
public void testWrongQualifier() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/wrongQualifier.kt");
|
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/wrongQualifier.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/wasmTests/jsInterop/rtti")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Rtti {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInRtti() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/wasmTests/jsInterop/rtti"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("castToNativeInterface.kt")
|
||||||
|
public void testCastToNativeInterface() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/rtti/castToNativeInterface.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("checkForNativeInterface.kt")
|
||||||
|
public void testCheckForNativeInterface() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/rtti/checkForNativeInterface.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nativeInterfaceAsReifiedTypeArgument.kt")
|
||||||
|
public void testNativeInterfaceAsReifiedTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/rtti/nativeInterfaceAsReifiedTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nativeInterfaceClassLiteral.kt")
|
||||||
|
public void testNativeInterfaceClassLiteral() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/rtti/nativeInterfaceClassLiteral.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("whenIsNativeInterface.kt")
|
||||||
|
public void testWhenIsNativeInterface() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/rtti/whenIsNativeInterface.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+40
@@ -128,6 +128,46 @@ public class DiagnosticsWasmTestGenerated extends AbstractDiagnosticsWasmTest {
|
|||||||
public void testWrongQualifier() throws Exception {
|
public void testWrongQualifier() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/wrongQualifier.kt");
|
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/wrongQualifier.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/wasmTests/jsInterop/rtti")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Rtti {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInRtti() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/wasmTests/jsInterop/rtti"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("castToNativeInterface.kt")
|
||||||
|
public void testCastToNativeInterface() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/rtti/castToNativeInterface.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("checkForNativeInterface.kt")
|
||||||
|
public void testCheckForNativeInterface() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/rtti/checkForNativeInterface.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nativeInterfaceAsReifiedTypeArgument.kt")
|
||||||
|
public void testNativeInterfaceAsReifiedTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/rtti/nativeInterfaceAsReifiedTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nativeInterfaceClassLiteral.kt")
|
||||||
|
public void testNativeInterfaceClassLiteral() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/rtti/nativeInterfaceClassLiteral.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("whenIsNativeInterface.kt")
|
||||||
|
public void testWhenIsNativeInterface() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/rtti/whenIsNativeInterface.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
Reference in New Issue
Block a user