[JS IR] Control an inheritance of non-external entity from external

Add a special annotation @JsExternalInheritorsOnly for marking
 external interfaces and classes. The marked interface or class
 can’t be a parent for non external interfaces, classes or objects.

^KT-57423 Fixed
This commit is contained in:
Alexander Korepanov
2023-03-21 11:45:04 +01:00
committed by Space Team
parent 6e7b078873
commit 4813b659ab
26 changed files with 677 additions and 1 deletions
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticList
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.PositioningStrategy
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.psi.*
@@ -94,6 +95,10 @@ object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") {
parameter<ConeKotlinType>("targetType")
}
val EXTERNAL_INTERFACE_AS_CLASS_LITERAL by error<KtElement>()
val JS_EXTERNAL_INHERITORS_ONLY by error<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
parameter<FirClassLikeSymbol<*>>("parent")
parameter<FirClassLikeSymbol<*>>("kid")
}
}
val EXPORT by object : DiagnosticGroup("Export") {
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies
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.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.psi.KtAnonymousInitializer
@@ -78,6 +79,7 @@ object FirJsErrors {
val CANNOT_CHECK_FOR_EXTERNAL_INTERFACE by error1<KtElement, ConeKotlinType>()
val UNCHECKED_CAST_TO_EXTERNAL_INTERFACE by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
val EXTERNAL_INTERFACE_AS_CLASS_LITERAL by error0<KtElement>()
val JS_EXTERNAL_INHERITORS_ONLY by error2<KtDeclaration, FirClassLikeSymbol<*>, FirClassLikeSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
// Export
val NESTED_JS_EXPORT by error0<KtElement>()
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.IMPLEMENTING
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.ENUM_CLASS_IN_EXTERNAL_DECLARATION_WARNING
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_EXTERNAL_INHERITORS_ONLY
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
@@ -153,6 +154,12 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
"Can''t put non-external declarations in file marked with {0} annotation",
FirDiagnosticRenderers.RENDER_TYPE
)
map.put(
JS_EXTERNAL_INHERITORS_ONLY,
"External {0} can''t be a parent of non-external {1}",
FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT_NAME,
FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT_NAME
)
map.put(JS_NAME_PROHIBITED_FOR_EXTENSION_PROPERTY, "@JsName is prohibited for extension properties")
map.put(JS_NAME_IS_NOT_ON_ALL_ACCESSORS, "@JsName should be on all the property accessors")
map.put(JS_NAME_PROHIBITED_FOR_NAMED_NATIVE, "@JsName is prohibited for external declaration with explicit name")
@@ -36,6 +36,7 @@ object JsDeclarationCheckers : DeclarationCheckers() {
FirJsMultipleInheritanceChecker,
FirJsDynamicDeclarationChecker,
FirJsInheritanceClassChecker,
FirJsExternalInheritorOnlyChecker
)
override val simpleFunctionCheckers: Set<FirSimpleFunctionChecker>
@@ -0,0 +1,53 @@
/*
* 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.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirClassChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
import org.jetbrains.kotlin.fir.analysis.js.checkers.isEffectivelyExternal
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.hasAnnotation
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.name.JsStandardClassIds.Annotations.JsExternalInheritorsOnly
import org.jetbrains.kotlin.utils.addToStdlib.popLast
object FirJsExternalInheritorOnlyChecker : FirClassChecker() {
private fun FirClass.forEachParents(context: CheckerContext, f: (FirRegularClassSymbol) -> Unit) {
val todo = superConeTypes.toMutableList()
val done = hashSetOf<FirRegularClassSymbol>()
while (todo.isNotEmpty()) {
val classSymbol = todo.popLast().toRegularClassSymbol(context.session) ?: continue
if (done.add(classSymbol)) {
f(classSymbol)
classSymbol.resolvedSuperTypeRefs.mapNotNullTo(todo) { it.type as? ConeClassLikeType }
}
}
}
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
if (!declaration.symbol.isEffectivelyExternal(context)) {
declaration.forEachParents(context) { parent ->
if (parent.hasAnnotation(JsExternalInheritorsOnly, context.session)) {
reporter.reportOn(
declaration.source,
FirJsErrors.JS_EXTERNAL_INHERITORS_ONLY,
parent,
declaration.symbol,
context
)
}
}
}
}
}
@@ -0,0 +1,135 @@
// FIR_IDENTICAL
@OptIn(ExperimentalStdlibApi::class)
@JsExternalInheritorsOnly
external interface ExternalInterfaceX {
val x: String
}
@OptIn(ExperimentalStdlibApi::class)
@JsExternalInheritorsOnly
external open class ExternalOpenClassX {
val x: String
}
// check interfaces
external interface ExternalInterfaceXY : ExternalInterfaceX {
val y: String
}
interface <!JS_EXTERNAL_INHERITORS_ONLY!>InterfaceXY<!> : ExternalInterfaceX {
val y: String
}
interface <!JS_EXTERNAL_INHERITORS_ONLY!>InterfaceXYZ<!> : ExternalInterfaceXY {
val z: String
}
// check objects
external object ExternalObjectXY : ExternalInterfaceX {
override val x: String
val y: String
}
external object ExternalObjectXYZ : ExternalInterfaceXY {
override val x: String
override val y: String
val z: String
}
external object ExternalObjectXZ : ExternalOpenClassX {
val z: String
}
<!JS_EXTERNAL_INHERITORS_ONLY!>object ObjectXY<!> : ExternalInterfaceX {
override val x: String = "X"
val y: String = "Y"
}
<!JS_EXTERNAL_INHERITORS_ONLY!>object ObjectXYZ<!> : ExternalInterfaceXY {
override val x: String = "X"
override val y: String = "Y"
val z: String = "Z"
}
<!JS_EXTERNAL_INHERITORS_ONLY!>object ObjectXZ<!> : ExternalOpenClassX() {
val z: String = "Z"
}
// check classes
external class ExternalClassXY : ExternalInterfaceX {
override val x: String
val y: String
}
external class ExternalClassXYZ : ExternalInterfaceXY {
override val x: String
override val y: String
val z: String
}
external open class ExternalOpenClassXZ : ExternalOpenClassX {
val z: String
}
class <!JS_EXTERNAL_INHERITORS_ONLY!>ClassXY<!> : ExternalInterfaceX {
override val x: String = "X"
val y: String = "Y"
}
class <!JS_EXTERNAL_INHERITORS_ONLY!>ClassXYZ<!> : ExternalInterfaceXY {
override val x: String = "X"
override val y: String = "Y"
val z: String = "Z"
}
class <!JS_EXTERNAL_INHERITORS_ONLY!>ClassXZ<!> : ExternalOpenClassX() {
val z: String = "Z"
}
class <!JS_EXTERNAL_INHERITORS_ONLY!>ClassXZY<!> : ExternalOpenClassXZ() {
val y: String = "Y"
}
// check nested
external class ExternalClassNameSpace {
@OptIn(ExperimentalStdlibApi::class)
@JsExternalInheritorsOnly
interface NestedInterfaceX {
val x: String
}
interface NestedInterfaceXY : NestedInterfaceX {
val y: String
}
}
external interface ExternalInterfaceXY2 : ExternalClassNameSpace.NestedInterfaceX {
val y: String
}
external interface ExternalInterfaceXYZ2 : ExternalClassNameSpace.NestedInterfaceXY {
val z: String
}
interface <!JS_EXTERNAL_INHERITORS_ONLY!>InterfaceXY2<!> : ExternalClassNameSpace.NestedInterfaceX {
val y: String
}
interface <!JS_EXTERNAL_INHERITORS_ONLY!>InterfaceXYZ2<!> : ExternalClassNameSpace.NestedInterfaceXY {
val z: String
}
// multiple inheritance
external class ExternalClassXY2 : ExternalInterfaceX, ExternalOpenClassX {
val y: String
}
class <!JS_EXTERNAL_INHERITORS_ONLY, JS_EXTERNAL_INHERITORS_ONLY!>ClassXY2<!> : ExternalInterfaceX, ExternalOpenClassX() {
val y: String = "Y"
}
@@ -0,0 +1,238 @@
package
public final class ClassXY : ExternalInterfaceX {
public constructor ClassXY()
public open override /*1*/ val x: kotlin.String = "X"
public final val y: kotlin.String = "Y"
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 final class ClassXY2 : ExternalInterfaceX, ExternalOpenClassX {
public constructor ClassXY2()
public final override /*2*/ /*fake_override*/ val x: kotlin.String
public final val y: kotlin.String = "Y"
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class ClassXYZ : ExternalInterfaceXY {
public constructor ClassXYZ()
public open override /*1*/ val x: kotlin.String = "X"
public open override /*1*/ val y: kotlin.String = "Y"
public final val z: kotlin.String = "Z"
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 final class ClassXZ : ExternalOpenClassX {
public constructor ClassXZ()
public final override /*1*/ /*fake_override*/ val x: kotlin.String
public final val z: kotlin.String = "Z"
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 final class ClassXZY : ExternalOpenClassXZ {
public constructor ClassXZY()
public final override /*1*/ /*fake_override*/ val x: kotlin.String
public final val y: kotlin.String = "Y"
public final override /*1*/ /*fake_override*/ val z: kotlin.String
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 final external class ExternalClassNameSpace {
public constructor ExternalClassNameSpace()
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
@kotlin.OptIn(markerClass = {kotlin.ExperimentalStdlibApi::class}) @kotlin.js.JsExternalInheritorsOnly public interface NestedInterfaceX {
public abstract val x: kotlin.String
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 interface NestedInterfaceXY : ExternalClassNameSpace.NestedInterfaceX {
public abstract override /*1*/ /*fake_override*/ val x: kotlin.String
public abstract val y: kotlin.String
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 final external class ExternalClassXY : ExternalInterfaceX {
public constructor ExternalClassXY()
public open override /*1*/ val x: kotlin.String
public final val y: kotlin.String
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 final external class ExternalClassXY2 : ExternalInterfaceX, ExternalOpenClassX {
public constructor ExternalClassXY2()
public final override /*2*/ /*fake_override*/ val x: kotlin.String
public final val y: kotlin.String
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public final external class ExternalClassXYZ : ExternalInterfaceXY {
public constructor ExternalClassXYZ()
public open override /*1*/ val x: kotlin.String
public open override /*1*/ val y: kotlin.String
public final val z: kotlin.String
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
}
@kotlin.OptIn(markerClass = {kotlin.ExperimentalStdlibApi::class}) @kotlin.js.JsExternalInheritorsOnly public external interface ExternalInterfaceX {
public abstract val x: kotlin.String
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 external interface ExternalInterfaceXY : ExternalInterfaceX {
public abstract override /*1*/ /*fake_override*/ val x: kotlin.String
public abstract val y: kotlin.String
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 external interface ExternalInterfaceXY2 : ExternalClassNameSpace.NestedInterfaceX {
public abstract override /*1*/ /*fake_override*/ val x: kotlin.String
public abstract val y: kotlin.String
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 external interface ExternalInterfaceXYZ2 : ExternalClassNameSpace.NestedInterfaceXY {
public abstract override /*1*/ /*fake_override*/ val x: kotlin.String
public abstract override /*1*/ /*fake_override*/ val y: kotlin.String
public abstract val z: kotlin.String
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 external object ExternalObjectXY : ExternalInterfaceX {
private constructor ExternalObjectXY()
public open override /*1*/ val x: kotlin.String
public final val y: kotlin.String
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 external object ExternalObjectXYZ : ExternalInterfaceXY {
private constructor ExternalObjectXYZ()
public open override /*1*/ val x: kotlin.String
public open override /*1*/ val y: kotlin.String
public final val z: kotlin.String
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 external object ExternalObjectXZ : ExternalOpenClassX {
private constructor ExternalObjectXZ()
public final override /*1*/ /*fake_override*/ val x: kotlin.String
public final val z: kotlin.String
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
}
@kotlin.OptIn(markerClass = {kotlin.ExperimentalStdlibApi::class}) @kotlin.js.JsExternalInheritorsOnly public open external class ExternalOpenClassX {
public constructor ExternalOpenClassX()
public final val x: kotlin.String
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 open external class ExternalOpenClassXZ : ExternalOpenClassX {
public constructor ExternalOpenClassXZ()
public final override /*1*/ /*fake_override*/ val x: kotlin.String
public final val z: kotlin.String
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 interface InterfaceXY : ExternalInterfaceX {
public abstract override /*1*/ /*fake_override*/ val x: kotlin.String
public abstract val y: kotlin.String
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 interface InterfaceXY2 : ExternalClassNameSpace.NestedInterfaceX {
public abstract override /*1*/ /*fake_override*/ val x: kotlin.String
public abstract val y: kotlin.String
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 interface InterfaceXYZ : ExternalInterfaceXY {
public abstract override /*1*/ /*fake_override*/ val x: kotlin.String
public abstract override /*1*/ /*fake_override*/ val y: kotlin.String
public abstract val z: kotlin.String
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 interface InterfaceXYZ2 : ExternalClassNameSpace.NestedInterfaceXY {
public abstract override /*1*/ /*fake_override*/ val x: kotlin.String
public abstract override /*1*/ /*fake_override*/ val y: kotlin.String
public abstract val z: kotlin.String
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 object ObjectXY : ExternalInterfaceX {
private constructor ObjectXY()
public open override /*1*/ val x: kotlin.String = "X"
public final val y: kotlin.String = "Y"
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 object ObjectXYZ : ExternalInterfaceXY {
private constructor ObjectXYZ()
public open override /*1*/ val x: kotlin.String = "X"
public open override /*1*/ val y: kotlin.String = "Y"
public final val z: kotlin.String = "Z"
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 object ObjectXZ : ExternalOpenClassX {
private constructor ObjectXZ()
public final override /*1*/ /*fake_override*/ val x: kotlin.String
public final val z: kotlin.String = "Z"
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
}
@@ -36,6 +36,12 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
runTest("compiler/testData/diagnostics/testsWithJsStdLib/implementingFunction.kt");
}
@Test
@TestMetadata("jsExternalInheritorsOnly.kt")
public void testJsExternalInheritorsOnly() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJsStdLib/jsExternalInheritorsOnly.kt");
}
@Test
@TestMetadata("localClassMetadata.kt")
public void testLocalClassMetadata() throws Exception {