From 37c8ec1e51352cc3f7a9c3dd83840629a8b46176 Mon Sep 17 00:00:00 2001 From: Alexander Korepanov Date: Wed, 19 Jul 2023 15:46:46 +0200 Subject: [PATCH] [JS FIR] Support JS_BUILTIN_NAME_CLASH diagnostic ^KT-59391 Fixed --- .../diagnostics/KtFirDataClassConverters.kt | 7 + .../api/fir/diagnostics/KtFirDiagnostics.kt | 5 + .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 6 + .../diagnostics/FirJsDiagnosticsList.kt | 3 + .../analysis/diagnostics/js/FirJsErrors.kt | 1 + .../js/FirJsErrorsDefaultMessages.kt | 7 + .../fir/analysis/js/checkers/FirJsHelpers.kt | 36 +++++ .../js/checkers/JsDeclarationCheckers.kt | 1 + .../FirJsBuiltinNameClashChecker.kt | 44 ++++++ .../name/builtinClash.fir.kt | 56 -------- .../testsWithJsStdLib/name/builtinClash.kt | 75 +++++++++- .../testsWithJsStdLib/name/builtinClash.txt | 135 ++++++++++++++++++ 12 files changed, 319 insertions(+), 57 deletions(-) create mode 100644 compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsBuiltinNameClashChecker.kt delete mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/name/builtinClash.fir.kt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index 00688abb1a5..1bae343464c 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -1227,6 +1227,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirJsErrors.JS_BUILTIN_NAME_CLASH) { firDiagnostic -> + JsBuiltinNameClashImpl( + firDiagnostic.a, + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirErrors.OPT_IN_USAGE) { firDiagnostic -> OptInUsageImpl( firDiagnostic.a, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index d11dc950f9f..187a322d8a9 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -881,6 +881,11 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = JsNameProhibitedForExtensionProperty::class } + interface JsBuiltinNameClash : KtFirDiagnostic { + override val diagnosticClass get() = JsBuiltinNameClash::class + val name: String + } + interface OptInUsage : KtFirDiagnostic { override val diagnosticClass get() = OptInUsage::class val optInMarkerFqName: FqName diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 9b0d721568d..43673aea7d0 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -1059,6 +1059,12 @@ internal class JsNameProhibitedForExtensionPropertyImpl( token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.JsNameProhibitedForExtensionProperty +internal class JsBuiltinNameClashImpl( + override val name: String, + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.JsBuiltinNameClash + internal class OptInUsageImpl( override val optInMarkerFqName: FqName, override val message: String, diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJsDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJsDiagnosticsList.kt index dd3644b0565..441ac793944 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJsDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJsDiagnosticsList.kt @@ -54,6 +54,9 @@ object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") { val JS_NAME_ON_PRIMARY_CONSTRUCTOR_PROHIBITED by error() val JS_NAME_ON_ACCESSOR_AND_PROPERTY by error() val JS_NAME_PROHIBITED_FOR_EXTENSION_PROPERTY by error() + val JS_BUILTIN_NAME_CLASH by error(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) { + parameter("name") + } } val SUPERTYPES by object : DiagnosticGroup("Supertypes") { diff --git a/compiler/fir/checkers/checkers.js/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrors.kt b/compiler/fir/checkers/checkers.js/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrors.kt index 109f28f30a9..2ff14468a6d 100644 --- a/compiler/fir/checkers/checkers.js/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrors.kt +++ b/compiler/fir/checkers/checkers.js/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrors.kt @@ -50,6 +50,7 @@ object FirJsErrors { val JS_NAME_ON_PRIMARY_CONSTRUCTOR_PROHIBITED by error0() val JS_NAME_ON_ACCESSOR_AND_PROPERTY by error0() val JS_NAME_PROHIBITED_FOR_EXTENSION_PROPERTY by error0() + val JS_BUILTIN_NAME_CLASH by error1(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT) // Supertypes val WRONG_MULTIPLE_INHERITANCE by error1>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT) diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrorsDefaultMessages.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrorsDefaultMessages.kt index c0b94c2a084..9a554318644 100644 --- a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/diagnostics/js/FirJsErrorsDefaultMessages.kt @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.ENUM_CLASS_I import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.EXTERNAL_INTERFACE_AS_REIFIED_TYPE_ARGUMENT 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_BUILTIN_NAME_CLASH import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.JS_EXTERNAL_ARGUMENT 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 @@ -193,6 +194,12 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() { FirDiagnosticRenderers.RENDER_TYPE ) map.put(JS_NAME_PROHIBITED_FOR_EXTENSION_PROPERTY, "@JsName is prohibited for extension properties") + map.put( + JS_BUILTIN_NAME_CLASH, + "JavaScript name generated for this declaration clashes with built-in declaration {0}", + CommonRenderers.STRING + ) + 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") map.put(JS_NAME_PROHIBITED_FOR_OVERRIDE, "@JsName is prohibited for overridden members") diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/FirJsHelpers.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/FirJsHelpers.kt index 98dbcce0204..6d6f142072a 100644 --- a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/FirJsHelpers.kt +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/FirJsHelpers.kt @@ -10,6 +10,7 @@ package org.jetbrains.kotlin.fir.analysis.js.checkers import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.effectiveVisibility import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.checkers.* import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext @@ -161,3 +162,38 @@ internal fun getRootClassLikeSymbolOrSelf(symbol: FirBasedSymbol<*>, session: Fi return symbol.getContainingClassSymbol(session)?.let { getRootClassLikeSymbolOrSelf(it, session) } ?: symbol } +internal fun FirBasedSymbol<*>.getStableNameInJavaScript(session: FirSession): String? { + val jsName = getJsName(session) + if (jsName != null) { + return jsName + } + val hasStableNameInJavaScript = when { + isEffectivelyExternal(session) -> true + isExportedObject(session) -> true + else -> false + } + + // TODO: rethink in KT-60554 + val hasPublicName = when (this) { + is FirClassLikeSymbol -> !isLocal + is FirCallableSymbol -> { + val parentClass = getContainingClassSymbol(session) + if (parentClass != null) { + when (visibility) { + is Visibilities.Public -> true + is Visibilities.Protected -> !parentClass.isFinal && parentClass.visibility.isPublicAPI + else -> false + } + } else { + !callableId.isLocal && effectiveVisibility.publicApi + } + } + else -> false + } + + if (hasStableNameInJavaScript || hasPublicName) { + return (fir as? FirMemberDeclaration)?.nameOrSpecialName?.identifierOrNullIfSpecial + } + return null +} + diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsDeclarationCheckers.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsDeclarationCheckers.kt index d2f2692ac81..de7308b788e 100644 --- a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsDeclarationCheckers.kt +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsDeclarationCheckers.kt @@ -23,6 +23,7 @@ object JsDeclarationCheckers : DeclarationCheckers() { FirJsNameChecker, FirJsExportAnnotationChecker, FirJsExportDeclarationChecker, + FirJsBuiltinNameClashChecker ) override val classCheckers: Set diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsBuiltinNameClashChecker.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsBuiltinNameClashChecker.kt new file mode 100644 index 00000000000..3fd689829ad --- /dev/null +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsBuiltinNameClashChecker.kt @@ -0,0 +1,44 @@ +/* + * 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.FirBasicDeclarationChecker +import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol +import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors +import org.jetbrains.kotlin.fir.analysis.js.checkers.getStableNameInJavaScript +import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeObject +import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration +import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration +import org.jetbrains.kotlin.fir.declarations.FirDeclaration +import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility +import org.jetbrains.kotlin.fir.declarations.utils.isLocal +import org.jetbrains.kotlin.fir.declarations.utils.nameOrSpecialName + +object FirJsBuiltinNameClashChecker : FirBasicDeclarationChecker() { + private val PROHIBITED_STATIC_NAMES = setOf("prototype", "length", "\$metadata\$") + private val PROHIBITED_MEMBER_NAMES = setOf("constructor") + + override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { + if (declaration.symbol.isNativeObject(context.session)) { + return + } + if (declaration.getContainingClassSymbol(context.session) == null) { + return + } + + val stableName = declaration.symbol.getStableNameInJavaScript(context.session) ?: return + + if (declaration is FirClassLikeDeclaration && stableName in PROHIBITED_STATIC_NAMES) { + reporter.reportOn(declaration.source, FirJsErrors.JS_BUILTIN_NAME_CLASH, "Function.$stableName", context) + } + if (declaration is FirCallableDeclaration && stableName in PROHIBITED_MEMBER_NAMES) { + reporter.reportOn(declaration.source, FirJsErrors.JS_BUILTIN_NAME_CLASH, "Object.prototype.$stableName", context) + } + } +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/name/builtinClash.fir.kt b/compiler/testData/diagnostics/testsWithJsStdLib/name/builtinClash.fir.kt deleted file mode 100644 index 6d9873173c7..00000000000 --- a/compiler/testData/diagnostics/testsWithJsStdLib/name/builtinClash.fir.kt +++ /dev/null @@ -1,56 +0,0 @@ -class C { - class prototype - - class length - - class `$metadata$` - - fun constructor() {} -} - -class D { - private class prototype - - private class length - - private class `$metadata$` - - private fun constructor() {} -} - -class E { - @JsName("prototype") - class D - - @JsName("constructor") - fun f() {} -} - -class F { - @JsName("A") - class prototype - - @JsName("B") - class length - - @JsName("f") - fun constructor() {} -} - -class prototype - -class length - -fun constructor() { -} - -fun f() { - class prototype - class length - - fun constructor() {} -} - -external interface Object { - val constructor: Any? -} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/name/builtinClash.kt b/compiler/testData/diagnostics/testsWithJsStdLib/name/builtinClash.kt index 88d7de80da4..db44a78e62d 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/name/builtinClash.kt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/name/builtinClash.kt @@ -1,3 +1,6 @@ +// FIR_IDENTICAL +// !OPT_IN: kotlin.js.ExperimentalJsExport +// FILE: f0.kt class C { class prototype @@ -37,6 +40,27 @@ class F { fun constructor() {} } +class G { + val x: String + @JsName("constructor") get() { + return "1" + } +} + +class H { + var x: String = "1" + @JsName("constructor") set(v) { + field = v + } + @JsName("getter") get() { + return "1" + } +} + +class I { + val constructor = 1 +} + class prototype class length @@ -53,4 +77,53 @@ fun f() { external interface Object { val constructor: Any? -} \ No newline at end of file +} + +external interface ExternalInterface { + fun constructor() +} + +class NonExternalChild : ExternalInterface { + override fun constructor() {} +} + +// FILE: f1.kt +package foo1 + +class prototype { + companion object { + fun test() {} + } +} + +class length { + companion object { + fun test() {} + } +} + +@JsExport +class C { + class prototype + + class length + + class `$metadata$` + + fun constructor() {} +} + +// FILE: f2.kt +package foo2 + +external class prototype { + companion object { + fun test() + } +} + +external class length { + companion object { + fun test() + } +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/name/builtinClash.txt b/compiler/testData/diagnostics/testsWithJsStdLib/name/builtinClash.txt index 0864678f7a9..4c36f17e505 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/name/builtinClash.txt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/name/builtinClash.txt @@ -76,6 +76,13 @@ public final class E { } } +public external interface ExternalInterface { + public abstract fun constructor(): kotlin.Unit + 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 F { public constructor F() @kotlin.js.JsName(name = "f") public final fun constructor(): kotlin.Unit @@ -98,6 +105,38 @@ public final class F { } } +public final class G { + public constructor G() + @get:kotlin.js.JsName(name = "constructor") 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 final class H { + public constructor H() + @get:kotlin.js.JsName(name = "getter") @set:kotlin.js.JsName(name = "constructor") public final var 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 final class I { + public constructor I() + public final val constructor: kotlin.Int = 1 + 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 NonExternalChild : ExternalInterface { + public constructor NonExternalChild() + public open override /*1*/ fun constructor(): kotlin.Unit + 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 Object { public abstract val constructor: kotlin.Any? public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean @@ -118,3 +157,99 @@ public final class prototype { public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } + +package foo1 { + + @kotlin.js.JsExport public final class C { + public constructor C() + public final fun constructor(): kotlin.Unit + 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 `$metadata$` { + public constructor `$metadata$`() + 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 length { + public constructor length() + 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 prototype { + public constructor prototype() + 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 length { + public constructor length() + 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 Companion { + private constructor Companion() + 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 final fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } + + public final class prototype { + public constructor prototype() + 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 Companion { + private constructor Companion() + 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 final fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} + +package foo2 { + + public final external class length { + public constructor length() + 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 Companion { + private constructor Companion() + 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 final fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } + + public final external class prototype { + public constructor prototype() + 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 Companion { + private constructor Companion() + 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 final fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} +