[K/JS] Support companion objects in external and exported declarations
This commit is contained in:
+12
@@ -5742,6 +5742,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirJsErrors.NAMED_COMPANION_IN_EXPORTED_INTERFACE) { firDiagnostic ->
|
||||||
|
NamedCompanionInExportedInterfaceImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirWebCommonErrors.NESTED_JS_EXPORT) { firDiagnostic ->
|
add(FirWebCommonErrors.NESTED_JS_EXPORT) { firDiagnostic ->
|
||||||
NestedJsExportImpl(
|
NestedJsExportImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
@@ -5881,6 +5887,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirWebCommonErrors.NAMED_COMPANION_IN_EXTERNAL_INTERFACE) { firDiagnostic ->
|
||||||
|
NamedCompanionInExternalInterfaceImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirWebCommonErrors.JSCODE_ARGUMENT_NON_CONST_EXPRESSION) { firDiagnostic ->
|
add(FirWebCommonErrors.JSCODE_ARGUMENT_NON_CONST_EXPRESSION) { firDiagnostic ->
|
||||||
JscodeArgumentNonConstExpressionImpl(
|
JscodeArgumentNonConstExpressionImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+8
@@ -3999,6 +3999,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
val name: String
|
val name: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface NamedCompanionInExportedInterface : KtFirDiagnostic<KtElement> {
|
||||||
|
override val diagnosticClass get() = NamedCompanionInExportedInterface::class
|
||||||
|
}
|
||||||
|
|
||||||
interface NestedJsExport : KtFirDiagnostic<KtElement> {
|
interface NestedJsExport : KtFirDiagnostic<KtElement> {
|
||||||
override val diagnosticClass get() = NestedJsExport::class
|
override val diagnosticClass get() = NestedJsExport::class
|
||||||
}
|
}
|
||||||
@@ -4094,6 +4098,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
val typeArgument: KtType
|
val typeArgument: KtType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface NamedCompanionInExternalInterface : KtFirDiagnostic<KtElement> {
|
||||||
|
override val diagnosticClass get() = NamedCompanionInExternalInterface::class
|
||||||
|
}
|
||||||
|
|
||||||
interface JscodeArgumentNonConstExpression : KtFirDiagnostic<KtElement> {
|
interface JscodeArgumentNonConstExpression : KtFirDiagnostic<KtElement> {
|
||||||
override val diagnosticClass get() = JscodeArgumentNonConstExpression::class
|
override val diagnosticClass get() = JscodeArgumentNonConstExpression::class
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -4828,6 +4828,11 @@ internal class NonConsumableExportedIdentifierImpl(
|
|||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
) : KtAbstractFirDiagnostic<KtElement>(firDiagnostic, token), KtFirDiagnostic.NonConsumableExportedIdentifier
|
) : KtAbstractFirDiagnostic<KtElement>(firDiagnostic, token), KtFirDiagnostic.NonConsumableExportedIdentifier
|
||||||
|
|
||||||
|
internal class NamedCompanionInExportedInterfaceImpl(
|
||||||
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
|
token: KtLifetimeToken,
|
||||||
|
) : KtAbstractFirDiagnostic<KtElement>(firDiagnostic, token), KtFirDiagnostic.NamedCompanionInExportedInterface
|
||||||
|
|
||||||
internal class NestedJsExportImpl(
|
internal class NestedJsExportImpl(
|
||||||
firDiagnostic: KtPsiDiagnostic,
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
@@ -4945,6 +4950,11 @@ internal class ExternalInterfaceAsReifiedTypeArgumentImpl(
|
|||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
) : KtAbstractFirDiagnostic<KtElement>(firDiagnostic, token), KtFirDiagnostic.ExternalInterfaceAsReifiedTypeArgument
|
) : KtAbstractFirDiagnostic<KtElement>(firDiagnostic, token), KtFirDiagnostic.ExternalInterfaceAsReifiedTypeArgument
|
||||||
|
|
||||||
|
internal class NamedCompanionInExternalInterfaceImpl(
|
||||||
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
|
token: KtLifetimeToken,
|
||||||
|
) : KtAbstractFirDiagnostic<KtElement>(firDiagnostic, token), KtFirDiagnostic.NamedCompanionInExternalInterface
|
||||||
|
|
||||||
internal class JscodeArgumentNonConstExpressionImpl(
|
internal class JscodeArgumentNonConstExpressionImpl(
|
||||||
firDiagnostic: KtPsiDiagnostic,
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
|
|||||||
+1
@@ -113,6 +113,7 @@ object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") {
|
|||||||
val NON_CONSUMABLE_EXPORTED_IDENTIFIER by warning<KtElement>(PositioningStrategy.DEFAULT) {
|
val NON_CONSUMABLE_EXPORTED_IDENTIFIER by warning<KtElement>(PositioningStrategy.DEFAULT) {
|
||||||
parameter<String>("name")
|
parameter<String>("name")
|
||||||
}
|
}
|
||||||
|
val NAMED_COMPANION_IN_EXPORTED_INTERFACE by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
}
|
}
|
||||||
|
|
||||||
val DYNAMICS by object : DiagnosticGroup("Dynamics") {
|
val DYNAMICS by object : DiagnosticGroup("Dynamics") {
|
||||||
|
|||||||
+1
@@ -44,6 +44,7 @@ object WEB_COMMON_DIAGNOSTICS_LIST : DiagnosticList("FirWebCommonErrors") {
|
|||||||
val EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
val EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||||
parameter<ConeKotlinType>("typeArgument")
|
parameter<ConeKotlinType>("typeArgument")
|
||||||
}
|
}
|
||||||
|
val NAMED_COMPANION_IN_EXTERNAL_INTERFACE by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
}
|
}
|
||||||
|
|
||||||
val EXPORT by object : DiagnosticGroup("Export") {
|
val EXPORT by object : DiagnosticGroup("Export") {
|
||||||
|
|||||||
+1
@@ -78,6 +78,7 @@ object FirJsErrors {
|
|||||||
val WRONG_EXPORTED_DECLARATION: KtDiagnosticFactory1<String> by error1<KtElement, String>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val WRONG_EXPORTED_DECLARATION: KtDiagnosticFactory1<String> by error1<KtElement, String>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
val NON_EXPORTABLE_TYPE: KtDiagnosticFactory2<String, ConeKotlinType> by warning2<KtElement, String, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val NON_EXPORTABLE_TYPE: KtDiagnosticFactory2<String, ConeKotlinType> by warning2<KtElement, String, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
val NON_CONSUMABLE_EXPORTED_IDENTIFIER: KtDiagnosticFactory1<String> by warning1<KtElement, String>()
|
val NON_CONSUMABLE_EXPORTED_IDENTIFIER: KtDiagnosticFactory1<String> by warning1<KtElement, String>()
|
||||||
|
val NAMED_COMPANION_IN_EXPORTED_INTERFACE: KtDiagnosticFactory0 by error0<KtElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
|
||||||
// Dynamics
|
// Dynamics
|
||||||
val DELEGATION_BY_DYNAMIC: KtDiagnosticFactory0 by error0<KtElement>()
|
val DELEGATION_BY_DYNAMIC: KtDiagnosticFactory0 by error0<KtElement>()
|
||||||
|
|||||||
+2
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_NAME_ON_P
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_NAME_PROHIBITED_FOR_EXTENSION_PROPERTY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_NAME_PROHIBITED_FOR_EXTENSION_PROPERTY
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_NAME_PROHIBITED_FOR_NAMED_NATIVE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_NAME_PROHIBITED_FOR_NAMED_NATIVE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_NAME_PROHIBITED_FOR_OVERRIDE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_NAME_PROHIBITED_FOR_OVERRIDE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NAMED_COMPANION_IN_EXPORTED_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NAME_CONTAINS_ILLEGAL_CHARS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NAME_CONTAINS_ILLEGAL_CHARS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NATIVE_ANNOTATIONS_ALLOWED_ONLY_ON_MEMBER_OR_EXTENSION_FUN
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NATIVE_ANNOTATIONS_ALLOWED_ONLY_ON_MEMBER_OR_EXTENSION_FUN
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NATIVE_GETTER_RETURN_TYPE_SHOULD_BE_NULLABLE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NATIVE_GETTER_RETURN_TYPE_SHOULD_BE_NULLABLE
|
||||||
@@ -189,5 +190,6 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
"Exported declaration contains non-consumable identifier ''{0}'', which cannot be represented inside TS definitions and ESM.",
|
"Exported declaration contains non-consumable identifier ''{0}'', which cannot be represented inside TS definitions and ESM.",
|
||||||
CommonRenderers.STRING,
|
CommonRenderers.STRING,
|
||||||
)
|
)
|
||||||
|
map.put(NAMED_COMPANION_IN_EXPORTED_INTERFACE, "Named companions are not allowed inside exported interfaces.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-2
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.types.*
|
|||||||
import org.jetbrains.kotlin.js.common.RESERVED_KEYWORDS
|
import org.jetbrains.kotlin.js.common.RESERVED_KEYWORDS
|
||||||
import org.jetbrains.kotlin.js.common.SPECIAL_KEYWORDS
|
import org.jetbrains.kotlin.js.common.SPECIAL_KEYWORDS
|
||||||
import org.jetbrains.kotlin.name.JsStandardClassIds
|
import org.jetbrains.kotlin.name.JsStandardClassIds
|
||||||
|
import org.jetbrains.kotlin.name.SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
|
||||||
|
|
||||||
object FirJsExportDeclarationChecker : FirBasicDeclarationChecker(MppCheckerKind.Common) {
|
object FirJsExportDeclarationChecker : FirBasicDeclarationChecker(MppCheckerKind.Common) {
|
||||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
@@ -135,11 +136,15 @@ object FirJsExportDeclarationChecker : FirBasicDeclarationChecker(MppCheckerKind
|
|||||||
declaration.isInline -> "value class"
|
declaration.isInline -> "value class"
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
else -> if (context.isInsideInterface) {
|
else -> if (context.isInsideInterface && !declaration.status.isCompanion) {
|
||||||
"${if (declaration.status.isCompanion) "companion object" else "nested/inner declaration"} inside exported interface"
|
"nested/inner declaration inside exported interface"
|
||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.isInsideInterface && declaration.status.isCompanion && declaration.nameOrSpecialName != DEFAULT_NAME_FOR_COMPANION_OBJECT) {
|
||||||
|
reporter.reportOn(declaration.source, FirJsErrors.NAMED_COMPANION_IN_EXPORTED_INTERFACE, context)
|
||||||
|
}
|
||||||
|
|
||||||
if (wrongDeclaration != null) {
|
if (wrongDeclaration != null) {
|
||||||
reportWrongExportedDeclaration(wrongDeclaration)
|
reportWrongExportedDeclaration(wrongDeclaration)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.name.JsStandardClassIds
|
|||||||
import org.jetbrains.kotlin.name.JsStandardClassIds.Annotations.JsNative
|
import org.jetbrains.kotlin.name.JsStandardClassIds.Annotations.JsNative
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
|
|
||||||
object FirJsExternalChecker : FirWebCommonExternalChecker() {
|
object FirJsExternalChecker : FirWebCommonExternalChecker(allowCompanionInInterface = true) {
|
||||||
override fun isNativeOrEffectivelyExternal(symbol: FirBasedSymbol<*>, session: FirSession): Boolean {
|
override fun isNativeOrEffectivelyExternal(symbol: FirBasedSymbol<*>, session: FirSession): Boolean {
|
||||||
return symbol.isNativeObject(session)
|
return symbol.isNativeObject(session)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
|||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.name.WebCommonStandardClassIds
|
import org.jetbrains.kotlin.name.WebCommonStandardClassIds
|
||||||
|
|
||||||
object FirWasmExternalChecker : FirWebCommonExternalChecker() {
|
object FirWasmExternalChecker : FirWebCommonExternalChecker(allowCompanionInInterface = false) {
|
||||||
override fun isNativeOrEffectivelyExternal(symbol: FirBasedSymbol<*>, session: FirSession): Boolean {
|
override fun isNativeOrEffectivelyExternal(symbol: FirBasedSymbol<*>, session: FirSession): Boolean {
|
||||||
return symbol.isEffectivelyExternal(session)
|
return symbol.isEffectivelyExternal(session)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -43,6 +43,7 @@ object FirWebCommonErrors {
|
|||||||
val UNCHECKED_CAST_TO_EXTERNAL_INTERFACE: KtDiagnosticFactory2<ConeKotlinType, ConeKotlinType> by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
|
val UNCHECKED_CAST_TO_EXTERNAL_INTERFACE: KtDiagnosticFactory2<ConeKotlinType, ConeKotlinType> by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
|
||||||
val EXTERNAL_INTERFACE_AS_CLASS_LITERAL: KtDiagnosticFactory0 by error0<KtElement>()
|
val EXTERNAL_INTERFACE_AS_CLASS_LITERAL: KtDiagnosticFactory0 by error0<KtElement>()
|
||||||
val EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT: KtDiagnosticFactory1<ConeKotlinType> by error1<KtElement, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT: KtDiagnosticFactory1<ConeKotlinType> by error1<KtElement, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
val NAMED_COMPANION_IN_EXTERNAL_INTERFACE: KtDiagnosticFactory0 by error0<KtElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
|
||||||
// Export
|
// Export
|
||||||
val NESTED_JS_EXPORT: KtDiagnosticFactory0 by error0<KtElement>()
|
val NESTED_JS_EXPORT: KtDiagnosticFactory0 by error0<KtElement>()
|
||||||
|
|||||||
+2
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.web.common.FirWebCommonErro
|
|||||||
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.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.NAMED_COMPANION_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_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
|
||||||
@@ -76,5 +77,6 @@ object FirWebCommonErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
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.")
|
||||||
|
|
||||||
map.put(JSCODE_ARGUMENT_NON_CONST_EXPRESSION, "An argument for the 'js()' function must be a constant string expression.")
|
map.put(JSCODE_ARGUMENT_NON_CONST_EXPRESSION, "An argument for the 'js()' function must be a constant string expression.")
|
||||||
|
map.put(NAMED_COMPANION_IN_EXTERNAL_INTERFACE, "Named companions are not allowed inside external interfaces.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+17
-6
@@ -6,9 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.analysis.web.common.checkers.declaration
|
package org.jetbrains.kotlin.fir.analysis.web.common.checkers.declaration
|
||||||
|
|
||||||
import org.jetbrains.kotlin.*
|
import org.jetbrains.kotlin.*
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
@@ -30,9 +28,10 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
|||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
|
import org.jetbrains.kotlin.name.SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
|
|
||||||
abstract class FirWebCommonExternalChecker : FirBasicDeclarationChecker(MppCheckerKind.Common) {
|
abstract class FirWebCommonExternalChecker(private val allowCompanionInInterface: Boolean) : FirBasicDeclarationChecker(MppCheckerKind.Common) {
|
||||||
abstract fun isNativeOrEffectivelyExternal(symbol: FirBasedSymbol<*>, session: FirSession): Boolean
|
abstract fun isNativeOrEffectivelyExternal(symbol: FirBasedSymbol<*>, session: FirSession): Boolean
|
||||||
|
|
||||||
abstract fun reportExternalEnum(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter)
|
abstract fun reportExternalEnum(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter)
|
||||||
@@ -87,12 +86,24 @@ abstract class FirWebCommonExternalChecker : FirBasicDeclarationChecker(MppCheck
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
declaration is FirClass &&
|
declaration is FirClass &&
|
||||||
declaration.classKind != ClassKind.INTERFACE &&
|
!declaration.classKind.isInterface && (!allowCompanionInInterface || !declaration.status.isCompanion) &&
|
||||||
container is FirClass && container.classKind == ClassKind.INTERFACE
|
container is FirClass && container.classKind.isInterface
|
||||||
) {
|
) {
|
||||||
reporter.reportOn(declaration.source, FirWebCommonErrors.NESTED_CLASS_IN_EXTERNAL_INTERFACE, context)
|
reporter.reportOn(declaration.source, FirWebCommonErrors.NESTED_CLASS_IN_EXTERNAL_INTERFACE, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
allowCompanionInInterface &&
|
||||||
|
declaration is FirClass &&
|
||||||
|
declaration.status.isCompanion &&
|
||||||
|
container is FirClass &&
|
||||||
|
container.isInterface &&
|
||||||
|
declaration.nameOrSpecialName != DEFAULT_NAME_FOR_COMPANION_OBJECT
|
||||||
|
) {
|
||||||
|
reporter.reportOn(declaration.source, FirWebCommonErrors.NAMED_COMPANION_IN_EXTERNAL_INTERFACE, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (declaration !is FirPropertyAccessor && declaration is FirCallableDeclaration && declaration.isExtension) {
|
if (declaration !is FirPropertyAccessor && declaration is FirCallableDeclaration && declaration.isExtension) {
|
||||||
val target = when (declaration) {
|
val target = when (declaration) {
|
||||||
is FirFunction -> "extension function"
|
is FirFunction -> "extension function"
|
||||||
|
|||||||
+2
@@ -645,6 +645,7 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
|
|||||||
"JS_EXTERNAL_INHERITORS_ONLY",
|
"JS_EXTERNAL_INHERITORS_ONLY",
|
||||||
"JS_EXTERNAL_ARGUMENT",
|
"JS_EXTERNAL_ARGUMENT",
|
||||||
"WRONG_EXPORTED_DECLARATION",
|
"WRONG_EXPORTED_DECLARATION",
|
||||||
|
"NAMED_COMPANION_IN_EXPORTED_INTERFACE",
|
||||||
"NESTED_JS_EXPORT",
|
"NESTED_JS_EXPORT",
|
||||||
"DELEGATION_BY_DYNAMIC",
|
"DELEGATION_BY_DYNAMIC",
|
||||||
"PROPERTY_DELEGATION_BY_DYNAMIC",
|
"PROPERTY_DELEGATION_BY_DYNAMIC",
|
||||||
@@ -700,6 +701,7 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
|
|||||||
"CANNOT_CHECK_FOR_EXTERNAL_INTERFACE",
|
"CANNOT_CHECK_FOR_EXTERNAL_INTERFACE",
|
||||||
"EXTERNAL_INTERFACE_AS_CLASS_LITERAL",
|
"EXTERNAL_INTERFACE_AS_CLASS_LITERAL",
|
||||||
"EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT",
|
"EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT",
|
||||||
|
"NAMED_COMPANION_IN_EXTERNAL_INTERFACE",
|
||||||
"JSCODE_ARGUMENT_NON_CONST_EXPRESSION",
|
"JSCODE_ARGUMENT_NON_CONST_EXPRESSION",
|
||||||
"SYNTAX",
|
"SYNTAX",
|
||||||
)
|
)
|
||||||
|
|||||||
+18
-7
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
import org.jetbrains.kotlin.utils.*
|
import org.jetbrains.kotlin.utils.*
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
@@ -328,12 +329,15 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
|||||||
members.addIfNotNull(exportProperty(candidate)?.withAttributesFor(candidate))
|
members.addIfNotNull(exportProperty(candidate)?.withAttributesFor(candidate))
|
||||||
|
|
||||||
is IrClass -> {
|
is IrClass -> {
|
||||||
if (klass.isInterface) continue
|
if (klass.isInterface) {
|
||||||
val ec = exportClass(candidate)?.withAttributesFor(candidate)
|
nestedClasses.addIfNotNull(klass.companionObject()?.let { exportClass(it) as? ExportedClass }?.withAttributesFor(candidate))
|
||||||
if (ec is ExportedClass) {
|
|
||||||
nestedClasses.add(ec)
|
|
||||||
} else {
|
} else {
|
||||||
members.addIfNotNull(ec)
|
val ec = exportClass(candidate)?.withAttributesFor(candidate)
|
||||||
|
if (ec is ExportedClass) {
|
||||||
|
nestedClasses.add(ec)
|
||||||
|
} else {
|
||||||
|
members.addIfNotNull(ec)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,7 +445,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
|||||||
.map { exportType(it, false) }
|
.map { exportType(it, false) }
|
||||||
.memoryOptimizedFilter { it !is ExportedType.ErrorType }
|
.memoryOptimizedFilter { it !is ExportedType.ErrorType }
|
||||||
|
|
||||||
val name = klass.getExportedIdentifier()
|
val name = klass.getExportedIdentifierForClass()
|
||||||
|
|
||||||
return if (klass.kind == ClassKind.OBJECT) {
|
return if (klass.kind == ClassKind.OBJECT) {
|
||||||
return ExportedObject(
|
return ExportedObject(
|
||||||
@@ -862,12 +866,19 @@ val strictModeReservedWords = setOf(
|
|||||||
|
|
||||||
private val allReservedWords = reservedWords + strictModeReservedWords
|
private val allReservedWords = reservedWords + strictModeReservedWords
|
||||||
|
|
||||||
fun ExportedDeclaration.withAttributesFor(declaration: IrDeclaration): ExportedDeclaration {
|
fun <T : ExportedDeclaration> T.withAttributesFor(declaration: IrDeclaration): T {
|
||||||
declaration.getDeprecated()?.let { attributes.add(ExportedAttribute.DeprecatedAttribute(it)) }
|
declaration.getDeprecated()?.let { attributes.add(ExportedAttribute.DeprecatedAttribute(it)) }
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun IrClass.getExportedIdentifierForClass(): String {
|
||||||
|
val parentClass = parentClassOrNull
|
||||||
|
return if (parentClass != null && isCompanion && parentClass.isInterface) {
|
||||||
|
parentClass.getExportedIdentifierForClass()
|
||||||
|
} else getExportedIdentifier()
|
||||||
|
}
|
||||||
|
|
||||||
fun IrDeclarationWithName.getExportedIdentifier(): String =
|
fun IrDeclarationWithName.getExportedIdentifier(): String =
|
||||||
with(getJsNameOrKotlinName()) {
|
with(getJsNameOrKotlinName()) {
|
||||||
if (isSpecial)
|
if (isSpecial)
|
||||||
|
|||||||
+5
-3
@@ -33,7 +33,7 @@ class ExportModelToJsStatements(
|
|||||||
fun generateModuleExport(
|
fun generateModuleExport(
|
||||||
module: ExportedModule,
|
module: ExportedModule,
|
||||||
internalModuleName: JsName?,
|
internalModuleName: JsName?,
|
||||||
esModules: Boolean
|
esModules: Boolean,
|
||||||
): List<JsStatement> {
|
): List<JsStatement> {
|
||||||
return module.declarations.flatMap {
|
return module.declarations.flatMap {
|
||||||
generateDeclarationExport(it, internalModuleName?.makeRef(), esModules)
|
generateDeclarationExport(it, internalModuleName?.makeRef(), esModules)
|
||||||
@@ -44,7 +44,7 @@ class ExportModelToJsStatements(
|
|||||||
declaration: ExportedDeclaration,
|
declaration: ExportedDeclaration,
|
||||||
namespace: JsExpression?,
|
namespace: JsExpression?,
|
||||||
esModules: Boolean,
|
esModules: Boolean,
|
||||||
parentClass: IrClass? = null
|
parentClass: IrClass? = null,
|
||||||
): List<JsStatement> {
|
): List<JsStatement> {
|
||||||
return when (declaration) {
|
return when (declaration) {
|
||||||
is ExportedNamespace -> {
|
is ExportedNamespace -> {
|
||||||
@@ -155,7 +155,9 @@ class ExportModelToJsStatements(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is ExportedRegularClass -> {
|
is ExportedRegularClass -> {
|
||||||
if (declaration.isInterface) return emptyList()
|
if (declaration.isInterface) {
|
||||||
|
return declaration.nestedClasses.flatMap { generateDeclarationExport(it, namespace, esModules, parentClass) }
|
||||||
|
}
|
||||||
val (name, classInitialization) = declaration.getNameAndInitialization()
|
val (name, classInitialization) = declaration.getNameAndInitialization()
|
||||||
val newNameSpace = when {
|
val newNameSpace = when {
|
||||||
namespace != null -> jsElementAccess(declaration.name, namespace)
|
namespace != null -> jsElementAccess(declaration.name, namespace)
|
||||||
|
|||||||
+19
-13
@@ -14,10 +14,7 @@ import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName
|
|||||||
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
|
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.util.isObject
|
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
|
||||||
import org.jetbrains.kotlin.ir.util.primaryConstructor
|
|
||||||
import org.jetbrains.kotlin.js.common.isValidES5Identifier
|
import org.jetbrains.kotlin.js.common.isValidES5Identifier
|
||||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
@@ -106,7 +103,7 @@ class ExportModelToTsDeclarations {
|
|||||||
is ExportedConstructSignature -> generateTypeScriptString(indent)
|
is ExportedConstructSignature -> generateTypeScriptString(indent)
|
||||||
is ExportedNamespace -> generateTypeScriptString(indent, prefix)
|
is ExportedNamespace -> generateTypeScriptString(indent, prefix)
|
||||||
is ExportedFunction -> generateTypeScriptString(indent, prefix)
|
is ExportedFunction -> generateTypeScriptString(indent, prefix)
|
||||||
is ExportedRegularClass -> generateTypeScriptString(indent, prefix)
|
is ExportedRegularClass -> generateTypeScriptString(indent, prefix, esModules)
|
||||||
is ExportedProperty -> generateTypeScriptString(indent, prefix, esModules)
|
is ExportedProperty -> generateTypeScriptString(indent, prefix, esModules)
|
||||||
is ExportedObject -> generateTypeScriptString(indent, prefix, esModules)
|
is ExportedObject -> generateTypeScriptString(indent, prefix, esModules)
|
||||||
}
|
}
|
||||||
@@ -235,7 +232,7 @@ class ExportModelToTsDeclarations {
|
|||||||
t = ExportedType.IntersectionType(t, ExportedType.InlineInterfaceType(listOf(constructor)))
|
t = ExportedType.IntersectionType(t, ExportedType.InlineInterfaceType(listOf(constructor)))
|
||||||
}
|
}
|
||||||
|
|
||||||
val maybeParentClass = ir.parent as? IrClass
|
val maybeParentClass = (ir.parent as? IrClass)?.takeIf { !it.isInterface }
|
||||||
|
|
||||||
val propertyName = ir
|
val propertyName = ir
|
||||||
.takeIf { shouldRenderSeparatedAbstractClass }
|
.takeIf { shouldRenderSeparatedAbstractClass }
|
||||||
@@ -275,21 +272,22 @@ class ExportModelToTsDeclarations {
|
|||||||
|
|
||||||
if (esModules && !property.isMember) {
|
if (esModules && !property.isMember) {
|
||||||
property.copy(type = ExportedType.TypeOf(className), name = name)
|
property.copy(type = ExportedType.TypeOf(className), name = name)
|
||||||
.generateTypeScriptString(indent, prefix, esModules) + "\n${classForRender.generateTypeScriptString(indent, declare)}"
|
.generateTypeScriptString(indent, prefix, esModules) + "\n${classForRender.generateTypeScriptString(indent, declare, esModules)}"
|
||||||
} else {
|
} else {
|
||||||
classForRender.generateTypeScriptString(indent, prefix)
|
classForRender.generateTypeScriptString(indent, prefix, esModules)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ExportedRegularClass.generateTypeScriptString(indent: String, prefix: String): String {
|
private fun ExportedRegularClass.generateTypeScriptString(indent: String, prefix: String, esModules: Boolean): String {
|
||||||
val keyword = if (isInterface) "interface" else "class"
|
val keyword = if (isInterface) "interface" else "class"
|
||||||
|
val (interfaceCompanions, allNestedClasses) = nestedClasses.partition { isInterface && it.ir.isCompanion }
|
||||||
val superInterfacesKeyword = if (isInterface) "extends" else "implements"
|
val superInterfacesKeyword = if (isInterface) "extends" else "implements"
|
||||||
|
|
||||||
val superClassClause = superClasses.toExtendsClause(indent)
|
val superClassClause = superClasses.toExtendsClause(indent)
|
||||||
val superInterfacesClause = superInterfaces.toImplementsClause(superInterfacesKeyword, indent)
|
val superInterfacesClause = superInterfaces.toImplementsClause(superInterfacesKeyword, indent)
|
||||||
|
|
||||||
val (memberObjects, nestedDeclarations) = nestedClasses.partition { it.couldBeProperty() }
|
val (memberObjects, nestedDeclarations) = allNestedClasses.partition { it.couldBeProperty() }
|
||||||
|
|
||||||
val members = members.map {
|
val members = members.map {
|
||||||
if (!ir.isInner || it !is ExportedFunction || !it.isStatic) {
|
if (!ir.isInner || it !is ExportedFunction || !it.isStatic) {
|
||||||
@@ -321,7 +319,7 @@ class ExportModelToTsDeclarations {
|
|||||||
|
|
||||||
val bodyString = privateCtorString + membersString + indent
|
val bodyString = privateCtorString + membersString + indent
|
||||||
|
|
||||||
val nestedClasses = nonInnerClasses + innerClasses.map { it.withProtectedConstructors() }
|
val realNestedClasses = nonInnerClasses + innerClasses.map { it.withProtectedConstructors() }
|
||||||
val tsIgnoreForPrivateConstructorInheritance = if (hasSuperClassWithPrivateConstructor()) {
|
val tsIgnoreForPrivateConstructorInheritance = if (hasSuperClassWithPrivateConstructor()) {
|
||||||
tsIgnore("extends class with private primary constructor") + "\n$indent"
|
tsIgnore("extends class with private primary constructor") + "\n$indent"
|
||||||
} else ""
|
} else ""
|
||||||
@@ -329,9 +327,17 @@ class ExportModelToTsDeclarations {
|
|||||||
val klassExport =
|
val klassExport =
|
||||||
"$prefix$modifiers$keyword $name$renderedTypeParameters$superClassClause$superInterfacesClause {\n$bodyString}"
|
"$prefix$modifiers$keyword $name$renderedTypeParameters$superClassClause$superInterfacesClause {\n$bodyString}"
|
||||||
val staticsExport =
|
val staticsExport =
|
||||||
if (nestedClasses.isNotEmpty()) "\n" + ExportedNamespace(name, nestedClasses).toTypeScript(indent, prefix) else ""
|
if (realNestedClasses.isNotEmpty()) "\n" + ExportedNamespace(name, realNestedClasses).toTypeScript(indent, prefix) else ""
|
||||||
|
|
||||||
return if (name.isValidES5Identifier()) tsIgnoreForPrivateConstructorInheritance + klassExport + staticsExport else ""
|
val interfaceCompanionsString = if (interfaceCompanions.isNotEmpty()) "\n" + interfaceCompanions.joinToString("\n") {
|
||||||
|
it.toTypeScript(
|
||||||
|
indent,
|
||||||
|
prefix,
|
||||||
|
esModules
|
||||||
|
)
|
||||||
|
} else ""
|
||||||
|
|
||||||
|
return if (name.isValidES5Identifier()) tsIgnoreForPrivateConstructorInheritance + klassExport + staticsExport + interfaceCompanionsString else ""
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ExportedRegularClass.hasSuperClassWithPrivateConstructor(): Boolean {
|
private fun ExportedRegularClass.hasSuperClassWithPrivateConstructor(): Boolean {
|
||||||
|
|||||||
+3
-3
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.types.isUnit
|
|||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind
|
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.metadata.constant
|
||||||
import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects
|
import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects
|
||||||
import org.jetbrains.kotlin.js.backend.ast.metadata.synthetic
|
import org.jetbrains.kotlin.js.backend.ast.metadata.synthetic
|
||||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||||
@@ -148,9 +149,8 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
|||||||
assert(obj.kind == ClassKind.OBJECT)
|
assert(obj.kind == ClassKind.OBJECT)
|
||||||
assert(obj.isEffectivelyExternal()) { "Non external IrGetObjectValue must be lowered" }
|
assert(obj.isEffectivelyExternal()) { "Non external IrGetObjectValue must be lowered" }
|
||||||
|
|
||||||
return when {
|
return context.getRefForExternalClass(obj).withSource(expression, context).apply {
|
||||||
obj.isCompanion && obj.parentAsClass.let { it.isInterface && it.isExternal } -> JsNullLiteral()
|
sideEffects = SideEffectKind.PURE
|
||||||
else -> context.getRefForExternalClass(obj).withSource(expression, context)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-1
@@ -25,7 +25,14 @@ external interface GoodInterface
|
|||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
interface InterfaceWithCompanion {
|
interface InterfaceWithCompanion {
|
||||||
companion <!WRONG_EXPORTED_DECLARATION("companion object inside exported interface")!>object<!> {
|
companion object {
|
||||||
|
fun foo() = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
interface InterfaceWithNamedCompanion {
|
||||||
|
companion <!NAMED_COMPANION_IN_EXPORTED_INTERFACE!>object Named<!> {
|
||||||
fun foo() = 42
|
fun foo() = 42
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -25,7 +25,14 @@ external interface GoodInterface
|
|||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
interface InterfaceWithCompanion {
|
interface InterfaceWithCompanion {
|
||||||
companion <!WRONG_EXPORTED_DECLARATION("companion object inside exported interface")!>object<!> {
|
companion object {
|
||||||
|
fun foo() = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
interface InterfaceWithNamedCompanion {
|
||||||
|
companion <!NAMED_COMPANION_IN_EXPORTED_INTERFACE!>object Named<!> {
|
||||||
fun foo() = 42
|
fun foo() = 42
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
@@ -64,6 +64,20 @@ package foo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@kotlin.js.JsExport public interface InterfaceWithNamedCompanion {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Named {
|
||||||
|
private constructor Named()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@kotlin.js.JsExport public interface OuterInterface {
|
@kotlin.js.JsExport public interface OuterInterface {
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
|||||||
+5
-1
@@ -9,5 +9,9 @@ external interface I {
|
|||||||
|
|
||||||
enum class <!ENUM_CLASS_IN_EXTERNAL_DECLARATION_WARNING, NESTED_CLASS_IN_EXTERNAL_INTERFACE!>E<!>
|
enum class <!ENUM_CLASS_IN_EXTERNAL_DECLARATION_WARNING, NESTED_CLASS_IN_EXTERNAL_INTERFACE!>E<!>
|
||||||
|
|
||||||
companion <!NESTED_CLASS_IN_EXTERNAL_INTERFACE!>object<!>
|
companion object
|
||||||
|
}
|
||||||
|
|
||||||
|
external interface I2 {
|
||||||
|
companion <!NAMED_COMPANION_IN_EXTERNAL_INTERFACE!>object Named<!>
|
||||||
}
|
}
|
||||||
+14
@@ -47,3 +47,17 @@ public external interface I {
|
|||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public external interface I2 {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Named {
|
||||||
|
private constructor Named()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ object JsPlatformConfigurator : PlatformConfiguratorBase(
|
|||||||
additionalDeclarationCheckers = listOf(
|
additionalDeclarationCheckers = listOf(
|
||||||
NativeInvokeChecker(), NativeGetterChecker(), NativeSetterChecker(),
|
NativeInvokeChecker(), NativeGetterChecker(), NativeSetterChecker(),
|
||||||
JsNameChecker, JsModuleChecker, JsExternalFileChecker,
|
JsNameChecker, JsModuleChecker, JsExternalFileChecker,
|
||||||
JsExternalChecker, JsInheritanceChecker, JsMultipleInheritanceChecker,
|
JsInheritanceChecker, JsMultipleInheritanceChecker,
|
||||||
JsExternalInheritorOnlyChecker,
|
JsExternalInheritorOnlyChecker,
|
||||||
JsRuntimeAnnotationChecker,
|
JsRuntimeAnnotationChecker,
|
||||||
JsDynamicDeclarationChecker,
|
JsDynamicDeclarationChecker,
|
||||||
@@ -51,7 +51,8 @@ object JsPlatformConfigurator : PlatformConfiguratorBase(
|
|||||||
container.useInstance(ExtensionFunctionToExternalIsInlinable)
|
container.useInstance(ExtensionFunctionToExternalIsInlinable)
|
||||||
container.useInstance(JsQualifierChecker)
|
container.useInstance(JsQualifierChecker)
|
||||||
container.useInstance(JsNativeDiagnosticSuppressor)
|
container.useInstance(JsNativeDiagnosticSuppressor)
|
||||||
container.useInstance(JsExportDeclarationChecker(includeUnsignedNumbers = false))
|
container.useInstance(JsExternalChecker(allowCompanionInInterface = true))
|
||||||
|
container.useInstance(JsExportDeclarationChecker(allowCompanionInInterface = true, includeUnsignedNumbers = false))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun configureModuleDependentCheckers(container: StorageComponentContainer) {
|
override fun configureModuleDependentCheckers(container: StorageComponentContainer) {
|
||||||
|
|||||||
+3
@@ -34,6 +34,9 @@ private val DIAGNOSTIC_FACTORY_TO_RENDERER by lazy {
|
|||||||
put(ErrorsJs.INLINE_CLASS_IN_EXTERNAL_DECLARATION_WARNING, "Using value classes as parameter type or return type of external declarations is experimental")
|
put(ErrorsJs.INLINE_CLASS_IN_EXTERNAL_DECLARATION_WARNING, "Using value classes as parameter type or return type of external declarations is experimental")
|
||||||
put(ErrorsJs.ENUM_CLASS_IN_EXTERNAL_DECLARATION_WARNING, "Using enum classes with an `external` qualifier becomes deprecated and will be an error in future releases")
|
put(ErrorsJs.ENUM_CLASS_IN_EXTERNAL_DECLARATION_WARNING, "Using enum classes with an `external` qualifier becomes deprecated and will be an error in future releases")
|
||||||
|
|
||||||
|
put(ErrorsJs.NAMED_COMPANION_IN_EXTERNAL_INTERFACE, "Named companions are not allowed inside external interfaces")
|
||||||
|
put(ErrorsJs.NAMED_COMPANION_IN_EXPORTED_INTERFACE, "Named companions are not allowed inside exported interfaces")
|
||||||
|
|
||||||
put(ErrorsJs.JS_NAME_CLASH, "JavaScript name ({0}) generated for this declaration clashes with another declaration: {1}",
|
put(ErrorsJs.JS_NAME_CLASH, "JavaScript name ({0}) generated for this declaration clashes with another declaration: {1}",
|
||||||
STRING, Renderers.COMPACT)
|
STRING, Renderers.COMPACT)
|
||||||
put(ErrorsJs.JS_FAKE_NAME_CLASH, "JavaScript name {0} is generated for different inherited members: {1} and {2}",
|
put(ErrorsJs.JS_FAKE_NAME_CLASH, "JavaScript name {0} is generated for different inherited members: {1} and {2}",
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ public interface ErrorsJs {
|
|||||||
DiagnosticFactory0<KtElement> INLINE_CLASS_IN_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
DiagnosticFactory0<KtElement> INLINE_CLASS_IN_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
DiagnosticFactory0<KtElement> ENUM_CLASS_IN_EXTERNAL_DECLARATION_WARNING = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE_OR_DEFAULT);
|
DiagnosticFactory0<KtElement> ENUM_CLASS_IN_EXTERNAL_DECLARATION_WARNING = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
DiagnosticFactory0<KtElement> INLINE_CLASS_IN_EXTERNAL_DECLARATION_WARNING = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE_OR_DEFAULT);
|
DiagnosticFactory0<KtElement> INLINE_CLASS_IN_EXTERNAL_DECLARATION_WARNING = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
DiagnosticFactory0<KtElement> NAMED_COMPANION_IN_EXTERNAL_INTERFACE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
DiagnosticFactory0<KtElement> NAMED_COMPANION_IN_EXPORTED_INTERFACE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
|
||||||
DiagnosticFactory2<KtElement, String, DeclarationDescriptor> JS_NAME_CLASH = DiagnosticFactory2.create(
|
DiagnosticFactory2<KtElement, String, DeclarationDescriptor> JS_NAME_CLASH = DiagnosticFactory2.create(
|
||||||
ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.js.resolve.diagnostics
|
package org.jetbrains.kotlin.js.resolve.diagnostics
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.js.resolve.diagnostics.JsExternalChecker.DEFINED_EXTERNALLY_PROPERTY_NAMES
|
import org.jetbrains.kotlin.js.resolve.diagnostics.JsExternalChecker.Companion.DEFINED_EXTERNALLY_PROPERTY_NAMES
|
||||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
||||||
|
|||||||
+10
-2
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.js.common.SPECIAL_KEYWORDS
|
|||||||
import org.jetbrains.kotlin.js.naming.NameSuggestion
|
import org.jetbrains.kotlin.js.naming.NameSuggestion
|
||||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
@@ -35,7 +36,10 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.types.isDynamic
|
import org.jetbrains.kotlin.types.isDynamic
|
||||||
import org.jetbrains.kotlin.types.typeUtil.*
|
import org.jetbrains.kotlin.types.typeUtil.*
|
||||||
|
|
||||||
class JsExportDeclarationChecker(private val includeUnsignedNumbers: Boolean) : DeclarationChecker {
|
class JsExportDeclarationChecker(
|
||||||
|
private val includeUnsignedNumbers: Boolean,
|
||||||
|
private val allowCompanionInInterface: Boolean
|
||||||
|
) : DeclarationChecker {
|
||||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
val trace = context.trace
|
val trace = context.trace
|
||||||
val bindingContext = trace.bindingContext
|
val bindingContext = trace.bindingContext
|
||||||
@@ -130,11 +134,15 @@ class JsExportDeclarationChecker(private val includeUnsignedNumbers: Boolean) :
|
|||||||
descriptor.isInlineClass() -> "${if (descriptor.isInline) "inline " else ""}${if (descriptor.isValue) "value " else ""}class"
|
descriptor.isInlineClass() -> "${if (descriptor.isInline) "inline " else ""}${if (descriptor.isValue) "value " else ""}class"
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
else -> if (descriptor.isInsideInterface) {
|
else -> if (descriptor.isInsideInterface && (!allowCompanionInInterface || !descriptor.isCompanionObject)) {
|
||||||
"${if (descriptor.isCompanionObject) "companion object" else "nested/inner declaration"} inside exported interface"
|
"${if (descriptor.isCompanionObject) "companion object" else "nested/inner declaration"} inside exported interface"
|
||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allowCompanionInInterface && descriptor.isCompanionObject && descriptor.isInsideInterface && descriptor.name != DEFAULT_NAME_FOR_COMPANION_OBJECT) {
|
||||||
|
trace.report(ErrorsJs.NAMED_COMPANION_IN_EXPORTED_INTERFACE.on(declaration))
|
||||||
|
}
|
||||||
|
|
||||||
if (wrongDeclaration != null) {
|
if (wrongDeclaration != null) {
|
||||||
reportWrongExportedDeclaration(wrongDeclaration)
|
reportWrongExportedDeclaration(wrongDeclaration)
|
||||||
return
|
return
|
||||||
|
|||||||
+13
-6
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.js.PredefinedAnnotation
|
|||||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.JsStandardClassIds
|
import org.jetbrains.kotlin.name.JsStandardClassIds
|
||||||
|
import org.jetbrains.kotlin.name.SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
|
||||||
import org.jetbrains.kotlin.platform.isWasm
|
import org.jetbrains.kotlin.platform.isWasm
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -28,9 +29,11 @@ import org.jetbrains.kotlin.resolve.source.getPsi
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
|
|
||||||
object JsExternalChecker : DeclarationChecker {
|
class JsExternalChecker(private val allowCompanionInInterface: Boolean) : DeclarationChecker {
|
||||||
val DEFINED_EXTERNALLY_PROPERTY_NAMES = JsStandardClassIds.Callables.definedExternallyPropertyNames
|
companion object {
|
||||||
.map { it.asSingleFqName().toUnsafe() }
|
val DEFINED_EXTERNALLY_PROPERTY_NAMES = JsStandardClassIds.Callables.definedExternallyPropertyNames
|
||||||
|
.map { it.asSingleFqName().toUnsafe() }
|
||||||
|
}
|
||||||
|
|
||||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
if (!AnnotationsUtils.isNativeObject(descriptor)) return
|
if (!AnnotationsUtils.isNativeObject(descriptor)) return
|
||||||
@@ -68,12 +71,16 @@ object JsExternalChecker : DeclarationChecker {
|
|||||||
trace.report(ErrorsJs.WRONG_EXTERNAL_DECLARATION.on(declaration, "private member of class"))
|
trace.report(ErrorsJs.WRONG_EXTERNAL_DECLARATION.on(declaration, "private member of class"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor is ClassDescriptor && descriptor.kind != ClassKind.INTERFACE &&
|
val containingDeclarationsIsInterface = descriptor.containingDeclaration.let { it is ClassDescriptor && it.kind == ClassKind.INTERFACE }
|
||||||
descriptor.containingDeclaration.let { it is ClassDescriptor && it.kind == ClassKind.INTERFACE }
|
|
||||||
) {
|
if (descriptor is ClassDescriptor && descriptor.kind != ClassKind.INTERFACE && (!allowCompanionInInterface || !descriptor.isCompanionObject) && containingDeclarationsIsInterface) {
|
||||||
trace.report(ErrorsJs.NESTED_CLASS_IN_EXTERNAL_INTERFACE.on(declaration))
|
trace.report(ErrorsJs.NESTED_CLASS_IN_EXTERNAL_INTERFACE.on(declaration))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allowCompanionInInterface && descriptor.isCompanionObject() && containingDeclarationsIsInterface && descriptor.name != DEFAULT_NAME_FOR_COMPANION_OBJECT) {
|
||||||
|
trace.report(ErrorsJs.NAMED_COMPANION_IN_EXTERNAL_INTERFACE.on(declaration))
|
||||||
|
}
|
||||||
|
|
||||||
if (descriptor !is PropertyAccessorDescriptor && descriptor.isExtension) {
|
if (descriptor !is PropertyAccessorDescriptor && descriptor.isExtension) {
|
||||||
val target = when (descriptor) {
|
val target = when (descriptor) {
|
||||||
is FunctionDescriptor -> "extension function"
|
is FunctionDescriptor -> "extension function"
|
||||||
|
|||||||
+8
-1
@@ -17,6 +17,9 @@
|
|||||||
package org.jetbrains.kotlin.js.inline.clean
|
package org.jetbrains.kotlin.js.inline.clean
|
||||||
|
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.metadata.constant
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects
|
||||||
import org.jetbrains.kotlin.js.backend.ast.metadata.synthetic
|
import org.jetbrains.kotlin.js.backend.ast.metadata.synthetic
|
||||||
import org.jetbrains.kotlin.js.inline.util.collectFreeVariables
|
import org.jetbrains.kotlin.js.inline.util.collectFreeVariables
|
||||||
|
|
||||||
@@ -55,7 +58,8 @@ internal class RedundantVariableDeclarationElimination(private val root: JsState
|
|||||||
object : JsVisitorWithContextImpl() {
|
object : JsVisitorWithContextImpl() {
|
||||||
override fun endVisit(x: JsVars, ctx: JsContext<*>) {
|
override fun endVisit(x: JsVars, ctx: JsContext<*>) {
|
||||||
if (x.synthetic) {
|
if (x.synthetic) {
|
||||||
if (x.vars.removeAll { it.initExpression == null && it.name !in usages }) {
|
if (
|
||||||
|
x.vars.removeAll { it.initExpression.isPure && it.name !in usages }) {
|
||||||
hasChanges = true
|
hasChanges = true
|
||||||
}
|
}
|
||||||
if (x.vars.isEmpty()) {
|
if (x.vars.isEmpty()) {
|
||||||
@@ -65,6 +69,9 @@ internal class RedundantVariableDeclarationElimination(private val root: JsState
|
|||||||
super.endVisit(x, ctx)
|
super.endVisit(x, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val JsExpression?.isPure: Boolean
|
||||||
|
get() = this == null || constant || sideEffects == SideEffectKind.PURE
|
||||||
|
|
||||||
override fun visit(x: JsFunction, ctx: JsContext<*>) = false
|
override fun visit(x: JsFunction, ctx: JsContext<*>) = false
|
||||||
}.accept(root)
|
}.accept(root)
|
||||||
}
|
}
|
||||||
|
|||||||
+30
@@ -2605,6 +2605,12 @@ public class FirJsES6BoxTestGenerated extends AbstractFirJsES6BoxTest {
|
|||||||
runTest("js/js.translator/testData/box/esModules/jsExport/exportedDefaultStub.kt");
|
runTest("js/js.translator/testData/box/esModules/jsExport/exportedDefaultStub.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfaceWithCompanion.kt")
|
||||||
|
public void testInterfaceWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/interfaceWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExportInClass.kt")
|
@TestMetadata("jsExportInClass.kt")
|
||||||
public void testJsExportInClass() {
|
public void testJsExportInClass() {
|
||||||
@@ -2699,6 +2705,12 @@ public class FirJsES6BoxTestGenerated extends AbstractFirJsES6BoxTest {
|
|||||||
runTest("js/js.translator/testData/box/esModules/jsModule/interfaces.kt");
|
runTest("js/js.translator/testData/box/esModules/jsModule/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExternalInheritorsOnly.kt")
|
@TestMetadata("jsExternalInheritorsOnly.kt")
|
||||||
public void testJsExternalInheritorsOnly() {
|
public void testJsExternalInheritorsOnly() {
|
||||||
@@ -7524,6 +7536,12 @@ public class FirJsES6BoxTestGenerated extends AbstractFirJsES6BoxTest {
|
|||||||
runTest("js/js.translator/testData/box/jsExport/exportedDefaultStub.kt");
|
runTest("js/js.translator/testData/box/jsExport/exportedDefaultStub.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfaceWithCompanion.kt")
|
||||||
|
public void testInterfaceWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsExport/interfaceWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExportInClass.kt")
|
@TestMetadata("jsExportInClass.kt")
|
||||||
public void testJsExportInClass() {
|
public void testJsExportInClass() {
|
||||||
@@ -7660,6 +7678,12 @@ public class FirJsES6BoxTestGenerated extends AbstractFirJsES6BoxTest {
|
|||||||
runTest("js/js.translator/testData/box/jsModule/interfaces.kt");
|
runTest("js/js.translator/testData/box/jsModule/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsModule/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt39378.kt")
|
@TestMetadata("kt39378.kt")
|
||||||
public void testKt39378() {
|
public void testKt39378() {
|
||||||
@@ -7836,6 +7860,12 @@ public class FirJsES6BoxTestGenerated extends AbstractFirJsES6BoxTest {
|
|||||||
runTest("js/js.translator/testData/box/jsQualifier/interfaces.kt");
|
runTest("js/js.translator/testData/box/jsQualifier/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsQualifier/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() {
|
public void testSimple() {
|
||||||
|
|||||||
Generated
+30
@@ -2499,6 +2499,12 @@ public class FirLightTreeJsBoxTestGenerated extends AbstractFirLightTreeJsBoxTes
|
|||||||
runTest("js/js.translator/testData/box/esModules/jsExport/exportedDefaultStub.kt");
|
runTest("js/js.translator/testData/box/esModules/jsExport/exportedDefaultStub.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfaceWithCompanion.kt")
|
||||||
|
public void testInterfaceWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/interfaceWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExportInClass.kt")
|
@TestMetadata("jsExportInClass.kt")
|
||||||
public void testJsExportInClass() {
|
public void testJsExportInClass() {
|
||||||
@@ -2593,6 +2599,12 @@ public class FirLightTreeJsBoxTestGenerated extends AbstractFirLightTreeJsBoxTes
|
|||||||
runTest("js/js.translator/testData/box/esModules/jsModule/interfaces.kt");
|
runTest("js/js.translator/testData/box/esModules/jsModule/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExternalInheritorsOnly.kt")
|
@TestMetadata("jsExternalInheritorsOnly.kt")
|
||||||
public void testJsExternalInheritorsOnly() {
|
public void testJsExternalInheritorsOnly() {
|
||||||
@@ -7418,6 +7430,12 @@ public class FirLightTreeJsBoxTestGenerated extends AbstractFirLightTreeJsBoxTes
|
|||||||
runTest("js/js.translator/testData/box/jsExport/exportedDefaultStub.kt");
|
runTest("js/js.translator/testData/box/jsExport/exportedDefaultStub.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfaceWithCompanion.kt")
|
||||||
|
public void testInterfaceWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsExport/interfaceWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExportInClass.kt")
|
@TestMetadata("jsExportInClass.kt")
|
||||||
public void testJsExportInClass() {
|
public void testJsExportInClass() {
|
||||||
@@ -7554,6 +7572,12 @@ public class FirLightTreeJsBoxTestGenerated extends AbstractFirLightTreeJsBoxTes
|
|||||||
runTest("js/js.translator/testData/box/jsModule/interfaces.kt");
|
runTest("js/js.translator/testData/box/jsModule/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsModule/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt39378.kt")
|
@TestMetadata("kt39378.kt")
|
||||||
public void testKt39378() {
|
public void testKt39378() {
|
||||||
@@ -7730,6 +7754,12 @@ public class FirLightTreeJsBoxTestGenerated extends AbstractFirLightTreeJsBoxTes
|
|||||||
runTest("js/js.translator/testData/box/jsQualifier/interfaces.kt");
|
runTest("js/js.translator/testData/box/jsQualifier/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsQualifier/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() {
|
public void testSimple() {
|
||||||
|
|||||||
+30
@@ -2499,6 +2499,12 @@ public class FirPsiJsBoxTestGenerated extends AbstractFirPsiJsBoxTest {
|
|||||||
runTest("js/js.translator/testData/box/esModules/jsExport/exportedDefaultStub.kt");
|
runTest("js/js.translator/testData/box/esModules/jsExport/exportedDefaultStub.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfaceWithCompanion.kt")
|
||||||
|
public void testInterfaceWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/interfaceWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExportInClass.kt")
|
@TestMetadata("jsExportInClass.kt")
|
||||||
public void testJsExportInClass() {
|
public void testJsExportInClass() {
|
||||||
@@ -2593,6 +2599,12 @@ public class FirPsiJsBoxTestGenerated extends AbstractFirPsiJsBoxTest {
|
|||||||
runTest("js/js.translator/testData/box/esModules/jsModule/interfaces.kt");
|
runTest("js/js.translator/testData/box/esModules/jsModule/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExternalInheritorsOnly.kt")
|
@TestMetadata("jsExternalInheritorsOnly.kt")
|
||||||
public void testJsExternalInheritorsOnly() {
|
public void testJsExternalInheritorsOnly() {
|
||||||
@@ -7418,6 +7430,12 @@ public class FirPsiJsBoxTestGenerated extends AbstractFirPsiJsBoxTest {
|
|||||||
runTest("js/js.translator/testData/box/jsExport/exportedDefaultStub.kt");
|
runTest("js/js.translator/testData/box/jsExport/exportedDefaultStub.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfaceWithCompanion.kt")
|
||||||
|
public void testInterfaceWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsExport/interfaceWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExportInClass.kt")
|
@TestMetadata("jsExportInClass.kt")
|
||||||
public void testJsExportInClass() {
|
public void testJsExportInClass() {
|
||||||
@@ -7554,6 +7572,12 @@ public class FirPsiJsBoxTestGenerated extends AbstractFirPsiJsBoxTest {
|
|||||||
runTest("js/js.translator/testData/box/jsModule/interfaces.kt");
|
runTest("js/js.translator/testData/box/jsModule/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsModule/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt39378.kt")
|
@TestMetadata("kt39378.kt")
|
||||||
public void testKt39378() {
|
public void testKt39378() {
|
||||||
@@ -7730,6 +7754,12 @@ public class FirPsiJsBoxTestGenerated extends AbstractFirPsiJsBoxTest {
|
|||||||
runTest("js/js.translator/testData/box/jsQualifier/interfaces.kt");
|
runTest("js/js.translator/testData/box/jsQualifier/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsQualifier/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() {
|
public void testSimple() {
|
||||||
|
|||||||
+30
@@ -2605,6 +2605,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
|
|||||||
runTest("js/js.translator/testData/box/esModules/jsExport/exportedDefaultStub.kt");
|
runTest("js/js.translator/testData/box/esModules/jsExport/exportedDefaultStub.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfaceWithCompanion.kt")
|
||||||
|
public void testInterfaceWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/interfaceWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExportInClass.kt")
|
@TestMetadata("jsExportInClass.kt")
|
||||||
public void testJsExportInClass() {
|
public void testJsExportInClass() {
|
||||||
@@ -2699,6 +2705,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
|
|||||||
runTest("js/js.translator/testData/box/esModules/jsModule/interfaces.kt");
|
runTest("js/js.translator/testData/box/esModules/jsModule/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExternalInheritorsOnly.kt")
|
@TestMetadata("jsExternalInheritorsOnly.kt")
|
||||||
public void testJsExternalInheritorsOnly() {
|
public void testJsExternalInheritorsOnly() {
|
||||||
@@ -7524,6 +7536,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
|
|||||||
runTest("js/js.translator/testData/box/jsExport/exportedDefaultStub.kt");
|
runTest("js/js.translator/testData/box/jsExport/exportedDefaultStub.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfaceWithCompanion.kt")
|
||||||
|
public void testInterfaceWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsExport/interfaceWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExportInClass.kt")
|
@TestMetadata("jsExportInClass.kt")
|
||||||
public void testJsExportInClass() {
|
public void testJsExportInClass() {
|
||||||
@@ -7660,6 +7678,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
|
|||||||
runTest("js/js.translator/testData/box/jsModule/interfaces.kt");
|
runTest("js/js.translator/testData/box/jsModule/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsModule/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt39378.kt")
|
@TestMetadata("kt39378.kt")
|
||||||
public void testKt39378() {
|
public void testKt39378() {
|
||||||
@@ -7836,6 +7860,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
|
|||||||
runTest("js/js.translator/testData/box/jsQualifier/interfaces.kt");
|
runTest("js/js.translator/testData/box/jsQualifier/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsQualifier/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() {
|
public void testSimple() {
|
||||||
|
|||||||
+30
@@ -2499,6 +2499,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/esModules/jsExport/exportedDefaultStub.kt");
|
runTest("js/js.translator/testData/box/esModules/jsExport/exportedDefaultStub.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfaceWithCompanion.kt")
|
||||||
|
public void testInterfaceWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsExport/interfaceWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExportInClass.kt")
|
@TestMetadata("jsExportInClass.kt")
|
||||||
public void testJsExportInClass() {
|
public void testJsExportInClass() {
|
||||||
@@ -2593,6 +2599,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/esModules/jsModule/interfaces.kt");
|
runTest("js/js.translator/testData/box/esModules/jsModule/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/esModules/jsModule/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExternalInheritorsOnly.kt")
|
@TestMetadata("jsExternalInheritorsOnly.kt")
|
||||||
public void testJsExternalInheritorsOnly() {
|
public void testJsExternalInheritorsOnly() {
|
||||||
@@ -7418,6 +7430,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/jsExport/exportedDefaultStub.kt");
|
runTest("js/js.translator/testData/box/jsExport/exportedDefaultStub.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfaceWithCompanion.kt")
|
||||||
|
public void testInterfaceWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsExport/interfaceWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("jsExportInClass.kt")
|
@TestMetadata("jsExportInClass.kt")
|
||||||
public void testJsExportInClass() {
|
public void testJsExportInClass() {
|
||||||
@@ -7554,6 +7572,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/jsModule/interfaces.kt");
|
runTest("js/js.translator/testData/box/jsModule/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsModule/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt39378.kt")
|
@TestMetadata("kt39378.kt")
|
||||||
public void testKt39378() {
|
public void testKt39378() {
|
||||||
@@ -7730,6 +7754,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/jsQualifier/interfaces.kt");
|
runTest("js/js.translator/testData/box/jsQualifier/interfaces.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("interfacesWithCompanion.kt")
|
||||||
|
public void testInterfacesWithCompanion() {
|
||||||
|
runTest("js/js.translator/testData/box/jsQualifier/interfacesWithCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() {
|
public void testSimple() {
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// SKIP_MINIFICATION
|
||||||
|
// ES_MODULES
|
||||||
|
|
||||||
|
// FILE: api.kt
|
||||||
|
package api
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
interface A {
|
||||||
|
companion object {
|
||||||
|
fun ok() = "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
external interface JsResult {
|
||||||
|
val res: String
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsModule("./interfaceWithCompanion.mjs")
|
||||||
|
external fun jsBox(): JsResult
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return jsBox().res
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import * as api from "./interfaceWithCompanion_v5.mjs";
|
||||||
|
|
||||||
|
export default function() {
|
||||||
|
return {
|
||||||
|
"res": api.A.getInstance().ok()
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// TARGET_BACKEND: JS_IR
|
||||||
|
// TARGET_BACKEND: JS_IR_ES6
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1238
|
||||||
|
// ES_MODULES
|
||||||
|
// FILE: bar.kt
|
||||||
|
@file:JsModule("./interfacesWithCompanion.mjs")
|
||||||
|
package bar
|
||||||
|
|
||||||
|
external interface Bar {
|
||||||
|
companion object {
|
||||||
|
fun ok(): String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
import bar.Bar
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return Bar.ok()
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export const Bar = {
|
||||||
|
ok() { return "OK" }
|
||||||
|
};
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
$kotlin_test_internal$.beginModule();
|
||||||
|
|
||||||
|
module.exports = function() {
|
||||||
|
var { A } = require("main").api
|
||||||
|
|
||||||
|
return {
|
||||||
|
"res": A.ok()
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$kotlin_test_internal$.endModule("lib");
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// MODULE_KIND: COMMON_JS
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
|
||||||
|
// FILE: api.kt
|
||||||
|
package api
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
interface A {
|
||||||
|
companion object {
|
||||||
|
fun ok() = "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
external interface JsResult {
|
||||||
|
val res: String
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsModule("lib")
|
||||||
|
external fun jsBox(): JsResult
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return jsBox().res
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
define("bar", [], function() {
|
||||||
|
return {
|
||||||
|
Bar: {
|
||||||
|
ok() { return "OK" }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// TARGET_BACKEND: JS_IR
|
||||||
|
// TARGET_BACKEND: JS_IR_ES6
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1238
|
||||||
|
// MODULE_KIND: AMD
|
||||||
|
// FILE: bar.kt
|
||||||
|
@file:JsModule("bar")
|
||||||
|
package bar
|
||||||
|
|
||||||
|
external interface Bar {
|
||||||
|
companion object {
|
||||||
|
fun ok(): String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
import bar.Bar
|
||||||
|
|
||||||
|
inline fun Bar.Companion.test() = "CHECK"
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
Bar.test()
|
||||||
|
return Bar.ok()
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// TARGET_BACKEND: JS_IR
|
||||||
|
// TARGET_BACKEND: JS_IR_ES6
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1238
|
||||||
|
// FILE: bar.kt
|
||||||
|
@file:JsQualifier("bar")
|
||||||
|
package bar
|
||||||
|
|
||||||
|
external interface Bar {
|
||||||
|
companion object {
|
||||||
|
fun ok(): String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
import bar.Bar
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return Bar.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test.js
|
||||||
|
var bar = function() {
|
||||||
|
var Bar = {
|
||||||
|
ok() {
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
Bar: Bar
|
||||||
|
}
|
||||||
|
}();
|
||||||
+9
@@ -30,6 +30,15 @@ declare namespace JS_TESTS {
|
|||||||
readonly __doNotUseOrImplementIt: foo.TestInterfaceImpl["__doNotUseOrImplementIt"] & foo.AnotherExportedInterface["__doNotUseOrImplementIt"];
|
readonly __doNotUseOrImplementIt: foo.TestInterfaceImpl["__doNotUseOrImplementIt"] & foo.AnotherExportedInterface["__doNotUseOrImplementIt"];
|
||||||
}
|
}
|
||||||
function processInterface(test: foo.TestInterface): string;
|
function processInterface(test: foo.TestInterface): string;
|
||||||
|
interface WithTheCompanion {
|
||||||
|
readonly interfaceField: string;
|
||||||
|
readonly __doNotUseOrImplementIt: {
|
||||||
|
readonly "foo.WithTheCompanion": unique symbol;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const WithTheCompanion: {
|
||||||
|
companionFunction(): string;
|
||||||
|
};
|
||||||
function processOptionalInterface(a: foo.OptionalFieldsInterface): string;
|
function processOptionalInterface(a: foo.OptionalFieldsInterface): string;
|
||||||
interface InterfaceWithCompanion {
|
interface InterfaceWithCompanion {
|
||||||
readonly __doNotUseOrImplementIt: {
|
readonly __doNotUseOrImplementIt: {
|
||||||
|
|||||||
+10
@@ -43,6 +43,15 @@ external interface OptionalFieldsInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface WithTheCompanion {
|
||||||
|
val interfaceField: String
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun companionFunction(): String = "FUNCTION"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun processOptionalInterface(a: OptionalFieldsInterface): String {
|
fun processOptionalInterface(a: OptionalFieldsInterface): String {
|
||||||
return "${a.required}${a.notRequired ?: "unknown"}"
|
return "${a.required}${a.notRequired ?: "unknown"}"
|
||||||
}
|
}
|
||||||
@@ -52,6 +61,7 @@ fun processOptionalInterface(a: OptionalFieldsInterface): String {
|
|||||||
interface InterfaceWithCompanion {
|
interface InterfaceWithCompanion {
|
||||||
// Emulate added by plugin companion like kotlinx.serialization does
|
// Emulate added by plugin companion like kotlinx.serialization does
|
||||||
@Suppress("WRONG_EXPORTED_DECLARATION")
|
@Suppress("WRONG_EXPORTED_DECLARATION")
|
||||||
|
@JsExport.Ignore
|
||||||
companion object {
|
companion object {
|
||||||
fun foo() = "String"
|
fun foo() = "String"
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+3
@@ -2,6 +2,7 @@ import TestInterfaceImpl = JS_TESTS.foo.TestInterfaceImpl;
|
|||||||
import ChildTestInterfaceImpl = JS_TESTS.foo.ChildTestInterfaceImpl;
|
import ChildTestInterfaceImpl = JS_TESTS.foo.ChildTestInterfaceImpl;
|
||||||
import processInterface = JS_TESTS.foo.processInterface;
|
import processInterface = JS_TESTS.foo.processInterface;
|
||||||
import processOptionalInterface = JS_TESTS.foo.processOptionalInterface;
|
import processOptionalInterface = JS_TESTS.foo.processOptionalInterface;
|
||||||
|
import WithTheCompanion = JS_TESTS.foo.WithTheCompanion;
|
||||||
|
|
||||||
function assert(condition: boolean) {
|
function assert(condition: boolean) {
|
||||||
if (!condition) {
|
if (!condition) {
|
||||||
@@ -20,5 +21,7 @@ function box(): string {
|
|||||||
assert(processOptionalInterface({ required: 4, notRequired: null }) == "4unknown")
|
assert(processOptionalInterface({ required: 4, notRequired: null }) == "4unknown")
|
||||||
assert(processOptionalInterface({ required: 4, notRequired: 5 }) == "45")
|
assert(processOptionalInterface({ required: 4, notRequired: 5 }) == "45")
|
||||||
|
|
||||||
|
assert(WithTheCompanion.companionFunction() == "FUNCTION")
|
||||||
|
|
||||||
return "OK";
|
return "OK";
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,15 @@ declare namespace JS_TESTS {
|
|||||||
readonly __doNotUseOrImplementIt: foo.TestInterfaceImpl["__doNotUseOrImplementIt"] & foo.AnotherExportedInterface["__doNotUseOrImplementIt"];
|
readonly __doNotUseOrImplementIt: foo.TestInterfaceImpl["__doNotUseOrImplementIt"] & foo.AnotherExportedInterface["__doNotUseOrImplementIt"];
|
||||||
}
|
}
|
||||||
function processInterface(test: foo.TestInterface): string;
|
function processInterface(test: foo.TestInterface): string;
|
||||||
|
interface WithTheCompanion {
|
||||||
|
readonly interfaceField: string;
|
||||||
|
readonly __doNotUseOrImplementIt: {
|
||||||
|
readonly "foo.WithTheCompanion": unique symbol;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const WithTheCompanion: {
|
||||||
|
companionFunction(): string;
|
||||||
|
};
|
||||||
function processOptionalInterface(a: foo.OptionalFieldsInterface): string;
|
function processOptionalInterface(a: foo.OptionalFieldsInterface): string;
|
||||||
interface InterfaceWithCompanion {
|
interface InterfaceWithCompanion {
|
||||||
readonly __doNotUseOrImplementIt: {
|
readonly __doNotUseOrImplementIt: {
|
||||||
|
|||||||
@@ -38,6 +38,15 @@ external interface OptionalFieldsInterface {
|
|||||||
val notRequired: Int?
|
val notRequired: Int?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
interface WithTheCompanion {
|
||||||
|
val interfaceField: String
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun companionFunction(): String = "FUNCTION"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
fun processOptionalInterface(a: OptionalFieldsInterface): String {
|
fun processOptionalInterface(a: OptionalFieldsInterface): String {
|
||||||
return "${a.required}${a.notRequired ?: "unknown"}"
|
return "${a.required}${a.notRequired ?: "unknown"}"
|
||||||
@@ -48,6 +57,7 @@ fun processOptionalInterface(a: OptionalFieldsInterface): String {
|
|||||||
interface InterfaceWithCompanion {
|
interface InterfaceWithCompanion {
|
||||||
// Emulate added by plugin companion like kotlinx.serialization does
|
// Emulate added by plugin companion like kotlinx.serialization does
|
||||||
@Suppress("WRONG_EXPORTED_DECLARATION")
|
@Suppress("WRONG_EXPORTED_DECLARATION")
|
||||||
|
@JsExport.Ignore
|
||||||
companion object {
|
companion object {
|
||||||
fun foo() = "String"
|
fun foo() = "String"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import TestInterfaceImpl = JS_TESTS.foo.TestInterfaceImpl;
|
|||||||
import ChildTestInterfaceImpl = JS_TESTS.foo.ChildTestInterfaceImpl;
|
import ChildTestInterfaceImpl = JS_TESTS.foo.ChildTestInterfaceImpl;
|
||||||
import processInterface = JS_TESTS.foo.processInterface;
|
import processInterface = JS_TESTS.foo.processInterface;
|
||||||
import processOptionalInterface = JS_TESTS.foo.processOptionalInterface;
|
import processOptionalInterface = JS_TESTS.foo.processOptionalInterface;
|
||||||
|
import WithTheCompanion = JS_TESTS.foo.WithTheCompanion;
|
||||||
|
|
||||||
function assert(condition: boolean) {
|
function assert(condition: boolean) {
|
||||||
if (!condition) {
|
if (!condition) {
|
||||||
@@ -20,5 +21,7 @@ function box(): string {
|
|||||||
assert(processOptionalInterface({ required: 4, notRequired: null }) == "4unknown")
|
assert(processOptionalInterface({ required: 4, notRequired: null }) == "4unknown")
|
||||||
assert(processOptionalInterface({ required: 4, notRequired: 5 }) == "45")
|
assert(processOptionalInterface({ required: 4, notRequired: 5 }) == "45")
|
||||||
|
|
||||||
|
assert(WithTheCompanion.companionFunction() == "FUNCTION")
|
||||||
|
|
||||||
return "OK";
|
return "OK";
|
||||||
}
|
}
|
||||||
+3
-2
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.wasm.resolve.diagnostics.*
|
|||||||
object WasmJsPlatformConfigurator : PlatformConfiguratorBase(
|
object WasmJsPlatformConfigurator : PlatformConfiguratorBase(
|
||||||
additionalDeclarationCheckers = listOf(
|
additionalDeclarationCheckers = listOf(
|
||||||
JsNameChecker, JsModuleChecker, JsExternalFileChecker,
|
JsNameChecker, JsModuleChecker, JsExternalFileChecker,
|
||||||
JsExternalChecker, WasmExternalInheritanceChecker,
|
WasmExternalInheritanceChecker,
|
||||||
JsRuntimeAnnotationChecker,
|
JsRuntimeAnnotationChecker,
|
||||||
JsExportAnnotationChecker,
|
JsExportAnnotationChecker,
|
||||||
WasmExternalDeclarationChecker,
|
WasmExternalDeclarationChecker,
|
||||||
@@ -50,7 +50,8 @@ object WasmJsPlatformConfigurator : PlatformConfiguratorBase(
|
|||||||
container.useInstance(ExtensionFunctionToExternalIsInlinable)
|
container.useInstance(ExtensionFunctionToExternalIsInlinable)
|
||||||
container.useInstance(JsQualifierChecker)
|
container.useInstance(JsQualifierChecker)
|
||||||
container.useInstance(WasmDiagnosticSuppressor)
|
container.useInstance(WasmDiagnosticSuppressor)
|
||||||
container.useInstance(JsExportDeclarationChecker(includeUnsignedNumbers = true))
|
container.useInstance(JsExternalChecker(allowCompanionInInterface = false))
|
||||||
|
container.useInstance(JsExportDeclarationChecker(allowCompanionInInterface = false, includeUnsignedNumbers = true))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun configureModuleDependentCheckers(container: StorageComponentContainer) {
|
override fun configureModuleDependentCheckers(container: StorageComponentContainer) {
|
||||||
|
|||||||
Reference in New Issue
Block a user