[JS] JsExport diagnostics and legacy support

Account for JsExport in legacy backend namer. It means we
catch overloaded exported function conflicts for free!

Add error diagnostics:
* NESTED_JS_EXPORT (Fixes KT-36798)
* WRONG_EXPORTED_DECLARATION (Part of the fix for KT-37752)
* NON_EXPORTABLE_TYPE (Fixes KT-37771)
This commit is contained in:
Svyatoslav Kuzmich
2019-08-29 18:25:09 +03:00
parent 4076bf40a9
commit 6e3d3831c2
52 changed files with 972 additions and 72 deletions
@@ -0,0 +1,26 @@
// !USE_EXPERIMENTAL: kotlin.js.ExperimentalJsExport
// !RENDER_DIAGNOSTICS_MESSAGES
package foo
open class NonExportedClass
@JsExport
class <!NON_EXPORTABLE_TYPE("super", "NonExportedClass")!>ExportedClass<!> : NonExportedClass()
interface NonExportedInterface
@JsExport
class <!NON_EXPORTABLE_TYPE("super", "NonExportedInterface")!>ExportedClass2<!> : NonExportedInterface
@JsExport
open class ExportedGenericClass<T>
@JsExport
class <!NON_EXPORTABLE_TYPE("super", "ExportedGenericClass<NonExportedClass>")!>ExportedClass3<!> : ExportedGenericClass<NonExportedClass>()
@JsExport
interface ExportedGenericInterface<T>
@JsExport
class <!NON_EXPORTABLE_TYPE("super", "ExportedGenericInterface<NonExportedClass>")!>ExportedClass4<!> : ExportedGenericInterface<NonExportedClass>
@@ -0,0 +1,58 @@
package
package foo {
@kotlin.js.JsExport public final class ExportedClass : foo.NonExportedClass {
public constructor ExportedClass()
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.js.JsExport public final class ExportedClass2 : foo.NonExportedInterface {
public constructor ExportedClass2()
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.js.JsExport public final class ExportedClass3 : foo.ExportedGenericClass<foo.NonExportedClass> {
public constructor ExportedClass3()
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.js.JsExport public final class ExportedClass4 : foo.ExportedGenericInterface<foo.NonExportedClass> {
public constructor ExportedClass4()
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.js.JsExport public open class ExportedGenericClass</*0*/ T> {
public constructor ExportedGenericClass</*0*/ T>()
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.js.JsExport public interface ExportedGenericInterface</*0*/ T> {
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 class NonExportedClass {
public constructor NonExportedClass()
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 NonExportedInterface {
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
}
}
@@ -0,0 +1,22 @@
// !USE_EXPERIMENTAL: kotlin.js.ExperimentalJsExport
package foo
class C1 {
<!NESTED_JS_EXPORT!>@JsExport<!>
fun f1() {}
<!NESTED_JS_EXPORT!>@JsExport<!>
val p: Int = 10
<!NESTED_JS_EXPORT!>@JsExport<!>
object O
}
fun f2() {
<!NESTED_JS_EXPORT!>@JsExport<!>
fun f3() {}
<!NESTED_JS_EXPORT!>@JsExport<!>
class C2
}
@@ -0,0 +1,21 @@
package
package foo {
public fun f2(): kotlin.Unit
public final class C1 {
public constructor C1()
@kotlin.js.JsExport public final val p: kotlin.Int = 10
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@kotlin.js.JsExport public final fun f1(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
@kotlin.js.JsExport public object O {
private constructor O()
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
}
}
}
@@ -0,0 +1,15 @@
// !USE_EXPERIMENTAL: kotlin.js.ExperimentalJsExport
// !RENDER_DIAGNOSTICS_MESSAGES
package foo
@JsExport
class C(val x: String) {
<!WRONG_EXPORTED_DECLARATION("secondary constructor without @JsName")!>constructor(x: Int)<!>: this(x.toString())
}
@JsExport
class C2(val x: String) {
@JsName("JsNameProvided")
constructor(x: Int): this(x.toString())
}
@@ -0,0 +1,22 @@
package
package foo {
@kotlin.js.JsExport public final class C {
public constructor C(/*0*/ x: kotlin.Int)
public constructor C(/*0*/ x: kotlin.String)
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
}
@kotlin.js.JsExport public final class C2 {
@kotlin.js.JsName(name = "JsNameProvided") public constructor C2(/*0*/ x: kotlin.Int)
public constructor C2(/*0*/ x: kotlin.String)
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
}
}
@@ -0,0 +1,56 @@
// !USE_EXPERIMENTAL: kotlin.js.ExperimentalJsExport
// !DIAGNOSTICS: -UNUSED_PARAMETER
// !RENDER_DIAGNOSTICS_MESSAGES
package foo
class C
@JsExport
fun foo(<!NON_EXPORTABLE_TYPE("parameter", "C")!>x: C<!>) {
}
<!NON_EXPORTABLE_TYPE("return", "C")!>@JsExport
fun bar()<!> = C()
<!NON_EXPORTABLE_TYPE("property", "C")!>@JsExport
val x: C<!> = C()
<!NON_EXPORTABLE_TYPE("property", "C")!>@JsExport
var x2: C<!>
get() = C()
set(value) { }
@JsExport
class A(
<!NON_EXPORTABLE_TYPE("parameter", "C"), NON_EXPORTABLE_TYPE("property", "C")!>val x: C<!>,
<!NON_EXPORTABLE_TYPE("parameter", "C")!>y: C<!>
) {
<!NON_EXPORTABLE_TYPE("return", "C")!>fun foo(<!NON_EXPORTABLE_TYPE("parameter", "C")!>x: C<!>)<!> = x
<!NON_EXPORTABLE_TYPE("property", "C")!>val x2: C<!> = C()
<!NON_EXPORTABLE_TYPE("property", "C")!>var x3: C<!>
get() = C()
set(value) { }
}
@JsExport
fun foo2() {
}
@JsExport
fun foo3(<!NON_EXPORTABLE_TYPE("parameter", "Unit")!>x: Unit<!>) {
}
@JsExport
fun foo4(x: () -> Unit) {
}
@JsExport
fun foo5(<!NON_EXPORTABLE_TYPE("parameter", "(Unit) -> Unit")!>x: (Unit) -> Unit<!>) {
}
@JsExport
fun foo6(x: (A) -> A) {
}
@@ -0,0 +1,31 @@
package
package foo {
@kotlin.js.JsExport public val x: foo.C
@kotlin.js.JsExport public var x2: foo.C
@kotlin.js.JsExport public fun bar(): foo.C
@kotlin.js.JsExport public fun foo(/*0*/ x: foo.C): kotlin.Unit
@kotlin.js.JsExport public fun foo2(): kotlin.Unit
@kotlin.js.JsExport public fun foo3(/*0*/ x: kotlin.Unit): kotlin.Unit
@kotlin.js.JsExport public fun foo4(/*0*/ x: () -> kotlin.Unit): kotlin.Unit
@kotlin.js.JsExport public fun foo5(/*0*/ x: (kotlin.Unit) -> kotlin.Unit): kotlin.Unit
@kotlin.js.JsExport public fun foo6(/*0*/ x: (foo.A) -> foo.A): kotlin.Unit
@kotlin.js.JsExport public final class A {
public constructor A(/*0*/ x: foo.C, /*1*/ y: foo.C)
public final val x: foo.C
public final val x2: foo.C
public final var x3: foo.C
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(/*0*/ x: foo.C): foo.C
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class C {
public constructor C()
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
}
}
@@ -0,0 +1,17 @@
// !USE_EXPERIMENTAL: kotlin.js.ExperimentalJsExport
// !DIAGNOSTICS: -UNUSED_PARAMETER
// !RENDER_DIAGNOSTICS_MESSAGES
package foo
abstract class C
interface I
@JsExport
fun <<!NON_EXPORTABLE_TYPE("upper bound", "C")!>T : C<!>>foo() { }
@JsExport
class A<<!NON_EXPORTABLE_TYPE("upper bound", "C")!>T : C<!>, <!NON_EXPORTABLE_TYPE("upper bound", "I")!>S: I<!>>
@JsExport
interface I2<<!NON_EXPORTABLE_TYPE("upper bound", "C"), NON_EXPORTABLE_TYPE("upper bound", "I")!>T<!>> where T : C, T : I
@@ -0,0 +1,31 @@
package
package foo {
@kotlin.js.JsExport public fun </*0*/ T : foo.C> foo(): kotlin.Unit
@kotlin.js.JsExport public final class A</*0*/ T : foo.C, /*1*/ S : foo.I> {
public constructor A</*0*/ T : foo.C, /*1*/ S : foo.I>()
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 abstract class C {
public constructor C()
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 I {
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.js.JsExport public interface I2</*0*/ T : foo.C> where T : foo.I {
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
}
}
@@ -0,0 +1,20 @@
// !USE_EXPERIMENTAL: kotlin.js.ExperimentalJsExport
// !RENDER_DIAGNOSTICS_MESSAGES
package foo
<!WRONG_EXPORTED_DECLARATION("inline function with reified type parameters")!>@JsExport
inline fun <reified T> inlineReifiedFun(x: Any)<!> = x is T
<!WRONG_EXPORTED_DECLARATION("suspend function")!>@JsExport
suspend fun suspendFun()<!> { }
<!WRONG_EXPORTED_DECLARATION("extension property")!>@JsExport
val String.extensionProperty<!>
get() = this.length
@JsExport
enum class <!WRONG_EXPORTED_DECLARATION("enum class")!>EnumClass<!> { ENTRY1, ENTRY2 }
@JsExport
annotation class <!WRONG_EXPORTED_DECLARATION("annotation class")!>AnnotationClass<!>
@@ -0,0 +1,33 @@
package
package foo {
@kotlin.js.JsExport public val kotlin.String.extensionProperty: kotlin.Int
@kotlin.js.JsExport public inline fun </*0*/ reified T> inlineReifiedFun(/*0*/ x: kotlin.Any): kotlin.Boolean
@kotlin.js.JsExport public suspend fun suspendFun(): kotlin.Unit
@kotlin.js.JsExport public final annotation class AnnotationClass : kotlin.Annotation {
public constructor AnnotationClass()
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.js.JsExport public final enum class EnumClass : kotlin.Enum<foo.EnumClass> {
enum entry ENTRY1
enum entry ENTRY2
private constructor EnumClass()
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: foo.EnumClass): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): foo.EnumClass
public final /*synthesized*/ fun values(): kotlin.Array<foo.EnumClass>
}
}
@@ -0,0 +1,17 @@
// !USE_EXPERIMENTAL: kotlin.js.ExperimentalJsExport
// !RENDER_DIAGNOSTICS_MESSAGES
@file:JsExport
package foo
<!WRONG_EXPORTED_DECLARATION("inline function with reified type parameters")!>inline fun <reified T> inlineReifiedFun(x: Any)<!> = x is T
<!WRONG_EXPORTED_DECLARATION("suspend function")!>suspend fun suspendFun()<!> { }
<!WRONG_EXPORTED_DECLARATION("extension property")!>val String.extensionProperty<!>
get() = this.length
enum class <!WRONG_EXPORTED_DECLARATION("enum class")!>EnumClass<!> { ENTRY1, ENTRY2 }
annotation class <!WRONG_EXPORTED_DECLARATION("annotation class")!>AnnotationClass<!>
@@ -0,0 +1,33 @@
package
package foo {
public val kotlin.String.extensionProperty: kotlin.Int
public inline fun </*0*/ reified T> inlineReifiedFun(/*0*/ x: kotlin.Any): kotlin.Boolean
public suspend fun suspendFun(): kotlin.Unit
public final annotation class AnnotationClass : kotlin.Annotation {
public constructor AnnotationClass()
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 enum class EnumClass : kotlin.Enum<foo.EnumClass> {
enum entry ENTRY1
enum entry ENTRY2
private constructor EnumClass()
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: foo.EnumClass): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): foo.EnumClass
public final /*synthesized*/ fun values(): kotlin.Array<foo.EnumClass>
}
}