[FIR JS] Implement FirJsExternalChecker
The JsAllowValueClassesInExternals feature is enabled explicitly, because otherwise it's enabled implicitly depending on the backend. See: org/jetbrains/kotlin/test/builders/LanguageVersionSettingsBuilder.kt:90 A property may have a fake source return kind, while its accessor has a real source kind. In this case we can't "just copy" the property return type down to the accessor.
This commit is contained in:
committed by
Space Team
parent
7b8f5f9980
commit
a20e29e8b7
+103
@@ -4685,6 +4685,109 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER) { firDiagnostic ->
|
||||
ExternalClassConstructorPropertyParameterImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.EXTERNAL_ENUM_ENTRY_WITH_BODY) { firDiagnostic ->
|
||||
ExternalEnumEntryWithBodyImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.EXTERNAL_ANONYMOUS_INITIALIZER) { firDiagnostic ->
|
||||
ExternalAnonymousInitializerImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.EXTERNAL_DELEGATION) { firDiagnostic ->
|
||||
ExternalDelegationImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.EXTERNAL_DELEGATED_CONSTRUCTOR_CALL) { firDiagnostic ->
|
||||
ExternalDelegatedConstructorCallImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.WRONG_BODY_OF_EXTERNAL_DECLARATION) { firDiagnostic ->
|
||||
WrongBodyOfExternalDeclarationImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION) { firDiagnostic ->
|
||||
WrongInitializerOfExternalDeclarationImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER) { firDiagnostic ->
|
||||
WrongDefaultValueForExternalFunParameterImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.NESTED_EXTERNAL_DECLARATION) { firDiagnostic ->
|
||||
NestedExternalDeclarationImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.WRONG_EXTERNAL_DECLARATION) { firDiagnostic ->
|
||||
WrongExternalDeclarationImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.NESTED_CLASS_IN_EXTERNAL_INTERFACE) { firDiagnostic ->
|
||||
NestedClassInExternalInterfaceImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE) { firDiagnostic ->
|
||||
ExternalTypeExtendsNonExternalTypeImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.INLINE_EXTERNAL_DECLARATION) { firDiagnostic ->
|
||||
InlineExternalDeclarationImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.INLINE_CLASS_IN_EXTERNAL_DECLARATION_WARNING) { firDiagnostic ->
|
||||
InlineClassInExternalDeclarationWarningImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.INLINE_CLASS_IN_EXTERNAL_DECLARATION) { firDiagnostic ->
|
||||
InlineClassInExternalDeclarationImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION) { firDiagnostic ->
|
||||
ExtensionFunctionInExternalDeclarationImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.NON_ABSTRACT_MEMBER_OF_EXTERNAL_INTERFACE) { firDiagnostic ->
|
||||
NonAbstractMemberOfExternalInterfaceImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.DELEGATION_BY_DYNAMIC) { firDiagnostic ->
|
||||
DelegationByDynamicImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
|
||||
+69
@@ -3258,6 +3258,75 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = CallToDefinedExternallyFromNonExternalDeclaration::class
|
||||
}
|
||||
|
||||
abstract class ExternalClassConstructorPropertyParameter : KtFirDiagnostic<KtParameter>() {
|
||||
override val diagnosticClass get() = ExternalClassConstructorPropertyParameter::class
|
||||
}
|
||||
|
||||
abstract class ExternalEnumEntryWithBody : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = ExternalEnumEntryWithBody::class
|
||||
}
|
||||
|
||||
abstract class ExternalAnonymousInitializer : KtFirDiagnostic<KtAnonymousInitializer>() {
|
||||
override val diagnosticClass get() = ExternalAnonymousInitializer::class
|
||||
}
|
||||
|
||||
abstract class ExternalDelegation : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = ExternalDelegation::class
|
||||
}
|
||||
|
||||
abstract class ExternalDelegatedConstructorCall : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = ExternalDelegatedConstructorCall::class
|
||||
}
|
||||
|
||||
abstract class WrongBodyOfExternalDeclaration : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = WrongBodyOfExternalDeclaration::class
|
||||
}
|
||||
|
||||
abstract class WrongInitializerOfExternalDeclaration : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = WrongInitializerOfExternalDeclaration::class
|
||||
}
|
||||
|
||||
abstract class WrongDefaultValueForExternalFunParameter : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = WrongDefaultValueForExternalFunParameter::class
|
||||
}
|
||||
|
||||
abstract class NestedExternalDeclaration : KtFirDiagnostic<KtExpression>() {
|
||||
override val diagnosticClass get() = NestedExternalDeclaration::class
|
||||
}
|
||||
|
||||
abstract class WrongExternalDeclaration : KtFirDiagnostic<KtExpression>() {
|
||||
override val diagnosticClass get() = WrongExternalDeclaration::class
|
||||
abstract val classKind: String
|
||||
}
|
||||
|
||||
abstract class NestedClassInExternalInterface : KtFirDiagnostic<KtExpression>() {
|
||||
override val diagnosticClass get() = NestedClassInExternalInterface::class
|
||||
}
|
||||
|
||||
abstract class ExternalTypeExtendsNonExternalType : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = ExternalTypeExtendsNonExternalType::class
|
||||
}
|
||||
|
||||
abstract class InlineExternalDeclaration : KtFirDiagnostic<KtDeclaration>() {
|
||||
override val diagnosticClass get() = InlineExternalDeclaration::class
|
||||
}
|
||||
|
||||
abstract class InlineClassInExternalDeclarationWarning : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = InlineClassInExternalDeclarationWarning::class
|
||||
}
|
||||
|
||||
abstract class InlineClassInExternalDeclaration : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = InlineClassInExternalDeclaration::class
|
||||
}
|
||||
|
||||
abstract class ExtensionFunctionInExternalDeclaration : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = ExtensionFunctionInExternalDeclaration::class
|
||||
}
|
||||
|
||||
abstract class NonAbstractMemberOfExternalInterface : KtFirDiagnostic<KtExpression>() {
|
||||
override val diagnosticClass get() = NonAbstractMemberOfExternalInterface::class
|
||||
}
|
||||
|
||||
abstract class DelegationByDynamic : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = DelegationByDynamic::class
|
||||
}
|
||||
|
||||
+86
@@ -3942,6 +3942,92 @@ internal class CallToDefinedExternallyFromNonExternalDeclarationImpl(
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.CallToDefinedExternallyFromNonExternalDeclaration(), KtAbstractFirDiagnostic<PsiElement>
|
||||
|
||||
internal class ExternalClassConstructorPropertyParameterImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.ExternalClassConstructorPropertyParameter(), KtAbstractFirDiagnostic<KtParameter>
|
||||
|
||||
internal class ExternalEnumEntryWithBodyImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.ExternalEnumEntryWithBody(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class ExternalAnonymousInitializerImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.ExternalAnonymousInitializer(), KtAbstractFirDiagnostic<KtAnonymousInitializer>
|
||||
|
||||
internal class ExternalDelegationImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.ExternalDelegation(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class ExternalDelegatedConstructorCallImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.ExternalDelegatedConstructorCall(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class WrongBodyOfExternalDeclarationImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.WrongBodyOfExternalDeclaration(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class WrongInitializerOfExternalDeclarationImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.WrongInitializerOfExternalDeclaration(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class WrongDefaultValueForExternalFunParameterImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.WrongDefaultValueForExternalFunParameter(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class NestedExternalDeclarationImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.NestedExternalDeclaration(), KtAbstractFirDiagnostic<KtExpression>
|
||||
|
||||
internal class WrongExternalDeclarationImpl(
|
||||
override val classKind: String,
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.WrongExternalDeclaration(), KtAbstractFirDiagnostic<KtExpression>
|
||||
|
||||
internal class NestedClassInExternalInterfaceImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.NestedClassInExternalInterface(), KtAbstractFirDiagnostic<KtExpression>
|
||||
|
||||
internal class ExternalTypeExtendsNonExternalTypeImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.ExternalTypeExtendsNonExternalType(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class InlineExternalDeclarationImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.InlineExternalDeclaration(), KtAbstractFirDiagnostic<KtDeclaration>
|
||||
|
||||
internal class InlineClassInExternalDeclarationWarningImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.InlineClassInExternalDeclarationWarning(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class InlineClassInExternalDeclarationImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.InlineClassInExternalDeclaration(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class ExtensionFunctionInExternalDeclarationImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.ExtensionFunctionInExternalDeclaration(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class NonAbstractMemberOfExternalInterfaceImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.NonAbstractMemberOfExternalInterface(), KtAbstractFirDiagnostic<KtExpression>
|
||||
|
||||
internal class DelegationByDynamicImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
|
||||
+20
-2
@@ -11,8 +11,7 @@ import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticL
|
||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.PositioningStrategy
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName", "ClassName", "unused")
|
||||
@OptIn(PrivateForInline::class)
|
||||
@@ -42,6 +41,25 @@ object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") {
|
||||
parameter<FirNamedFunctionSymbol>("function")
|
||||
}
|
||||
val CALL_TO_DEFINED_EXTERNALLY_FROM_NON_EXTERNAL_DECLARATION by error<PsiElement>()
|
||||
val EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER by error<KtParameter>()
|
||||
val EXTERNAL_ENUM_ENTRY_WITH_BODY by error<KtElement>()
|
||||
val EXTERNAL_ANONYMOUS_INITIALIZER by error<KtAnonymousInitializer>()
|
||||
val EXTERNAL_DELEGATION by error<KtElement>()
|
||||
val EXTERNAL_DELEGATED_CONSTRUCTOR_CALL by error<KtElement>()
|
||||
val WRONG_BODY_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 NESTED_EXTERNAL_DECLARATION by error<KtExpression>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val WRONG_EXTERNAL_DECLARATION by error<KtExpression>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||
parameter<String>("classKind")
|
||||
}
|
||||
val NESTED_CLASS_IN_EXTERNAL_INTERFACE by error<KtExpression>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val INLINE_EXTERNAL_DECLARATION by error<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val INLINE_CLASS_IN_EXTERNAL_DECLARATION_WARNING by warning<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val INLINE_CLASS_IN_EXTERNAL_DECLARATION by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val NON_ABSTRACT_MEMBER_OF_EXTERNAL_INTERFACE by error<KtExpression>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
}
|
||||
|
||||
val DYNAMICS by object : DiagnosticGroup("Dynamics") {
|
||||
|
||||
+21
@@ -12,8 +12,12 @@ import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.psi.KtAnonymousInitializer
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
@@ -39,6 +43,23 @@ object FirJsErrors {
|
||||
val OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS by error0<KtElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE by error1<KtElement, FirNamedFunctionSymbol>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val CALL_TO_DEFINED_EXTERNALLY_FROM_NON_EXTERNAL_DECLARATION by error0<PsiElement>()
|
||||
val EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER by error0<KtParameter>()
|
||||
val EXTERNAL_ENUM_ENTRY_WITH_BODY by error0<KtElement>()
|
||||
val EXTERNAL_ANONYMOUS_INITIALIZER by error0<KtAnonymousInitializer>()
|
||||
val EXTERNAL_DELEGATION by error0<KtElement>()
|
||||
val EXTERNAL_DELEGATED_CONSTRUCTOR_CALL by error0<KtElement>()
|
||||
val WRONG_BODY_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 NESTED_EXTERNAL_DECLARATION by error0<KtExpression>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val WRONG_EXTERNAL_DECLARATION by error1<KtExpression, String>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val NESTED_CLASS_IN_EXTERNAL_INTERFACE by error0<KtExpression>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE by error0<KtElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val INLINE_EXTERNAL_DECLARATION by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val INLINE_CLASS_IN_EXTERNAL_DECLARATION_WARNING by warning0<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 NON_ABSTRACT_MEMBER_OF_EXTERNAL_INTERFACE by error0<KtExpression>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
|
||||
// Dynamics
|
||||
val DELEGATION_BY_DYNAMIC by error0<KtElement>()
|
||||
|
||||
+50
@@ -7,18 +7,36 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics.js
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.checkMissingMessages
|
||||
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.EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_ANONYMOUS_INITIALIZER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_DELEGATED_CONSTRUCTOR_CALL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_DELEGATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_ENUM_ENTRY_WITH_BODY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.DELEGATION_BY_DYNAMIC
|
||||
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_WARNING
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.INLINE_EXTERNAL_DECLARATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_MODULE_PROHIBITED_ON_NON_NATIVE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_MODULE_PROHIBITED_ON_VAR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NESTED_JS_MODULE_PROHIBITED
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NESTED_CLASS_IN_EXTERNAL_INTERFACE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NESTED_EXTERNAL_DECLARATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NON_ABSTRACT_MEMBER_OF_EXTERNAL_INTERFACE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE
|
||||
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.WRONG_BODY_OF_EXTERNAL_DECLARATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_EXTERNAL_DECLARATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_JS_QUALIFIER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_MULTIPLE_INHERITANCE
|
||||
|
||||
@@ -51,6 +69,38 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
RUNTIME_ANNOTATION_NOT_SUPPORTED,
|
||||
"Reflection is not supported in JavaScript target, therefore you won't be able to read this annotation in run-time"
|
||||
)
|
||||
map.put(EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER, "External class constructor cannot have a property parameter")
|
||||
map.put(EXTERNAL_ENUM_ENTRY_WITH_BODY, "Entry of external enum class can't have body")
|
||||
map.put(EXTERNAL_ANONYMOUS_INITIALIZER, "Anonymous initializer is not allowed in external classes")
|
||||
map.put(EXTERNAL_DELEGATION, "Can't use delegate on external declaration")
|
||||
map.put(EXTERNAL_DELEGATED_CONSTRUCTOR_CALL, "Delegated constructor call in external class is not allowed")
|
||||
map.put(
|
||||
WRONG_BODY_OF_EXTERNAL_DECLARATION,
|
||||
"Wrong body of external declaration. Must be either ' = definedExternally' or { definedExternally }"
|
||||
)
|
||||
map.put(WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION, "Wrong initializer of external declaration. Must be ' = definedExternally'")
|
||||
map.put(
|
||||
WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER,
|
||||
"Wrong default value for parameter of external function. Must be ' = definedExternally'"
|
||||
)
|
||||
map.put(NESTED_EXTERNAL_DECLARATION, "Non top-level `external` declaration")
|
||||
map.put(WRONG_EXTERNAL_DECLARATION, "Declaration of such kind ({0}) can''t be external", CommonRenderers.STRING)
|
||||
map.put(NESTED_CLASS_IN_EXTERNAL_INTERFACE, "Interface can't contain nested classes and objects")
|
||||
map.put(EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE, "External type extends non-external type")
|
||||
map.put(INLINE_EXTERNAL_DECLARATION, "Inline external declaration")
|
||||
map.put(
|
||||
INLINE_CLASS_IN_EXTERNAL_DECLARATION_WARNING,
|
||||
"Using value classes as parameter type or return type of external declarations is experimental"
|
||||
)
|
||||
map.put(
|
||||
INLINE_CLASS_IN_EXTERNAL_DECLARATION,
|
||||
"Using value classes as parameter type or return type of external declarations is not supported"
|
||||
)
|
||||
map.put(EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION, "Function types with receiver are prohibited in external declarations")
|
||||
map.put(
|
||||
NON_ABSTRACT_MEMBER_OF_EXTERNAL_INTERFACE,
|
||||
"Only nullable properties of external interfaces are allowed to be non-abstract"
|
||||
)
|
||||
|
||||
map.checkMissingMessages(FirJsErrors)
|
||||
}
|
||||
|
||||
+1
@@ -24,6 +24,7 @@ object JsDeclarationCheckers : DeclarationCheckers() {
|
||||
get() = setOf(
|
||||
FirJsModuleChecker,
|
||||
FirJsRuntimeAnnotationChecker,
|
||||
FirJsExternalChecker,
|
||||
)
|
||||
|
||||
override val classCheckers: Set<FirClassChecker>
|
||||
|
||||
+348
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* 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.declaration
|
||||
|
||||
import org.jetbrains.kotlin.*
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory0
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.js.checkers.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyBackingField
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
||||
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeObject
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.JsStandardClassIds
|
||||
import org.jetbrains.kotlin.name.JsStandardClassIds.Annotations.JsNative
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
|
||||
object FirJsExternalChecker : FirBasicDeclarationChecker() {
|
||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (!declaration.symbol.isNativeObject(context)) return
|
||||
|
||||
if (!context.isTopLevel) {
|
||||
if (declaration !is FirPropertyAccessor && declaration.isDirectlyExternal(context.session)) {
|
||||
reporter.reportOn(declaration.source, FirJsErrors.NESTED_EXTERNAL_DECLARATION, context)
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration is FirClass) {
|
||||
// TODO: KT-55600: Stop generating diagnostic
|
||||
// messages inside checkers
|
||||
val classKind = when {
|
||||
declaration.status.isData -> "data class"
|
||||
declaration.status.isInner -> "inner class"
|
||||
declaration.status.isInline -> "value class"
|
||||
declaration.status.isFun -> "fun interface"
|
||||
declaration.classKind == ClassKind.ANNOTATION_CLASS -> "annotation class"
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (classKind != null) {
|
||||
reporter.reportOn(declaration.source, FirJsErrors.WRONG_EXTERNAL_DECLARATION, classKind, context)
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration is FirPropertyAccessor && declaration.isDirectlyExternal(context.session)) {
|
||||
reporter.reportOn(declaration.source, FirJsErrors.WRONG_EXTERNAL_DECLARATION, "property accessor", context)
|
||||
} else if (declaration !is FirPrimaryConstructor && declaration.isPrivateMemberOfExternalClass(context.session)) {
|
||||
reporter.reportOn(declaration.source, FirJsErrors.WRONG_EXTERNAL_DECLARATION, "private member of class", context)
|
||||
}
|
||||
|
||||
val container = context.containingDeclarations.lastOrNull()
|
||||
|
||||
if (
|
||||
declaration is FirClass &&
|
||||
declaration.classKind != ClassKind.INTERFACE &&
|
||||
container is FirClass && container.classKind == ClassKind.INTERFACE
|
||||
) {
|
||||
reporter.reportOn(declaration.source, FirJsErrors.NESTED_CLASS_IN_EXTERNAL_INTERFACE, context)
|
||||
}
|
||||
|
||||
if (declaration !is FirPropertyAccessor && declaration is FirCallableDeclaration && declaration.isExtension) {
|
||||
val target = when (declaration) {
|
||||
is FirFunction -> "extension function"
|
||||
is FirProperty -> "extension property"
|
||||
else -> "extension member"
|
||||
}
|
||||
reporter.reportOn(declaration.source, FirJsErrors.WRONG_EXTERNAL_DECLARATION, target, context)
|
||||
}
|
||||
|
||||
if (declaration is FirClass && declaration.classKind != ClassKind.ANNOTATION_CLASS) {
|
||||
val superClasses = declaration.superInterfaces(context.session).toMutableList()
|
||||
declaration.superClassNotAny(context.session)?.let {
|
||||
superClasses.add(it)
|
||||
}
|
||||
if (declaration.classKind == ClassKind.ENUM_CLASS || declaration.classKind == ClassKind.ENUM_ENTRY) {
|
||||
superClasses.removeAll { it.classId?.asSingleFqName()?.toUnsafe() == StandardNames.FqNames._enum }
|
||||
}
|
||||
val superDeclarations = superClasses.mapNotNull { it.toSymbol(context.session) }
|
||||
if (superDeclarations.any { !it.isNativeObject(context) && it.classId.asSingleFqName() != StandardNames.FqNames.throwable }) {
|
||||
reporter.reportOn(declaration.source, FirJsErrors.EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE, context)
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration is FirFunction && declaration.isInline) {
|
||||
reporter.reportOn(declaration.source, FirJsErrors.INLINE_EXTERNAL_DECLARATION, context)
|
||||
}
|
||||
|
||||
fun reportOnParametersAndReturnTypesIf(
|
||||
diagnosticFactory: KtDiagnosticFactory0,
|
||||
condition: (ConeKotlinType) -> Boolean,
|
||||
) {
|
||||
if (
|
||||
declaration !is FirCallableDeclaration ||
|
||||
declaration is FirDefaultPropertyAccessor ||
|
||||
declaration is FirDefaultPropertyBackingField
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
fun checkTypeIsNotInlineClass(type: ConeKotlinType, elementToReport: KtSourceElement?) {
|
||||
if (condition(type)) {
|
||||
reporter.reportOn(elementToReport, diagnosticFactory, context)
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration.returnTypeRef.source?.allowsReporting == true) {
|
||||
declaration.returnTypeRef.source?.let {
|
||||
checkTypeIsNotInlineClass(declaration.returnTypeRef.coneType, it)
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration !is FirFunction) {
|
||||
return
|
||||
}
|
||||
|
||||
for (parameter in declaration.valueParameters) {
|
||||
val ktParam = if (parameter.source?.psi is KtParameter) {
|
||||
parameter.source
|
||||
} else {
|
||||
declaration.source
|
||||
}
|
||||
|
||||
if (ktParam?.allowsReporting != true) {
|
||||
continue
|
||||
}
|
||||
|
||||
val typeToCheck = parameter.varargElementType ?: parameter.returnTypeRef.coneType
|
||||
checkTypeIsNotInlineClass(typeToCheck, ktParam)
|
||||
}
|
||||
}
|
||||
|
||||
val valueClassInExternalDiagnostic = when {
|
||||
context.languageVersionSettings.supportsFeature(LanguageFeature.JsAllowValueClassesInExternals) -> {
|
||||
FirJsErrors.INLINE_CLASS_IN_EXTERNAL_DECLARATION_WARNING
|
||||
}
|
||||
|
||||
else -> {
|
||||
FirJsErrors.INLINE_CLASS_IN_EXTERNAL_DECLARATION
|
||||
}
|
||||
}
|
||||
|
||||
reportOnParametersAndReturnTypesIf(valueClassInExternalDiagnostic) { it.isValueClass(context.session) }
|
||||
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.JsEnableExtensionFunctionInExternals)) {
|
||||
reportOnParametersAndReturnTypesIf(
|
||||
FirJsErrors.EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION, ConeKotlinType::isExtensionFunctionType
|
||||
)
|
||||
}
|
||||
|
||||
if (
|
||||
declaration is FirCallableDeclaration &&
|
||||
declaration.isNonAbstractMemberIfInterface(context.session) &&
|
||||
!declaration.isNullableProperty()
|
||||
) {
|
||||
reporter.reportOn(declaration.source, FirJsErrors.NON_ABSTRACT_MEMBER_OF_EXTERNAL_INTERFACE, context)
|
||||
}
|
||||
|
||||
declaration.checkBody(context, reporter)
|
||||
declaration.checkDelegation(context, reporter)
|
||||
declaration.checkAnonymousInitializer(context, reporter)
|
||||
declaration.checkEnumEntry(context, reporter)
|
||||
declaration.checkConstructorPropertyParam(context, reporter)
|
||||
}
|
||||
|
||||
private val KtSourceElement.allowsReporting
|
||||
get() = kind !is KtFakeSourceElementKind || kind == KtFakeSourceElementKind.PropertyFromParameter
|
||||
|
||||
private val FirValueParameter.varargElementType
|
||||
get() = when {
|
||||
!isVararg -> null
|
||||
else -> returnTypeRef.coneType.typeArguments.firstOrNull()?.type
|
||||
}
|
||||
|
||||
private fun FirClass.superClassNotAny(session: FirSession) = superConeTypes
|
||||
.filterNot { it.isAny || it.isNullableAny }
|
||||
.find { it.toSymbol(session)?.classKind == ClassKind.CLASS }
|
||||
|
||||
private fun FirClass.superInterfaces(session: FirSession) = superConeTypes
|
||||
.filterNot { it.isAny || it.isNullableAny }
|
||||
.filter { it.toSymbol(session)?.classKind == ClassKind.INTERFACE }
|
||||
|
||||
private fun FirDeclaration.checkBody(context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (this is FirDefaultPropertyAccessor) return
|
||||
|
||||
val body = when (this) {
|
||||
is FirFunction -> body
|
||||
is FirAnonymousInitializer -> body
|
||||
else -> null
|
||||
}
|
||||
|
||||
val initializer = when {
|
||||
this is FirEnumEntry -> null
|
||||
source?.kind == KtFakeSourceElementKind.PropertyFromParameter -> null
|
||||
this is FirVariable -> initializer
|
||||
body is FirSingleExpressionBlock -> (body.statement as? FirReturnExpression)?.result
|
||||
else -> null
|
||||
}
|
||||
|
||||
val isWrong = body !is FirSingleExpressionBlock && !hasValidExternalBody()
|
||||
|| initializer != null && !initializer.isDefinedExternallyExpression()
|
||||
|
||||
if (isWrong && body != null) {
|
||||
reporter.reportOn(body.source, FirJsErrors.WRONG_BODY_OF_EXTERNAL_DECLARATION, context)
|
||||
} else if (isWrong && initializer != null) {
|
||||
reporter.reportOn(initializer.source, FirJsErrors.WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION, context)
|
||||
}
|
||||
|
||||
// we shouldn't check such things as the
|
||||
// copy() function of a data class
|
||||
if (source?.kind !is KtRealSourceElementKind) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this is FirFunction) {
|
||||
for (defaultValue in valueParameters.mapNotNull { it.defaultValue }) {
|
||||
if (!defaultValue.isDefinedExternallyExpression()) {
|
||||
reporter.reportOn(defaultValue.source, FirJsErrors.WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirDeclaration.checkDelegation(context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (this !is FirMemberDeclaration || !symbol.isEffectivelyExternal(context)) return
|
||||
|
||||
if (this is FirClass) {
|
||||
declarations.firstIsInstanceOrNull<FirPrimaryConstructor>()?.let {
|
||||
val constructorCall = it.delegatedConstructor
|
||||
|
||||
if (constructorCall?.source?.kind is KtRealSourceElementKind) {
|
||||
reporter.reportOn(constructorCall.source, FirJsErrors.EXTERNAL_DELEGATED_CONSTRUCTOR_CALL, context)
|
||||
}
|
||||
}
|
||||
|
||||
for ((superType, delegate) in collectSupertypesWithDelegates()) {
|
||||
when {
|
||||
delegate != null -> {
|
||||
reporter.reportOn(superType.source, FirJsErrors.EXTERNAL_DELEGATION, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (this is FirConstructor && !isPrimary) {
|
||||
val delegationCall = delegatedConstructor
|
||||
|
||||
if (delegationCall?.source?.kind is KtRealSourceElementKind) {
|
||||
reporter.reportOn(delegationCall.source, FirJsErrors.EXTERNAL_DELEGATED_CONSTRUCTOR_CALL, context)
|
||||
}
|
||||
} else if (this is FirProperty) {
|
||||
delegate?.let {
|
||||
reporter.reportOn(it.source, FirJsErrors.EXTERNAL_DELEGATION, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirDeclaration.checkAnonymousInitializer(context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (this !is FirClass) return
|
||||
|
||||
for (anonymousInitializer in anonymousInitializers) {
|
||||
reporter.reportOn(anonymousInitializer.source, FirJsErrors.EXTERNAL_ANONYMOUS_INITIALIZER, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirDeclaration.checkEnumEntry(context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (this !is FirEnumEntry) return
|
||||
initializer?.let {
|
||||
reporter.reportOn(it.source, FirJsErrors.EXTERNAL_ENUM_ENTRY_WITH_BODY, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirDeclaration.checkConstructorPropertyParam(context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (this !is FirProperty || source?.kind != KtFakeSourceElementKind.PropertyFromParameter) return
|
||||
val containingClass = getContainingClassSymbol(context.session) as? FirClassSymbol<*> ?: return
|
||||
if (containingClass.isData || containingClass.classKind == ClassKind.ANNOTATION_CLASS) return
|
||||
reporter.reportOn(source, FirJsErrors.EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER, context)
|
||||
}
|
||||
|
||||
private fun FirDeclaration.isDirectlyExternal(session: FirSession): Boolean {
|
||||
// source kind is checked, otherwise this function
|
||||
// may return true for a primary constructor of an external class
|
||||
if (this is FirDefaultPropertyAccessor || this.source?.kind !is KtRealSourceElementKind) return false
|
||||
return hasModifier(KtTokens.EXTERNAL_KEYWORD) || hasAnnotation(JsNative, session)
|
||||
}
|
||||
|
||||
private fun FirDeclaration.isPrivateMemberOfExternalClass(session: FirSession): Boolean {
|
||||
if (this is FirPropertyAccessor && visibility == propertySymbol.visibility) return false
|
||||
if (this !is FirMemberDeclaration || visibility != Visibilities.Private) return false
|
||||
|
||||
val containingDeclaration = getContainingClassSymbol(session) ?: return false
|
||||
return containingDeclaration.isNativeObject(session)
|
||||
}
|
||||
|
||||
private fun FirDeclaration.isNonAbstractMemberIfInterface(session: FirSession): Boolean {
|
||||
return this is FirCallableDeclaration
|
||||
&& modality != Modality.ABSTRACT
|
||||
&& (getContainingClassSymbol(session) as? FirClassSymbol<*>)?.classKind == ClassKind.INTERFACE
|
||||
&& this !is FirPropertyAccessor
|
||||
}
|
||||
|
||||
private fun FirCallableDeclaration.isNullableProperty() = this is FirProperty && returnTypeRef.coneType.isNullable
|
||||
|
||||
private fun FirDeclaration.hasValidExternalBody(): Boolean {
|
||||
val body = when (this) {
|
||||
is FirFunction -> body
|
||||
is FirAnonymousInitializer -> body
|
||||
else -> return true
|
||||
}
|
||||
|
||||
return when {
|
||||
body is FirSingleExpressionBlock -> body.isDefinedExternallyExpression()
|
||||
body != null -> {
|
||||
val statement = body.statements.singleOrNull() ?: return false
|
||||
statement.isDefinedExternallyExpression()
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirElement.isDefinedExternallyExpression(): Boolean {
|
||||
val declaration = (this as? FirPropertyAccessExpression)
|
||||
?.calleeReference?.toResolvedPropertySymbol() ?: return false
|
||||
return declaration.callableId in JsStandardClassIds.Callables.definedExternallyPropertyNames
|
||||
}
|
||||
}
|
||||
@@ -206,6 +206,11 @@ fun FirNamedFunctionSymbol.overriddenFunctions(
|
||||
return overriddenFunctions
|
||||
}
|
||||
|
||||
fun FirClass.collectSupertypesWithDelegates(): Map<FirTypeRef, FirFieldSymbol?> {
|
||||
val fieldsMap = delegateFieldsMap ?: emptyMap()
|
||||
return superTypeRefs.mapIndexed { index, it -> it to fieldsMap[index] }.toMap()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the modality of the class
|
||||
*/
|
||||
|
||||
+1
-1
@@ -1120,7 +1120,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
source = parameterSource?.fakeElement(KtFakeSourceElementKind.DataClassGeneratedMembers)
|
||||
moduleData = baseModuleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
returnTypeRef = firProperty.returnTypeRef
|
||||
returnTypeRef = firProperty.returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.DataClassGeneratedMembers)
|
||||
this.name = name
|
||||
status = FirDeclarationStatusImpl(Visibilities.Public, Modality.FINAL).apply {
|
||||
isOperator = true
|
||||
|
||||
+2
-2
@@ -443,13 +443,13 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
|
||||
when {
|
||||
isGetter -> {
|
||||
if (returnTypeRef is FirImplicitTypeRef || forceUpdateForNonImplicitTypes) {
|
||||
replaceReturnTypeRef(propertyTypeRef)
|
||||
replaceReturnTypeRef(propertyTypeRef.copyWithNewSource(returnTypeRef.source))
|
||||
}
|
||||
}
|
||||
isSetter -> {
|
||||
val valueParameter = valueParameters.firstOrNull() ?: return
|
||||
if (valueParameter.returnTypeRef is FirImplicitTypeRef) {
|
||||
valueParameter.replaceReturnTypeRef(propertyTypeRef)
|
||||
valueParameter.replaceReturnTypeRef(propertyTypeRef.copyWithNewSource(returnTypeRef.source))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,9 @@
|
||||
package org.jetbrains.kotlin.fir
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.KtPsiSourceElement
|
||||
import org.jetbrains.kotlin.KtRealPsiSourceElement
|
||||
import org.jetbrains.kotlin.*
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fakeElement
|
||||
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
@@ -32,11 +29,15 @@ import org.jetbrains.kotlin.util.wrapIntoSourceCodeAnalysisExceptionIfNeeded
|
||||
// TODO: rewrite
|
||||
fun FirBlock.returnExpressions(): List<FirExpression> = listOfNotNull(statements.lastOrNull() as? FirExpression)
|
||||
|
||||
// do we need a deep copy here ?
|
||||
fun <R : FirTypeRef> R.copyWithNewSourceKind(newKind: KtFakeSourceElementKind): R {
|
||||
if (source == null) return this
|
||||
if (source?.kind == newKind) return this
|
||||
val newSource = source?.fakeElement(newKind)
|
||||
return copyWithNewSource(source?.fakeElement(newKind))
|
||||
}
|
||||
|
||||
// do we need a deep copy here ?
|
||||
fun <R : FirTypeRef> R.copyWithNewSource(newSource: KtSourceElement?): R {
|
||||
if (source?.kind == newSource?.kind) return this
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return when (val typeRef = this) {
|
||||
@@ -63,7 +64,7 @@ fun <R : FirTypeRef> R.copyWithNewSourceKind(newKind: KtFakeSourceElementKind):
|
||||
isMarkedNullable = typeRef.isMarkedNullable
|
||||
annotations += typeRef.annotations
|
||||
}
|
||||
is FirImplicitBuiltinTypeRef -> typeRef.withFakeSource(newKind)
|
||||
is FirImplicitBuiltinTypeRef -> typeRef.withNewSource(newSource)
|
||||
is FirIntersectionTypeRef -> buildIntersectionTypeRef {
|
||||
source = newSource
|
||||
isMarkedNullable = typeRef.isMarkedNullable
|
||||
|
||||
+2
@@ -43,3 +43,5 @@ val FirDeclaration.isNonLocal
|
||||
is FirClassLikeDeclaration -> !symbol.classId.isLocal
|
||||
else -> false
|
||||
}
|
||||
|
||||
val FirCallableDeclaration.isExtension get() = receiverParameter != null
|
||||
|
||||
+2
-3
@@ -183,10 +183,9 @@ class FirImplicitKMutableProperty2TypeRef(
|
||||
arrayOf(dispatchReceiverTypeArgument, extensionReceiverTypeArgument, propertyTypeArgument)
|
||||
)
|
||||
|
||||
fun FirImplicitBuiltinTypeRef.withFakeSource(kind: KtFakeSourceElementKind): FirImplicitBuiltinTypeRef {
|
||||
fun FirImplicitBuiltinTypeRef.withNewSource(newSource: KtSourceElement?): FirImplicitBuiltinTypeRef {
|
||||
val source = source ?: return this
|
||||
if (source.kind == kind) return this
|
||||
val newSource = source.fakeElement(kind)
|
||||
if (source.kind == newSource?.kind) return this
|
||||
return when (this) {
|
||||
is FirImplicitUnitTypeRef -> FirImplicitUnitTypeRef(newSource)
|
||||
is FirImplicitAnyTypeRef -> FirImplicitAnyTypeRef(newSource)
|
||||
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
external class A {
|
||||
init {
|
||||
definedExternally
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
external class A {
|
||||
<!EXTERNAL_ANONYMOUS_INITIALIZER!>init {
|
||||
definedExternally
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
external fun foo(): Int = definedExternally
|
||||
|
||||
external fun bar(): Unit {
|
||||
definedExternally
|
||||
}
|
||||
|
||||
external fun baz(): Int = 23
|
||||
|
||||
external fun f(x: Int, y: String = definedExternally): Unit
|
||||
|
||||
external fun g(x: Int, y: String = ""): Unit
|
||||
|
||||
external var a: Int
|
||||
get() = definedExternally
|
||||
set(value) {
|
||||
definedExternally
|
||||
}
|
||||
|
||||
external val b: Int
|
||||
get() = 23
|
||||
|
||||
external val c: Int = definedExternally
|
||||
|
||||
external val d: Int = 23
|
||||
|
||||
external class C {
|
||||
fun foo(): Int = definedExternally
|
||||
|
||||
fun bar(): Int = 23
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
external fun foo(): Int = definedExternally
|
||||
|
||||
external fun bar(): Unit {
|
||||
@@ -27,4 +28,4 @@ external class C {
|
||||
fun foo(): Int = definedExternally
|
||||
|
||||
fun bar(): Int = <!WRONG_BODY_OF_EXTERNAL_DECLARATION!>23<!>
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -1,17 +1,17 @@
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_MISSING_UNRESOLVED
|
||||
|
||||
external open class Base(x: Int) {
|
||||
constructor(x: String) : this(23)
|
||||
constructor(x: String) : <!EXTERNAL_DELEGATED_CONSTRUCTOR_CALL!>this<!>(23)
|
||||
|
||||
constructor(x: String, y: String) : this("")
|
||||
constructor(x: String, y: String) : <!EXTERNAL_DELEGATED_CONSTRUCTOR_CALL!>this<!>("")
|
||||
}
|
||||
|
||||
external open class Derived1() : Base(23) {
|
||||
constructor(x: Byte) : super(23)
|
||||
external open class Derived1() : <!EXTERNAL_DELEGATED_CONSTRUCTOR_CALL!>Base(23)<!> {
|
||||
constructor(x: Byte) : <!EXTERNAL_DELEGATED_CONSTRUCTOR_CALL!>super<!>(23)
|
||||
|
||||
constructor(x: String) : super("")
|
||||
constructor(x: String) : <!EXTERNAL_DELEGATED_CONSTRUCTOR_CALL!>super<!>("")
|
||||
|
||||
constructor(x: String, y: String) : super("")
|
||||
constructor(x: String, y: String) : <!EXTERNAL_DELEGATED_CONSTRUCTOR_CALL!>super<!>("")
|
||||
}
|
||||
|
||||
external open class Derived2() : Base("")
|
||||
external open class Derived2() : <!EXTERNAL_DELEGATED_CONSTRUCTOR_CALL!>Base("")<!>
|
||||
|
||||
@@ -9,10 +9,10 @@ class Delegate {
|
||||
operator fun setValue(thisRef: Any?, property: Any, value: String) {}
|
||||
}
|
||||
|
||||
external class A : I by O {
|
||||
val prop by Delegate()
|
||||
external class A : <!EXTERNAL_DELEGATION!>I<!> by O {
|
||||
val prop by <!EXTERNAL_DELEGATION!>Delegate()<!>
|
||||
|
||||
var mutableProp by Delegate()
|
||||
var mutableProp by <!EXTERNAL_DELEGATION!>Delegate()<!>
|
||||
}
|
||||
|
||||
external val topLevelProp by Delegate()
|
||||
external val topLevelProp by <!EXTERNAL_DELEGATION!>Delegate()<!>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
external enum class E {
|
||||
X,
|
||||
Y {
|
||||
<!EXTERNAL_ENUM_ENTRY_WITH_BODY!>Y {
|
||||
fun foo()
|
||||
},
|
||||
Z {}
|
||||
},<!>
|
||||
<!EXTERNAL_ENUM_ENTRY_WITH_BODY!>Z {}<!>
|
||||
}
|
||||
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
class A
|
||||
|
||||
external fun A.foo(): Unit = definedExternally
|
||||
|
||||
external var A.bar: String
|
||||
get() = definedExternally
|
||||
set(value) = definedExternally
|
||||
|
||||
external val A.baz: String
|
||||
get() = definedExternally
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class A
|
||||
|
||||
<!WRONG_EXTERNAL_DECLARATION!>external fun A.foo(): Unit<!> = definedExternally
|
||||
|
||||
Vendored
-25
@@ -1,25 +0,0 @@
|
||||
external fun foo(f: Int.() -> Int)
|
||||
|
||||
external fun bar(vararg f: Int.() -> Int)
|
||||
|
||||
external fun baz(): Int.() -> Int
|
||||
|
||||
external val prop: Int.() -> Int
|
||||
|
||||
external var prop2: Int.() -> Int
|
||||
|
||||
external val propGet
|
||||
get(): Int.() -> Int = definedExternally
|
||||
|
||||
external var propSet
|
||||
get(): Int.() -> Int = definedExternally
|
||||
set(v: Int.() -> Int) = definedExternally
|
||||
|
||||
external class A(f: Int.() -> Int)
|
||||
|
||||
external data class B(
|
||||
val a: Int.() -> Int,
|
||||
var b: Int.() -> Int
|
||||
) {
|
||||
val c: Int.() -> Int
|
||||
}
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
external fun foo(<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>f: Int.() -> Int<!>)
|
||||
|
||||
external fun bar(<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>vararg f: Int.() -> Int<!>)
|
||||
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
external fun interface I {
|
||||
fun f()
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
external fun interface <!WRONG_EXTERNAL_DECLARATION!>I<!> {
|
||||
fun f()
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
external interface I {
|
||||
interface J
|
||||
|
||||
class C
|
||||
|
||||
object O
|
||||
|
||||
enum class E
|
||||
|
||||
companion object
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
external interface I {
|
||||
interface J
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
open class A
|
||||
|
||||
interface I
|
||||
|
||||
external open class B
|
||||
|
||||
external class C : A
|
||||
|
||||
external class D : B, I
|
||||
|
||||
external interface K : I
|
||||
|
||||
external enum class E {
|
||||
X
|
||||
}
|
||||
|
||||
external enum class F : I {
|
||||
X
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
open class A
|
||||
|
||||
interface I
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// !DIAGNOSTICS: -NOTHING_TO_INLINE
|
||||
|
||||
inline external fun foo(): Unit
|
||||
|
||||
inline external val bar: Int
|
||||
get() = definedExternally
|
||||
|
||||
external val baz: Int
|
||||
inline get() = definedExternally
|
||||
|
||||
external class A {
|
||||
inline fun foo(): Unit
|
||||
|
||||
inline val bar: Int
|
||||
get() = definedExternally
|
||||
|
||||
val baz: Int
|
||||
inline get() = definedExternally
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -NOTHING_TO_INLINE
|
||||
|
||||
<!INLINE_EXTERNAL_DECLARATION!>inline external fun foo(): Unit<!>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses
|
||||
|
||||
external inline class C(val a: Int) {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
<!WRONG_MODIFIER_TARGET!>inline<!> external enum class E {
|
||||
A
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses
|
||||
|
||||
external inline class <!WRONG_EXTERNAL_DECLARATION!>C(<!EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER!>val a: Int<!>)<!> {
|
||||
|
||||
Vendored
-64
@@ -1,64 +0,0 @@
|
||||
// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses
|
||||
|
||||
// FILE: uint.kt
|
||||
|
||||
package kotlin
|
||||
|
||||
inline class UInt(private val i: Int)
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
inline class SomeIC(val a: Int)
|
||||
|
||||
external val l: SomeIC
|
||||
|
||||
external val ll
|
||||
get(): SomeIC = definedExternally
|
||||
|
||||
external var r: SomeIC
|
||||
|
||||
external var rr: SomeIC
|
||||
get() = definedExternally
|
||||
set(v: SomeIC) { definedExternally }
|
||||
|
||||
external fun foo(): SomeIC
|
||||
external fun foo(c: SomeIC): SomeIC
|
||||
external fun foo(a: Int, c: SomeIC): SomeIC
|
||||
|
||||
external fun foo(a: Int, <!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> args: SomeIC)
|
||||
external fun foo(a: Int, ui: UInt, vararg args: UInt)
|
||||
|
||||
external class CC(
|
||||
a: SomeIC,
|
||||
val b: SomeIC,
|
||||
var c: SomeIC
|
||||
) {
|
||||
val l: SomeIC
|
||||
var r: SomeIC
|
||||
|
||||
fun foo(): SomeIC
|
||||
fun foo(c: SomeIC): SomeIC
|
||||
fun foo(a: Int, c: SomeIC): SomeIC
|
||||
|
||||
class N(
|
||||
a: SomeIC,
|
||||
val b: SomeIC,
|
||||
var c: SomeIC
|
||||
) {
|
||||
val l: SomeIC
|
||||
var r: SomeIC
|
||||
|
||||
fun foo(): SomeIC
|
||||
fun foo(c: SomeIC): SomeIC
|
||||
fun foo(a: Int, c: SomeIC): SomeIC
|
||||
}
|
||||
}
|
||||
|
||||
external interface EI {
|
||||
val l: SomeIC
|
||||
var r: SomeIC
|
||||
|
||||
fun foo(): SomeIC
|
||||
fun foo(c: SomeIC): SomeIC
|
||||
fun foo(a: Int, c: SomeIC): SomeIC
|
||||
}
|
||||
Vendored
+2
-1
@@ -1,4 +1,5 @@
|
||||
// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses, -JsAllowValueClassesInExternals
|
||||
|
||||
// FILE: uint.kt
|
||||
|
||||
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses, +JsAllowValueClassesInExternals
|
||||
// !DIAGNOSTICS: +INLINE_CLASS_IN_EXTERNAL_DECLARATION_WARNING
|
||||
|
||||
// FILE: uint.kt
|
||||
|
||||
package kotlin
|
||||
|
||||
inline class UInt(private val i: Int)
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
inline class SomeIC(val a: Int)
|
||||
|
||||
external val l: SomeIC
|
||||
|
||||
external val ll
|
||||
get(): SomeIC = definedExternally
|
||||
|
||||
external var r: SomeIC
|
||||
|
||||
external var rr: SomeIC
|
||||
get() = definedExternally
|
||||
set(v: SomeIC) { definedExternally }
|
||||
|
||||
external fun foo(): SomeIC
|
||||
external fun foo(c: SomeIC): SomeIC
|
||||
external fun foo(a: Int, c: SomeIC): SomeIC
|
||||
|
||||
external fun foo(a: Int, <!FORBIDDEN_VARARG_PARAMETER_TYPE!>vararg<!> args: SomeIC)
|
||||
external fun foo(a: Int, ui: UInt, vararg args: UInt)
|
||||
|
||||
external class CC(
|
||||
a: SomeIC,
|
||||
val b: SomeIC,
|
||||
var c: SomeIC
|
||||
) {
|
||||
val l: SomeIC
|
||||
var r: SomeIC
|
||||
|
||||
fun foo(): SomeIC
|
||||
fun foo(c: SomeIC): SomeIC
|
||||
fun foo(a: Int, c: SomeIC): SomeIC
|
||||
|
||||
class N(
|
||||
a: SomeIC,
|
||||
val b: SomeIC,
|
||||
var c: SomeIC
|
||||
) {
|
||||
val l: SomeIC
|
||||
var r: SomeIC
|
||||
|
||||
fun foo(): SomeIC
|
||||
fun foo(c: SomeIC): SomeIC
|
||||
fun foo(a: Int, c: SomeIC): SomeIC
|
||||
}
|
||||
}
|
||||
|
||||
external interface EI {
|
||||
val l: SomeIC
|
||||
var r: SomeIC
|
||||
|
||||
fun foo(): SomeIC
|
||||
fun foo(c: SomeIC): SomeIC
|
||||
fun foo(a: Int, c: SomeIC): SomeIC
|
||||
}
|
||||
+2
@@ -1,4 +1,6 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses, +JsAllowValueClassesInExternals
|
||||
// !DIAGNOSTICS: +INLINE_CLASS_IN_EXTERNAL_DECLARATION_WARNING
|
||||
|
||||
// FILE: uint.kt
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
external class C {
|
||||
inner class Inner
|
||||
}
|
||||
|
||||
external enum class E {
|
||||
X;
|
||||
|
||||
inner class Inner
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
external class C {
|
||||
inner class <!WRONG_EXTERNAL_DECLARATION!>Inner<!>
|
||||
}
|
||||
@@ -6,4 +7,4 @@ external enum class E {
|
||||
X;
|
||||
|
||||
inner class <!WRONG_EXTERNAL_DECLARATION!>Inner<!>
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
object O
|
||||
|
||||
class TopLevel {
|
||||
external class A
|
||||
|
||||
class B
|
||||
|
||||
fun foo() = 23
|
||||
|
||||
external fun bar(): Int
|
||||
|
||||
val x = "a"
|
||||
|
||||
external val y: String
|
||||
|
||||
val O.u: String get() = "O.u"
|
||||
}
|
||||
|
||||
external class TopLevelNative {
|
||||
external class A
|
||||
|
||||
class B
|
||||
|
||||
fun foo(): Int = definedExternally
|
||||
|
||||
external fun bar(): Int
|
||||
|
||||
val x: String = definedExternally
|
||||
|
||||
external val y: String
|
||||
}
|
||||
|
||||
fun topLevelFun() {
|
||||
external class A
|
||||
|
||||
class B
|
||||
|
||||
fun foo() = 23
|
||||
|
||||
external fun bar(): Int
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
object O
|
||||
|
||||
class TopLevel {
|
||||
@@ -39,4 +40,3 @@ fun topLevelFun() {
|
||||
|
||||
<!NESTED_EXTERNAL_DECLARATION!>external fun bar(): Int<!>
|
||||
}
|
||||
|
||||
|
||||
Vendored
-21
@@ -1,21 +0,0 @@
|
||||
external interface I {
|
||||
fun foo(): Unit = definedExternally
|
||||
|
||||
val a: Int?
|
||||
get() = definedExternally
|
||||
|
||||
var b: String?
|
||||
get() = definedExternally
|
||||
set(value) = definedExternally
|
||||
|
||||
val c: Int
|
||||
get() = definedExternally
|
||||
|
||||
var d: String
|
||||
get() = definedExternally
|
||||
set(value) = definedExternally
|
||||
|
||||
var e: dynamic
|
||||
get() = definedExternally
|
||||
set(value) = definedExternally
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
external interface I {
|
||||
<!NON_ABSTRACT_MEMBER_OF_EXTERNAL_INTERFACE!>fun foo(): Unit<!> = definedExternally
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
// !DIAGNOSTICS: -NOTHING_TO_INLINE
|
||||
// TODO: should we disable NOTHING_TO_INLINE in JS backend?
|
||||
// TODO: uncomment declarations in case we decide to implement KT-14031
|
||||
|
||||
external class C {
|
||||
private fun a(): Int
|
||||
|
||||
private val b: String
|
||||
|
||||
private var c: Float
|
||||
|
||||
private var d: Float
|
||||
get
|
||||
set
|
||||
|
||||
var e: Float
|
||||
get
|
||||
private set
|
||||
|
||||
/*
|
||||
private inline fun inline_a(): Int = 23
|
||||
|
||||
private inline val inline_prop: Int
|
||||
get() = 42
|
||||
*/
|
||||
}
|
||||
|
||||
external object O {
|
||||
private fun a(): Int
|
||||
|
||||
private val b: String
|
||||
|
||||
private var c: Float
|
||||
|
||||
private var d: Float
|
||||
get
|
||||
set
|
||||
|
||||
/*
|
||||
private inline fun inline_a(): Int = 23
|
||||
|
||||
private inline val inline_prop: Int
|
||||
get() = 42
|
||||
*/
|
||||
}
|
||||
|
||||
external class Outer {
|
||||
class Inner {
|
||||
private fun a(): Int
|
||||
|
||||
private val b: String
|
||||
|
||||
private var c: Float
|
||||
|
||||
private var d: Float
|
||||
get
|
||||
set
|
||||
|
||||
/*
|
||||
private inline fun inline_a(): Int = 23
|
||||
|
||||
private inline val inline_prop: Int
|
||||
get() = 42
|
||||
*/
|
||||
}
|
||||
|
||||
private class PrivateInner
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -NOTHING_TO_INLINE
|
||||
// TODO: should we disable NOTHING_TO_INLINE in JS backend?
|
||||
// TODO: uncomment declarations in case we decide to implement KT-14031
|
||||
|
||||
-1
@@ -1 +0,0 @@
|
||||
external class C(x: Int, val y: String)
|
||||
@@ -1 +1,2 @@
|
||||
// FIR_IDENTICAL
|
||||
external class C(x: Int, <!EXTERNAL_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER!>val y: String<!>)
|
||||
@@ -1,21 +0,0 @@
|
||||
external annotation class A(val x: Int)
|
||||
|
||||
val x: Int
|
||||
external get() = definedExternally
|
||||
|
||||
class B
|
||||
|
||||
val B.x: Int
|
||||
external get() = definedExternally
|
||||
|
||||
class C {
|
||||
val a: Int
|
||||
external get() = definedExternally
|
||||
}
|
||||
|
||||
external class D {
|
||||
val a: Int
|
||||
external get() = definedExternally
|
||||
}
|
||||
|
||||
external data class E(val x: Int)
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
external annotation class <!WRONG_EXTERNAL_DECLARATION!>A(val x: Int)<!>
|
||||
|
||||
val x: Int
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.js.PredefinedAnnotation
|
||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.name.JsStandardClassIds
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -28,7 +28,8 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
object JsExternalChecker : DeclarationChecker {
|
||||
val DEFINED_EXTERNALLY_PROPERTY_NAMES = setOf(FqNameUnsafe("kotlin.js.noImpl"), FqNameUnsafe("kotlin.js.definedExternally"))
|
||||
val DEFINED_EXTERNALLY_PROPERTY_NAMES = JsStandardClassIds.Callables.definedExternallyPropertyNames
|
||||
.map { it.asSingleFqName().toUnsafe() }
|
||||
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (!AnnotationsUtils.isNativeObject(descriptor)) return
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// IGNORE_BACKEND_K1: JS_IR
|
||||
// IGNORE_BACKEND_K2: JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// TODO: Unmute when extension functions are supported in external declarations.
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// IGNORE_BACKEND_K1: JS_IR
|
||||
// IGNORE_BACKEND_K2: JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// TODO: Unmute when extension functions are supported in external declarations.
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
Reference in New Issue
Block a user