[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:
+26
@@ -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>
|
||||||
+58
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -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
|
||||||
|
}
|
||||||
+21
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+15
@@ -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())
|
||||||
|
}
|
||||||
Vendored
+22
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
+56
@@ -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) {
|
||||||
|
}
|
||||||
+31
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+17
@@ -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
|
||||||
Vendored
+31
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -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<!>
|
||||||
+33
@@ -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>
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+17
@@ -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<!>
|
||||||
Vendored
+33
@@ -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>
|
||||||
|
}
|
||||||
|
}
|
||||||
+48
@@ -334,6 +334,54 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/testsWithJsStdLib/export")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Export extends AbstractDiagnosticsTestWithJsStdLib {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInExport() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJsStdLib/export"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extendingNonExportedType.kt")
|
||||||
|
public void testExtendingNonExportedType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithJsStdLib/export/extendingNonExportedType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jsExportOnNestedDeclarations.kt")
|
||||||
|
public void testJsExportOnNestedDeclarations() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithJsStdLib/export/jsExportOnNestedDeclarations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("secondaryConstructorWithoutJsName.kt")
|
||||||
|
public void testSecondaryConstructorWithoutJsName() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithJsStdLib/export/secondaryConstructorWithoutJsName.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unexportableTypesInSignature.kt")
|
||||||
|
public void testUnexportableTypesInSignature() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithJsStdLib/export/unexportableTypesInSignature.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unexportableTypesInTypeParameters.kt")
|
||||||
|
public void testUnexportableTypesInTypeParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithJsStdLib/export/unexportableTypesInTypeParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("wrongExportedDeclaration.kt")
|
||||||
|
public void testWrongExportedDeclaration() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithJsStdLib/export/wrongExportedDeclaration.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("wrongExportedDeclarationInExportedFile.kt")
|
||||||
|
public void testWrongExportedDeclarationInExportedFile() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithJsStdLib/export/wrongExportedDeclarationInExportedFile.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/testsWithJsStdLib/inline")
|
@TestMetadata("compiler/testData/diagnostics/testsWithJsStdLib/inline")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
|||||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.getNameForAnnotatedObject
|
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.getNameForAnnotatedObject
|
||||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.isNativeObject
|
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.isNativeObject
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject
|
import org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
||||||
@@ -40,7 +41,7 @@ import kotlin.math.abs
|
|||||||
* A new instance of this class can be created for each request, however, it's recommended to use stable instance, since
|
* A new instance of this class can be created for each request, however, it's recommended to use stable instance, since
|
||||||
* [NameSuggestion] supports caching.
|
* [NameSuggestion] supports caching.
|
||||||
*/
|
*/
|
||||||
class NameSuggestion {
|
class NameSuggestion(val bindingContext: BindingContext) {
|
||||||
private val cache: MutableMap<DeclarationDescriptor, SuggestedName?> = Collections.synchronizedMap(WeakHashMap())
|
private val cache: MutableMap<DeclarationDescriptor, SuggestedName?> = Collections.synchronizedMap(WeakHashMap())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,7 +113,7 @@ class NameSuggestion {
|
|||||||
// Local functions and variables are always private with their own names as suggested names
|
// Local functions and variables are always private with their own names as suggested names
|
||||||
is CallableDescriptor ->
|
is CallableDescriptor ->
|
||||||
if (DescriptorUtils.isDescriptorWithLocalVisibility(descriptor)) {
|
if (DescriptorUtils.isDescriptorWithLocalVisibility(descriptor)) {
|
||||||
val ownName = getNameForAnnotatedObject(descriptor) ?: getSuggestedName(descriptor)
|
val ownName = getNameForAnnotatedObject(descriptor, bindingContext) ?: getSuggestedName(descriptor)
|
||||||
var name = ownName
|
var name = ownName
|
||||||
var scope = descriptor.containingDeclaration
|
var scope = descriptor.containingDeclaration
|
||||||
|
|
||||||
@@ -195,7 +196,7 @@ class NameSuggestion {
|
|||||||
|
|
||||||
parts.reverse()
|
parts.reverse()
|
||||||
val unmangledName = parts.joinToString("$")
|
val unmangledName = parts.joinToString("$")
|
||||||
val (id, stable) = mangleNameIfNecessary(unmangledName, fixedDescriptor)
|
val (id, stable) = mangleNameIfNecessary(unmangledName, fixedDescriptor, bindingContext)
|
||||||
return SuggestedName(listOf(id), stable, fixedDescriptor, current)
|
return SuggestedName(listOf(id), stable, fixedDescriptor, current)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +218,7 @@ class NameSuggestion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun mangleNameIfNecessary(baseName: String, descriptor: DeclarationDescriptor): NameAndStability {
|
private fun mangleNameIfNecessary(baseName: String, descriptor: DeclarationDescriptor, bindingContext: BindingContext): NameAndStability {
|
||||||
// If we have a callable descriptor (property or method) it can override method in a parent class.
|
// If we have a callable descriptor (property or method) it can override method in a parent class.
|
||||||
// Traverse to the topmost overridden method.
|
// Traverse to the topmost overridden method.
|
||||||
// It does not matter which path to choose during traversal, since front-end must ensure
|
// It does not matter which path to choose during traversal, since front-end must ensure
|
||||||
@@ -230,7 +231,7 @@ class NameSuggestion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If declaration is marked with either external, @native, @library or @JsName, return its stable name as is.
|
// If declaration is marked with either external, @native, @library or @JsName, return its stable name as is.
|
||||||
val nativeName = getNameForAnnotatedObject(overriddenDescriptor)
|
val nativeName = getNameForAnnotatedObject(overriddenDescriptor, bindingContext)
|
||||||
if (nativeName != null) return NameAndStability(nativeName, true)
|
if (nativeName != null) return NameAndStability(nativeName, true)
|
||||||
|
|
||||||
if (overriddenDescriptor is FunctionDescriptor) {
|
if (overriddenDescriptor is FunctionDescriptor) {
|
||||||
|
|||||||
@@ -31,11 +31,13 @@ import org.jetbrains.kotlin.types.DynamicTypesAllowed
|
|||||||
object JsPlatformConfigurator : PlatformConfiguratorBase(
|
object JsPlatformConfigurator : PlatformConfiguratorBase(
|
||||||
DynamicTypesAllowed(),
|
DynamicTypesAllowed(),
|
||||||
additionalDeclarationCheckers = listOf(
|
additionalDeclarationCheckers = listOf(
|
||||||
NativeInvokeChecker(), NativeGetterChecker(), NativeSetterChecker(),
|
NativeInvokeChecker(), NativeGetterChecker(), NativeSetterChecker(),
|
||||||
JsNameChecker, JsModuleChecker, JsExternalFileChecker,
|
JsNameChecker, JsModuleChecker, JsExternalFileChecker,
|
||||||
JsExternalChecker, JsInheritanceChecker, JsMultipleInheritanceChecker,
|
JsExternalChecker, JsInheritanceChecker, JsMultipleInheritanceChecker,
|
||||||
JsRuntimeAnnotationChecker,
|
JsRuntimeAnnotationChecker,
|
||||||
JsDynamicDeclarationChecker
|
JsDynamicDeclarationChecker,
|
||||||
|
JsExportAnnotationChecker,
|
||||||
|
JsExportDeclarationChecker
|
||||||
),
|
),
|
||||||
additionalCallCheckers = listOf(
|
additionalCallCheckers = listOf(
|
||||||
JsModuleCallChecker,
|
JsModuleCallChecker,
|
||||||
@@ -46,7 +48,6 @@ object JsPlatformConfigurator : PlatformConfiguratorBase(
|
|||||||
identifierChecker = JsIdentifierChecker
|
identifierChecker = JsIdentifierChecker
|
||||||
) {
|
) {
|
||||||
override fun configureModuleComponents(container: StorageComponentContainer) {
|
override fun configureModuleComponents(container: StorageComponentContainer) {
|
||||||
container.useInstance(NameSuggestion())
|
|
||||||
container.useImpl<JsCallChecker>()
|
container.useImpl<JsCallChecker>()
|
||||||
container.useImpl<JsTypeSpecificityComparator>()
|
container.useImpl<JsTypeSpecificityComparator>()
|
||||||
container.useImpl<JsNameClashChecker>()
|
container.useImpl<JsNameClashChecker>()
|
||||||
|
|||||||
+4
@@ -100,6 +100,10 @@ private val DIAGNOSTIC_FACTORY_TO_RENDERER by lazy {
|
|||||||
"Can't apply multiple inheritance here, since it's impossible to generate bridge for system function {0}",
|
"Can't apply multiple inheritance here, since it's impossible to generate bridge for system function {0}",
|
||||||
Renderers.DECLARATION_NAME_WITH_KIND)
|
Renderers.DECLARATION_NAME_WITH_KIND)
|
||||||
|
|
||||||
|
put(ErrorsJs.NESTED_JS_EXPORT, "@JsExport is only allowed on files and top-level declarations")
|
||||||
|
put(ErrorsJs.WRONG_EXPORTED_DECLARATION, "Declaration of such kind ({0}) can't be exported to JS", Renderers.STRING)
|
||||||
|
put(ErrorsJs.NON_EXPORTABLE_TYPE, "Exported declaration uses non-exportable {0} type: {1}", Renderers.STRING, RENDER_TYPE)
|
||||||
|
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,10 @@ public interface ErrorsJs {
|
|||||||
DiagnosticFactory1<PsiElement, CallableMemberDescriptor> WRONG_MULTIPLE_INHERITANCE =
|
DiagnosticFactory1<PsiElement, CallableMemberDescriptor> WRONG_MULTIPLE_INHERITANCE =
|
||||||
DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
|
||||||
|
DiagnosticFactory0<PsiElement> NESTED_JS_EXPORT = DiagnosticFactory0.create(ERROR);
|
||||||
|
DiagnosticFactory1<KtExpression, String> WRONG_EXPORTED_DECLARATION = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
DiagnosticFactory2<PsiElement, String, KotlinType> NON_EXPORTABLE_TYPE = DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
|
||||||
@SuppressWarnings("UnusedDeclaration")
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
Object _initializer = new Object() {
|
Object _initializer = new Object() {
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-1
@@ -25,8 +25,9 @@ import org.jetbrains.kotlin.psi.KtDeclaration
|
|||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||||
|
|
||||||
class JsBuiltinNameClashChecker(private val nameSuggestion: NameSuggestion) : DeclarationChecker {
|
class JsBuiltinNameClashChecker : DeclarationChecker {
|
||||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
|
val nameSuggestion = NameSuggestion(context.trace.bindingContext)
|
||||||
if (AnnotationsUtils.isNativeObject(descriptor)) return
|
if (AnnotationsUtils.isNativeObject(descriptor)) return
|
||||||
if (descriptor.containingDeclaration !is ClassDescriptor) return
|
if (descriptor.containingDeclaration !is ClassDescriptor) return
|
||||||
|
|
||||||
|
|||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.js.resolve.diagnostics
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
|
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||||
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||||
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
|
|
||||||
|
object JsExportAnnotationChecker : DeclarationChecker {
|
||||||
|
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
|
val trace = context.trace
|
||||||
|
|
||||||
|
val jsExport = AnnotationsUtils.getJsExportAnnotation(descriptor) ?: return
|
||||||
|
val jsExportPsi = jsExport.source.getPsi() ?: declaration
|
||||||
|
|
||||||
|
if (descriptor !is PackageFragmentDescriptor && !DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
||||||
|
trace.report(ErrorsJs.NESTED_JS_EXPORT.on(jsExportPsi))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+173
@@ -0,0 +1,173 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.js.resolve.diagnostics
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind.*
|
||||||
|
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||||
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtensionProperty
|
||||||
|
import org.jetbrains.kotlin.resolve.inline.isInlineWithReified
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.TypeProjection
|
||||||
|
import org.jetbrains.kotlin.types.isDynamic
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.*
|
||||||
|
|
||||||
|
object JsExportDeclarationChecker : DeclarationChecker {
|
||||||
|
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
|
val trace = context.trace
|
||||||
|
val bindingContext = trace.bindingContext
|
||||||
|
|
||||||
|
fun checkTypeParameter(descriptor: TypeParameterDescriptor) {
|
||||||
|
for (upperBound in descriptor.upperBounds) {
|
||||||
|
if (!isTypeExportable(upperBound, bindingContext)) {
|
||||||
|
val typeParameterDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(descriptor)!!
|
||||||
|
trace.report(ErrorsJs.NON_EXPORTABLE_TYPE.on(typeParameterDeclaration, "upper bound", upperBound))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkValueParameter(descriptor: ValueParameterDescriptor) {
|
||||||
|
if (!isTypeExportable(descriptor.type, bindingContext)) {
|
||||||
|
val valueParameterDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(descriptor)!!
|
||||||
|
trace.report(ErrorsJs.NON_EXPORTABLE_TYPE.on(valueParameterDeclaration, "parameter", descriptor.type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AnnotationsUtils.isExportedObject(descriptor, bindingContext)) return
|
||||||
|
if (descriptor !is MemberDescriptor)
|
||||||
|
return
|
||||||
|
|
||||||
|
val hasJsName = AnnotationsUtils.getJsNameAnnotation(descriptor) != null
|
||||||
|
|
||||||
|
fun reportWrongExportedDeclaration(kind: String) {
|
||||||
|
trace.report(ErrorsJs.WRONG_EXPORTED_DECLARATION.on(declaration, kind))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (descriptor.isExpect) {
|
||||||
|
reportWrongExportedDeclaration("expect")
|
||||||
|
}
|
||||||
|
|
||||||
|
when (descriptor) {
|
||||||
|
is FunctionDescriptor -> {
|
||||||
|
for (typeParameter in descriptor.typeParameters) {
|
||||||
|
checkTypeParameter(typeParameter)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (descriptor.isInlineWithReified()) {
|
||||||
|
reportWrongExportedDeclaration("inline function with reified type parameters")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (descriptor.isSuspend) {
|
||||||
|
reportWrongExportedDeclaration("suspend function")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (descriptor is ConstructorDescriptor) {
|
||||||
|
if (!descriptor.isPrimary && !hasJsName)
|
||||||
|
reportWrongExportedDeclaration("secondary constructor without @JsName")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Properties are checked instead of property accessors
|
||||||
|
if (descriptor !is PropertyAccessorDescriptor) {
|
||||||
|
for (parameter in descriptor.valueParameters) {
|
||||||
|
checkValueParameter(parameter)
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptor.returnType?.let { returnType ->
|
||||||
|
if (!isTypeExportable(returnType, bindingContext, true)) {
|
||||||
|
trace.report(ErrorsJs.NON_EXPORTABLE_TYPE.on(declaration, "return", returnType))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is PropertyDescriptor -> {
|
||||||
|
if (descriptor.isExtensionProperty) {
|
||||||
|
reportWrongExportedDeclaration("extension property")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!isTypeExportable(descriptor.type, bindingContext)) {
|
||||||
|
trace.report(ErrorsJs.NON_EXPORTABLE_TYPE.on(declaration, "property", descriptor.type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is ClassDescriptor -> {
|
||||||
|
for (typeParameter in descriptor.declaredTypeParameters) {
|
||||||
|
checkTypeParameter(typeParameter)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (descriptor.kind == ENUM_CLASS) {
|
||||||
|
reportWrongExportedDeclaration("enum class")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (descriptor.kind == ANNOTATION_CLASS) {
|
||||||
|
reportWrongExportedDeclaration("annotation class")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (descriptor.kind == ENUM_ENTRY) {
|
||||||
|
// Covered by ENUM_CLASS
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for (superType in descriptor.defaultType.supertypes()) {
|
||||||
|
if (!isTypeExportable(superType, bindingContext)) {
|
||||||
|
trace.report(ErrorsJs.NON_EXPORTABLE_TYPE.on(declaration, "super", superType))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun isTypeExportable(type: KotlinType, bindingContext: BindingContext, isReturnType: Boolean = false): Boolean {
|
||||||
|
if (isReturnType && type.isUnit())
|
||||||
|
return true
|
||||||
|
|
||||||
|
if (type.isFunctionType) {
|
||||||
|
val arguments = type.arguments
|
||||||
|
val argumentsSize = type.arguments.size - 1
|
||||||
|
for (i in 0 until argumentsSize) {
|
||||||
|
if (!isTypeExportable(arguments[i].type, bindingContext))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!isTypeExportable(arguments.last().type, bindingContext, isReturnType = true))
|
||||||
|
return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for (argument: TypeProjection in type.arguments) {
|
||||||
|
if (!isTypeExportable(argument.type, bindingContext))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val nonNullable = type.makeNotNullable()
|
||||||
|
|
||||||
|
// Is primitive exportable type
|
||||||
|
if (nonNullable.isAnyOrNullableAny() ||
|
||||||
|
nonNullable.isDynamic() ||
|
||||||
|
nonNullable.isBoolean() ||
|
||||||
|
KotlinBuiltIns.isThrowableOrNullableThrowable(nonNullable) ||
|
||||||
|
KotlinBuiltIns.isString(nonNullable) ||
|
||||||
|
(nonNullable.isPrimitiveNumberOrNullableType() && !nonNullable.isLong()) ||
|
||||||
|
nonNullable.isNothingOrNullableNothing() ||
|
||||||
|
(KotlinBuiltIns.isArray(type)) ||
|
||||||
|
KotlinBuiltIns.isPrimitiveArray(type)
|
||||||
|
) return true
|
||||||
|
|
||||||
|
val descriptor: ClassifierDescriptor = type.constructor.declarationDescriptor ?: return false
|
||||||
|
return descriptor.isEffectivelyExternal() || AnnotationsUtils.isExportedObject(descriptor, bindingContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
-2
@@ -5,18 +5,29 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.js.resolve.diagnostics
|
package org.jetbrains.kotlin.js.resolve.diagnostics
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||||
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.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||||
|
|
||||||
class JsNameCharsChecker(private val suggestion: NameSuggestion) : DeclarationChecker {
|
class JsNameCharsChecker : DeclarationChecker {
|
||||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
|
val bindingContext = context.trace.bindingContext
|
||||||
|
|
||||||
if (descriptor is PropertyAccessorDescriptor && AnnotationsUtils.getJsName(descriptor) == null) return
|
if (descriptor is PropertyAccessorDescriptor && AnnotationsUtils.getJsName(descriptor) == null) return
|
||||||
|
|
||||||
|
// This case will be reported as WRONG_EXPORTED_DECLARATION for
|
||||||
|
// secondary constructor with missing JsName. Skipping it here to simplify further logic.
|
||||||
|
if (descriptor is ConstructorDescriptor &&
|
||||||
|
AnnotationsUtils.getJsName(descriptor) == null &&
|
||||||
|
AnnotationsUtils.isExportedObject(descriptor, bindingContext)
|
||||||
|
) return
|
||||||
|
|
||||||
|
val suggestion = NameSuggestion(bindingContext)
|
||||||
val suggestedName = suggestion.suggest(descriptor) ?: return
|
val suggestedName = suggestion.suggest(descriptor) ?: return
|
||||||
if (suggestedName.stable && suggestedName.names.any { NameSuggestion.sanitizeName(it) != it }) {
|
if (suggestedName.stable && suggestedName.names.any { NameSuggestion.sanitizeName(it) != it }) {
|
||||||
context.trace.report(ErrorsJs.NAME_CONTAINS_ILLEGAL_CHARS.on(declaration))
|
context.trace.report(ErrorsJs.NAME_CONTAINS_ILLEGAL_CHARS.on(declaration))
|
||||||
|
|||||||
+3
-1
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isExtensionProperty
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
|
|
||||||
class JsNameClashChecker(
|
class JsNameClashChecker(
|
||||||
private val nameSuggestion: NameSuggestion,
|
|
||||||
private val languageVersionSettings: LanguageVersionSettings
|
private val languageVersionSettings: LanguageVersionSettings
|
||||||
) : DeclarationChecker {
|
) : DeclarationChecker {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -45,6 +44,7 @@ class JsNameClashChecker(
|
|||||||
Errors.PACKAGE_OR_CLASSIFIER_REDECLARATION)
|
Errors.PACKAGE_OR_CLASSIFIER_REDECLARATION)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lateinit var nameSuggestion: NameSuggestion
|
||||||
private val scopes = mutableMapOf<DeclarationDescriptor, MutableMap<String, DeclarationDescriptor>>()
|
private val scopes = mutableMapOf<DeclarationDescriptor, MutableMap<String, DeclarationDescriptor>>()
|
||||||
private val clashedFakeOverrides = mutableMapOf<DeclarationDescriptor, Pair<DeclarationDescriptor, DeclarationDescriptor>>()
|
private val clashedFakeOverrides = mutableMapOf<DeclarationDescriptor, Pair<DeclarationDescriptor, DeclarationDescriptor>>()
|
||||||
private val clashedDescriptors = mutableSetOf<Pair<DeclarationDescriptor, String>>()
|
private val clashedDescriptors = mutableSetOf<Pair<DeclarationDescriptor, String>>()
|
||||||
@@ -62,6 +62,8 @@ class JsNameClashChecker(
|
|||||||
diagnosticHolder: DiagnosticSink, bindingContext: BindingContext
|
diagnosticHolder: DiagnosticSink, bindingContext: BindingContext
|
||||||
) {
|
) {
|
||||||
if (descriptor is ConstructorDescriptor && descriptor.isPrimary) return
|
if (descriptor is ConstructorDescriptor && descriptor.isPrimary) return
|
||||||
|
if (!this::nameSuggestion.isInitialized || nameSuggestion.bindingContext !== bindingContext)
|
||||||
|
nameSuggestion = NameSuggestion(bindingContext)
|
||||||
|
|
||||||
for (suggested in nameSuggestion.suggestAllPossibleNames(descriptor)) {
|
for (suggested in nameSuggestion.suggestAllPossibleNames(descriptor)) {
|
||||||
if (suggested.stable && suggested.scope is ClassOrPackageFragmentDescriptor && presentsInGeneratedCode(suggested.descriptor)) {
|
if (suggested.stable && suggested.scope is ClassOrPackageFragmentDescriptor && presentsInGeneratedCode(suggested.descriptor)) {
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.isEf
|
|||||||
|
|
||||||
public final class AnnotationsUtils {
|
public final class AnnotationsUtils {
|
||||||
private static final String JS_NAME = "kotlin.js.JsName";
|
private static final String JS_NAME = "kotlin.js.JsName";
|
||||||
|
private static final FqName JS_EXPORT = new FqName("kotlin.js.JsExport");
|
||||||
public static final FqName JS_MODULE_ANNOTATION = new FqName("kotlin.js.JsModule");
|
public static final FqName JS_MODULE_ANNOTATION = new FqName("kotlin.js.JsModule");
|
||||||
private static final FqName JS_NON_MODULE_ANNOTATION = new FqName("kotlin.js.JsNonModule");
|
private static final FqName JS_NON_MODULE_ANNOTATION = new FqName("kotlin.js.JsNonModule");
|
||||||
public static final FqName JS_QUALIFIER_ANNOTATION = new FqName("kotlin.js.JsQualifier");
|
public static final FqName JS_QUALIFIER_ANNOTATION = new FqName("kotlin.js.JsQualifier");
|
||||||
@@ -83,7 +84,10 @@ public final class AnnotationsUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static String getNameForAnnotatedObject(@NotNull DeclarationDescriptor descriptor) {
|
public static String getNameForAnnotatedObject(
|
||||||
|
@NotNull DeclarationDescriptor descriptor,
|
||||||
|
@NotNull BindingContext bindingContext
|
||||||
|
) {
|
||||||
String defaultJsName = getJsName(descriptor);
|
String defaultJsName = getJsName(descriptor);
|
||||||
|
|
||||||
for (PredefinedAnnotation annotation : PredefinedAnnotation.Companion.getWITH_CUSTOM_NAME()) {
|
for (PredefinedAnnotation annotation : PredefinedAnnotation.Companion.getWITH_CUSTOM_NAME()) {
|
||||||
@@ -97,7 +101,7 @@ public final class AnnotationsUtils {
|
|||||||
return name != null ? name : descriptor.getName().asString();
|
return name != null ? name : descriptor.getName().asString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultJsName == null && isEffectivelyExternalMember(descriptor)) {
|
if (defaultJsName == null && (isEffectivelyExternalMember(descriptor) || isExportedObject(descriptor, bindingContext))) {
|
||||||
return descriptor.getName().asString();
|
return descriptor.getName().asString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,6 +116,23 @@ public final class AnnotationsUtils {
|
|||||||
return descriptor.getAnnotations().findAnnotation(annotation.getFqName());
|
return descriptor.getAnnotations().findAnnotation(annotation.getFqName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isExportedObject(@NotNull DeclarationDescriptor descriptor, @NotNull BindingContext bindingContext) {
|
||||||
|
if (descriptor instanceof MemberDescriptor) {
|
||||||
|
MemberDescriptor memberDescriptor = (MemberDescriptor) descriptor;
|
||||||
|
if (memberDescriptor.getVisibility() != Visibilities.PUBLIC) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasAnnotationOrInsideAnnotatedClass(descriptor, JS_EXPORT)) return true;
|
||||||
|
|
||||||
|
if (CollectionsKt.any(getContainingFileAnnotations(bindingContext, descriptor), annotation ->
|
||||||
|
JS_EXPORT.equals(annotation.getFqName())
|
||||||
|
)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) {
|
public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) {
|
||||||
if (hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.NATIVE) || isEffectivelyExternalMember(descriptor)) return true;
|
if (hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.NATIVE) || isEffectivelyExternalMember(descriptor)) return true;
|
||||||
|
|
||||||
@@ -154,6 +175,11 @@ public final class AnnotationsUtils {
|
|||||||
return descriptor.getAnnotations().findAnnotation(new FqName(JS_NAME));
|
return descriptor.getAnnotations().findAnnotation(new FqName(JS_NAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static AnnotationDescriptor getJsExportAnnotation(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
return descriptor.getAnnotations().findAnnotation(JS_EXPORT);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isPredefinedObject(@NotNull DeclarationDescriptor descriptor) {
|
public static boolean isPredefinedObject(@NotNull DeclarationDescriptor descriptor) {
|
||||||
if (descriptor instanceof MemberDescriptor && ((MemberDescriptor) descriptor).isExpect()) return true;
|
if (descriptor instanceof MemberDescriptor && ((MemberDescriptor) descriptor).isExpect()) return true;
|
||||||
if (isEffectivelyExternalMember(descriptor)) return true;
|
if (isEffectivelyExternalMember(descriptor)) return true;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.js.translate.context.Namer
|
|||||||
import org.jetbrains.kotlin.js.translate.expression.InlineMetadata
|
import org.jetbrains.kotlin.js.translate.expression.InlineMetadata
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getModuleName
|
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getModuleName
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||||
import org.jetbrains.kotlin.utils.JsLibraryUtils
|
import org.jetbrains.kotlin.utils.JsLibraryUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -55,7 +56,8 @@ private val SPECIAL_FUNCTION_PATTERN = Regex("var\\s+($JS_IDENTIFIER)\\s*=\\s*($
|
|||||||
|
|
||||||
class FunctionReader(
|
class FunctionReader(
|
||||||
private val reporter: JsConfig.Reporter,
|
private val reporter: JsConfig.Reporter,
|
||||||
private val config: JsConfig
|
private val config: JsConfig,
|
||||||
|
private val bindingContext: BindingContext
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* fileContent: .js file content, that contains this module definition.
|
* fileContent: .js file content, that contains this module definition.
|
||||||
@@ -205,7 +207,7 @@ class FunctionReader(
|
|||||||
info: ModuleInfo,
|
info: ModuleInfo,
|
||||||
fragment: JsProgramFragment
|
fragment: JsProgramFragment
|
||||||
): FunctionWithWrapper {
|
): FunctionWithWrapper {
|
||||||
val tag = Namer.getFunctionTag(descriptor, config)
|
val tag = Namer.getFunctionTag(descriptor, config, bindingContext)
|
||||||
val moduleReference = fragment.inlineModuleMap[tag]?.deepCopy() ?: fragment.scope.declareName("_").makeRef()
|
val moduleReference = fragment.inlineModuleMap[tag]?.deepCopy() ?: fragment.scope.declareName("_").makeRef()
|
||||||
val allDefinedNames = collectDefinedNamesInAllScopes(fn.function)
|
val allDefinedNames = collectDefinedNamesInAllScopes(fn.function)
|
||||||
val replacements = hashMapOf(
|
val replacements = hashMapOf(
|
||||||
@@ -234,7 +236,7 @@ class FunctionReader(
|
|||||||
|
|
||||||
private fun readFunctionFromSource(descriptor: CallableDescriptor, info: ModuleInfo): FunctionWithWrapper? {
|
private fun readFunctionFromSource(descriptor: CallableDescriptor, info: ModuleInfo): FunctionWithWrapper? {
|
||||||
val source = info.fileContent
|
val source = info.fileContent
|
||||||
var tag = Namer.getFunctionTag(descriptor, config)
|
var tag = Namer.getFunctionTag(descriptor, config, bindingContext)
|
||||||
var index = source.indexOf(tag)
|
var index = source.indexOf(tag)
|
||||||
|
|
||||||
// Hack for compatibility with old versions of stdlib
|
// Hack for compatibility with old versions of stdlib
|
||||||
|
|||||||
@@ -13,11 +13,13 @@ import org.jetbrains.kotlin.js.inline.context.FunctionDefinitionLoader
|
|||||||
import org.jetbrains.kotlin.js.inline.context.InliningContext
|
import org.jetbrains.kotlin.js.inline.context.InliningContext
|
||||||
|
|
||||||
import org.jetbrains.kotlin.js.translate.general.AstGenerationResult
|
import org.jetbrains.kotlin.js.translate.general.AstGenerationResult
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class JsInliner(
|
class JsInliner(
|
||||||
val reporter: JsConfig.Reporter,
|
val reporter: JsConfig.Reporter,
|
||||||
val config: JsConfig,
|
val config: JsConfig,
|
||||||
val trace: DiagnosticSink,
|
val trace: DiagnosticSink,
|
||||||
|
val bindingContext: BindingContext,
|
||||||
val translationResult: AstGenerationResult
|
val translationResult: AstGenerationResult
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -75,7 +75,7 @@ class FunctionDefinitionLoader(
|
|||||||
return lookUpFunctionDirect(call, scope) ?: lookUpFunctionIndirect(call, scope) ?: lookUpFunctionExternal(call, scope.fragment)
|
return lookUpFunctionDirect(call, scope) ?: lookUpFunctionIndirect(call, scope) ?: lookUpFunctionExternal(call, scope.fragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val functionReader = FunctionReader(inliner.reporter, inliner.config)
|
private val functionReader = FunctionReader(inliner.reporter, inliner.config, inliner.bindingContext)
|
||||||
|
|
||||||
private data class FragmentInfo(
|
private data class FragmentInfo(
|
||||||
val functions: Map<JsName, FunctionWithWrapper>,
|
val functions: Map<JsName, FunctionWithWrapper>,
|
||||||
@@ -160,7 +160,7 @@ class FunctionDefinitionLoader(
|
|||||||
private fun lookUpFunctionDirect(call: JsInvocation, callsiteScope: InliningScope): InlineFunctionDefinition? {
|
private fun lookUpFunctionDirect(call: JsInvocation, callsiteScope: InliningScope): InlineFunctionDefinition? {
|
||||||
val descriptor = call.descriptor ?: return null
|
val descriptor = call.descriptor ?: return null
|
||||||
|
|
||||||
val tag = Namer.getFunctionTag(descriptor, inliner.config)
|
val tag = Namer.getFunctionTag(descriptor, inliner.config, inliner.bindingContext)
|
||||||
|
|
||||||
val definitionFragment = fragmentByTag(tag) ?: return null
|
val definitionFragment = fragmentByTag(tag) ?: return null
|
||||||
|
|
||||||
@@ -178,7 +178,7 @@ class FunctionDefinitionLoader(
|
|||||||
private fun lookUpFunctionExternal(call: JsInvocation, fragment: JsProgramFragment): InlineFunctionDefinition? =
|
private fun lookUpFunctionExternal(call: JsInvocation, fragment: JsProgramFragment): InlineFunctionDefinition? =
|
||||||
call.descriptor?.let { descriptor ->
|
call.descriptor?.let { descriptor ->
|
||||||
functionReader[descriptor, fragment]?.let {
|
functionReader[descriptor, fragment]?.let {
|
||||||
InlineFunctionDefinition(it, Namer.getFunctionTag(descriptor, inliner.config))
|
InlineFunctionDefinition(it, Namer.getFunctionTag(descriptor, inliner.config, inliner.bindingContext))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ fun main(args: Array<String>) {
|
|||||||
model("typescript-export/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR)
|
model("typescript-export/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractLegacyJsTypeScriptExportTest> {
|
||||||
|
model("typescript-export/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
testClass<AbstractSourceMapGenerationSmokeTest> {
|
testClass<AbstractSourceMapGenerationSmokeTest> {
|
||||||
model("sourcemap/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
|
model("sourcemap/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
|
||||||
}
|
}
|
||||||
|
|||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.js.test.semantics
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.js.test.BasicBoxTest
|
||||||
|
|
||||||
|
abstract class AbstractLegacyJsTypeScriptExportTest : BasicBoxTest(
|
||||||
|
pathToTestDir = TEST_DATA_DIR_PATH + "typescript-export/",
|
||||||
|
testGroupOutputDirPrefix = "legacy-typescript-export/",
|
||||||
|
pathToRootOutputDir = TEST_DATA_DIR_PATH
|
||||||
|
)
|
||||||
Generated
+139
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.js.test.semantics;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||||
|
import org.jetbrains.kotlin.test.TargetBackend;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("js/js.translator/testData/typescript-export")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public class LegacyJsTypeScriptExportTestGenerated extends AbstractLegacyJsTypeScriptExportTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInTypescript_export() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/typescript-export/declarations")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Declarations extends AbstractLegacyJsTypeScriptExportTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInDeclarations() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/declarations"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("declarations.kt")
|
||||||
|
public void testDeclarations() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/typescript-export/declarations/declarations.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/typescript-export/inheritance")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Inheritance extends AbstractLegacyJsTypeScriptExportTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInInheritance() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/inheritance"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inheritance.kt")
|
||||||
|
public void testInheritance() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/typescript-export/inheritance/inheritance.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/typescript-export/namespaces")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Namespaces extends AbstractLegacyJsTypeScriptExportTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNamespaces() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/namespaces"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("namespaces.kt")
|
||||||
|
public void testNamespaces() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/typescript-export/namespaces/namespaces.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/typescript-export/primitives")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Primitives extends AbstractLegacyJsTypeScriptExportTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInPrimitives() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/primitives"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("primitives.kt")
|
||||||
|
public void testPrimitives() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/typescript-export/primitives/primitives.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/typescript-export/selectiveExport")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class SelectiveExport extends AbstractLegacyJsTypeScriptExportTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInSelectiveExport() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/selectiveExport"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("selectiveExport.kt")
|
||||||
|
public void testSelectiveExport() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/typescript-export/selectiveExport/selectiveExport.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js/js.translator/testData/typescript-export/visibility")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Visibility extends AbstractLegacyJsTypeScriptExportTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInVisibility() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/visibility"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("visibility.kt")
|
||||||
|
public void testVisibility() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/typescript-export/visibility/visibility.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -167,6 +167,7 @@ class K2JSTranslator @JvmOverloads constructor(
|
|||||||
reporter,
|
reporter,
|
||||||
config,
|
config,
|
||||||
analysisResult.bindingTrace,
|
analysisResult.bindingTrace,
|
||||||
|
bindingTrace.bindingContext,
|
||||||
translationResult
|
translationResult
|
||||||
).process()
|
).process()
|
||||||
if (hasError(diagnostics)) return TranslationResult.Fail(diagnostics)
|
if (hasError(diagnostics)) return TranslationResult.Fail(diagnostics)
|
||||||
|
|||||||
@@ -34,12 +34,12 @@ import org.jetbrains.kotlin.js.backend.ast.metadata.TypeCheck;
|
|||||||
import org.jetbrains.kotlin.js.config.JsConfig;
|
import org.jetbrains.kotlin.js.config.JsConfig;
|
||||||
import org.jetbrains.kotlin.js.naming.NameSuggestion;
|
import org.jetbrains.kotlin.js.naming.NameSuggestion;
|
||||||
import org.jetbrains.kotlin.js.naming.SuggestedName;
|
import org.jetbrains.kotlin.js.naming.SuggestedName;
|
||||||
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices;
|
|
||||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.ArrayFIF;
|
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.ArrayFIF;
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils;
|
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils;
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -57,8 +57,8 @@ public final class Namer {
|
|||||||
public static final String KOTLIN_NAME = KotlinLanguage.NAME;
|
public static final String KOTLIN_NAME = KotlinLanguage.NAME;
|
||||||
public static final String KOTLIN_LOWER_NAME = KOTLIN_NAME.toLowerCase();
|
public static final String KOTLIN_LOWER_NAME = KOTLIN_NAME.toLowerCase();
|
||||||
|
|
||||||
public static final String EQUALS_METHOD_NAME = getStableMangledNameForDescriptor(JsPlatformAnalyzerServices.INSTANCE.getBuiltIns().getAny(), "equals");
|
public static final String EQUALS_METHOD_NAME = "equals";
|
||||||
public static final String COMPARE_TO_METHOD_NAME = getStableMangledNameForDescriptor(JsPlatformAnalyzerServices.INSTANCE.getBuiltIns().getComparable(), "compareTo");
|
public static final String COMPARE_TO_METHOD_NAME = "compareTo_11rb$";
|
||||||
public static final String LONG_FROM_NUMBER = "fromNumber";
|
public static final String LONG_FROM_NUMBER = "fromNumber";
|
||||||
public static final String LONG_TO_NUMBER = "toNumber";
|
public static final String LONG_TO_NUMBER = "toNumber";
|
||||||
public static final String LONG_FROM_INT = "fromInt";
|
public static final String LONG_FROM_INT = "fromInt";
|
||||||
@@ -134,7 +134,11 @@ public final class Namer {
|
|||||||
public static final String SAM_FIELD_NAME = "function$";
|
public static final String SAM_FIELD_NAME = "function$";
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String getFunctionTag(@NotNull CallableDescriptor functionDescriptor, @NotNull JsConfig config) {
|
public static String getFunctionTag(
|
||||||
|
@NotNull CallableDescriptor functionDescriptor,
|
||||||
|
@NotNull JsConfig config,
|
||||||
|
@NotNull BindingContext bindingContext
|
||||||
|
) {
|
||||||
String intrinsicTag = ArrayFIF.INSTANCE.getTag(functionDescriptor, config);
|
String intrinsicTag = ArrayFIF.INSTANCE.getTag(functionDescriptor, config);
|
||||||
if (intrinsicTag != null) return intrinsicTag;
|
if (intrinsicTag != null) return intrinsicTag;
|
||||||
|
|
||||||
@@ -147,7 +151,7 @@ public final class Namer {
|
|||||||
qualifier = fqNameParent.asString();
|
qualifier = fqNameParent.asString();
|
||||||
}
|
}
|
||||||
|
|
||||||
SuggestedName suggestedName = new NameSuggestion().suggest(functionDescriptor);
|
SuggestedName suggestedName = new NameSuggestion(bindingContext).suggest(functionDescriptor);
|
||||||
assert suggestedName != null : "Suggested name can be null only for module descriptors: " + functionDescriptor;
|
assert suggestedName != null : "Suggested name can be null only for module descriptors: " + functionDescriptor;
|
||||||
String mangledName = suggestedName.getNames().get(0);
|
String mangledName = suggestedName.getNames().get(0);
|
||||||
return StringUtil.join(Arrays.asList(moduleName, qualifier, mangledName), ".");
|
return StringUtil.join(Arrays.asList(moduleName, qualifier, mangledName), ".");
|
||||||
@@ -225,18 +229,6 @@ public final class Namer {
|
|||||||
callSetProperty = kotlin("callSetter");
|
callSetProperty = kotlin("callSetter");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get rid of this function
|
|
||||||
@NotNull
|
|
||||||
private static String getStableMangledNameForDescriptor(@NotNull ClassDescriptor descriptor, @NotNull String functionName) {
|
|
||||||
Collection<? extends SimpleFunctionDescriptor> functions = descriptor.getDefaultType().getMemberScope().getContributedFunctions(
|
|
||||||
Name.identifier(functionName), NoLookupLocation.FROM_BACKEND
|
|
||||||
);
|
|
||||||
assert functions.size() == 1 : "Can't select a single function: " + functionName + " in " + descriptor;
|
|
||||||
SuggestedName suggested = new NameSuggestion().suggest(functions.iterator().next());
|
|
||||||
assert suggested != null : "Suggested name for class members is always non-null: " + functions.iterator().next();
|
|
||||||
return suggested.getNames().get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsNameRef kotlin(@NotNull JsName name) {
|
public static JsNameRef kotlin(@NotNull JsName name) {
|
||||||
return pureFqn(name, kotlinObject());
|
return pureFqn(name, kotlinObject());
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public final class StaticContext {
|
|||||||
private final JsImportedModule currentModuleAsImported;
|
private final JsImportedModule currentModuleAsImported;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final NameSuggestion nameSuggestion = new NameSuggestion();
|
private final NameSuggestion nameSuggestion;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Map<DeclarationDescriptor, JsName> nameCache = new HashMap<>();
|
private final Map<DeclarationDescriptor, JsName> nameCache = new HashMap<>();
|
||||||
@@ -169,6 +169,7 @@ public final class StaticContext {
|
|||||||
fragment = new JsProgramFragment(rootFunction.getScope(), packageFqn);
|
fragment = new JsProgramFragment(rootFunction.getScope(), packageFqn);
|
||||||
|
|
||||||
this.bindingTrace = bindingTrace;
|
this.bindingTrace = bindingTrace;
|
||||||
|
this.nameSuggestion = new NameSuggestion(bindingTrace.getBindingContext());
|
||||||
this.namer = Namer.newInstance(program.getRootScope());
|
this.namer = Namer.newInstance(program.getRootScope());
|
||||||
this.intrinsics = new Intrinsics();
|
this.intrinsics = new Intrinsics();
|
||||||
this.rootScope = fragment.getScope();
|
this.rootScope = fragment.getScope();
|
||||||
@@ -801,7 +802,7 @@ public final class StaticContext {
|
|||||||
|
|
||||||
public void addInlineCall(@NotNull CallableDescriptor descriptor) {
|
public void addInlineCall(@NotNull CallableDescriptor descriptor) {
|
||||||
descriptor = (CallableDescriptor) JsDescriptorUtils.findRealInlineDeclaration(descriptor);
|
descriptor = (CallableDescriptor) JsDescriptorUtils.findRealInlineDeclaration(descriptor);
|
||||||
String tag = Namer.getFunctionTag(descriptor, config);
|
String tag = Namer.getFunctionTag(descriptor, config, getBindingContext());
|
||||||
JsExpression moduleExpression = exportModuleForInline(DescriptorUtils.getContainingModule(descriptor));
|
JsExpression moduleExpression = exportModuleForInline(DescriptorUtils.getContainingModule(descriptor));
|
||||||
if (moduleExpression == null) {
|
if (moduleExpression == null) {
|
||||||
moduleExpression = getModuleExpressionFor(descriptor);
|
moduleExpression = getModuleExpressionFor(descriptor);
|
||||||
|
|||||||
+2
-2
@@ -179,13 +179,13 @@ public class TranslationContext {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public TranslationContext newFunctionBodyWithUsageTracker(@NotNull JsFunction fun, @NotNull MemberDescriptor descriptor) {
|
public TranslationContext newFunctionBodyWithUsageTracker(@NotNull JsFunction fun, @NotNull MemberDescriptor descriptor) {
|
||||||
DynamicContext dynamicContext = DynamicContext.newContext(fun.getScope(), fun.getBody());
|
DynamicContext dynamicContext = DynamicContext.newContext(fun.getScope(), fun.getBody());
|
||||||
UsageTracker usageTracker = new UsageTracker(this.usageTracker, descriptor);
|
UsageTracker usageTracker = new UsageTracker(this.usageTracker, descriptor, bindingContext());
|
||||||
return new TranslationContext(this, this.staticContext, dynamicContext, this.aliasingContext.inner(), usageTracker, descriptor);
|
return new TranslationContext(this, this.staticContext, dynamicContext, this.aliasingContext.inner(), usageTracker, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public TranslationContext innerWithUsageTracker(@NotNull MemberDescriptor descriptor) {
|
public TranslationContext innerWithUsageTracker(@NotNull MemberDescriptor descriptor) {
|
||||||
UsageTracker usageTracker = new UsageTracker(this.usageTracker, descriptor);
|
UsageTracker usageTracker = new UsageTracker(this.usageTracker, descriptor, bindingContext());
|
||||||
return new TranslationContext(this, staticContext, dynamicContext, aliasingContext.inner(), usageTracker, descriptor);
|
return new TranslationContext(this, staticContext, dynamicContext, aliasingContext.inner(), usageTracker, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.js.backend.ast.JsScope
|
|||||||
import org.jetbrains.kotlin.js.backend.ast.metadata.descriptor
|
import org.jetbrains.kotlin.js.backend.ast.metadata.descriptor
|
||||||
import org.jetbrains.kotlin.js.descriptorUtils.isCoroutineLambda
|
import org.jetbrains.kotlin.js.descriptorUtils.isCoroutineLambda
|
||||||
import org.jetbrains.kotlin.js.naming.NameSuggestion
|
import org.jetbrains.kotlin.js.naming.NameSuggestion
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.*
|
import org.jetbrains.kotlin.resolve.DescriptorUtils.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||||
@@ -30,7 +31,8 @@ private val CAPTURED_RECEIVER_NAME_PREFIX : String = "this$"
|
|||||||
|
|
||||||
class UsageTracker(
|
class UsageTracker(
|
||||||
private val parent: UsageTracker?,
|
private val parent: UsageTracker?,
|
||||||
val containingDescriptor: MemberDescriptor
|
val containingDescriptor: MemberDescriptor,
|
||||||
|
val bindingContext: BindingContext
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val captured = linkedMapOf<DeclarationDescriptor, JsName>()
|
private val captured = linkedMapOf<DeclarationDescriptor, JsName>()
|
||||||
@@ -175,7 +177,7 @@ class UsageTracker(
|
|||||||
|
|
||||||
// Append 'closure$' prefix to avoid name clash between closure and member fields in case of local classes
|
// Append 'closure$' prefix to avoid name clash between closure and member fields in case of local classes
|
||||||
else -> {
|
else -> {
|
||||||
val mangled = NameSuggestion.sanitizeName(NameSuggestion().suggest(this)!!.names.last())
|
val mangled = NameSuggestion.sanitizeName(NameSuggestion(bindingContext).suggest(this)!!.names.last())
|
||||||
"closure\$$mangled"
|
"closure\$$mangled"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class InlineMetadata(val tag: JsStringLiteral, val function: FunctionWithWrapper
|
|||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun compose(function: JsFunction, descriptor: CallableDescriptor, context: TranslationContext): InlineMetadata {
|
fun compose(function: JsFunction, descriptor: CallableDescriptor, context: TranslationContext): InlineMetadata {
|
||||||
val tag = JsStringLiteral(Namer.getFunctionTag(descriptor, context.config))
|
val tag = JsStringLiteral(Namer.getFunctionTag(descriptor, context.config, context.bindingContext()))
|
||||||
val inliningContext = context.inlineFunctionContext!!
|
val inliningContext = context.inlineFunctionContext!!
|
||||||
val block = JsBlock(inliningContext.importBlock.statements + inliningContext.prototypeBlock.statements +
|
val block = JsBlock(inliningContext.importBlock.statements + inliningContext.prototypeBlock.statements +
|
||||||
inliningContext.declarationsBlock.statements + JsReturn(function))
|
inliningContext.declarationsBlock.statements + JsReturn(function))
|
||||||
|
|||||||
+3
-4
@@ -1,16 +1,15 @@
|
|||||||
// SKIP_MINIFICATION
|
// SKIP_MINIFICATION
|
||||||
|
|
||||||
|
// Exported declaration uses non-exportable return type: Char
|
||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|
||||||
@JsName("foo")
|
@JsName("foo")
|
||||||
@JsExport
|
|
||||||
fun foo(): Char = '1'
|
fun foo(): Char = '1'
|
||||||
|
|
||||||
@JsExport
|
|
||||||
val p1: Char = '2'
|
val p1: Char = '2'
|
||||||
|
|
||||||
@JsExport
|
|
||||||
var p2: Char = '3'
|
var p2: Char = '3'
|
||||||
|
|
||||||
@JsExport
|
|
||||||
var p3: Char = '4'
|
var p3: Char = '4'
|
||||||
get() = field + 1
|
get() = field + 1
|
||||||
set(value) {
|
set(value) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1276
|
// EXPECTED_REACHABLE_NODES: 1276
|
||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|
||||||
@JsExport
|
|
||||||
class A(val x: Char)
|
class A(val x: Char)
|
||||||
|
|
||||||
fun typeOf(x: dynamic): String = js("typeof x")
|
fun typeOf(x: dynamic): String = js("typeof x")
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ interface I {
|
|||||||
val a: Char
|
val a: Char
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsExport
|
|
||||||
object X : I {
|
object X : I {
|
||||||
override var a = '#'
|
override var a = '#'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1289
|
// EXPECTED_REACHABLE_NODES: 1289
|
||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|
||||||
@JsExport
|
|
||||||
open class A {
|
open class A {
|
||||||
val foo: Char
|
val foo: Char
|
||||||
get() = 'X'
|
get() = 'X'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1282
|
// EXPECTED_REACHABLE_NODES: 1282
|
||||||
|
|
||||||
|
@JsExport
|
||||||
interface I {
|
interface I {
|
||||||
fun ok(): String
|
fun ok(): String
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ class A {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsExport
|
|
||||||
val A.z: Int
|
val A.z: Int
|
||||||
@JsName("getZ_") get() = 42
|
@JsName("getZ_") get() = 42
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// TARGET_BACKEND: JS_IR
|
|
||||||
// CHECK_TYPESCRIPT_DECLARATIONS
|
// CHECK_TYPESCRIPT_DECLARATIONS
|
||||||
// RUN_PLAIN_BOX_FUNCTION
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
// SKIP_NODE_JS
|
||||||
|
|
||||||
@file:JsExport
|
@file:JsExport
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// TARGET_BACKEND: JS_IR
|
|
||||||
// CHECK_TYPESCRIPT_DECLARATIONS
|
// CHECK_TYPESCRIPT_DECLARATIONS
|
||||||
// RUN_PLAIN_BOX_FUNCTION
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
// SKIP_NODE_JS
|
||||||
|
|
||||||
@file:JsExport
|
@file:JsExport
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// TARGET_BACKEND: JS_IR
|
|
||||||
// CHECK_TYPESCRIPT_DECLARATIONS
|
// CHECK_TYPESCRIPT_DECLARATIONS
|
||||||
// RUN_PLAIN_BOX_FUNCTION
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
// SKIP_NODE_JS
|
||||||
|
|
||||||
// FILE: file1.kt
|
// FILE: file1.kt
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ declare namespace JS_TESTS {
|
|||||||
type Nullable<T> = T | null | undefined
|
type Nullable<T> = T | null | undefined
|
||||||
namespace foo {
|
namespace foo {
|
||||||
const _any: any;
|
const _any: any;
|
||||||
const _unit: void;
|
|
||||||
function _nothing(): never
|
function _nothing(): never
|
||||||
const _throwable: Error;
|
const _throwable: Error;
|
||||||
const _string: string;
|
const _string: string;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// TARGET_BACKEND: JS_IR
|
|
||||||
// CHECK_TYPESCRIPT_DECLARATIONS
|
// CHECK_TYPESCRIPT_DECLARATIONS
|
||||||
// RUN_PLAIN_BOX_FUNCTION
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
// SKIP_NODE_JS
|
||||||
|
|
||||||
@file:JsExport
|
@file:JsExport
|
||||||
|
|
||||||
@@ -8,8 +9,6 @@ package foo
|
|||||||
|
|
||||||
val _any: Any = Any()
|
val _any: Any = Any()
|
||||||
|
|
||||||
val _unit: Unit = Unit
|
|
||||||
|
|
||||||
fun _nothing(): Nothing { throw Throwable() }
|
fun _nothing(): Nothing { throw Throwable() }
|
||||||
|
|
||||||
val _throwable: Throwable = Throwable()
|
val _throwable: Throwable = Throwable()
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
// TARGET_BACKEND: JS_IR
|
|
||||||
// CHECK_TYPESCRIPT_DECLARATIONS
|
// CHECK_TYPESCRIPT_DECLARATIONS
|
||||||
// RUN_PLAIN_BOX_FUNCTION
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
// SKIP_NODE_JS
|
||||||
|
|
||||||
// FILE: file1.kt
|
// FILE: file1.kt
|
||||||
package foo
|
package foo
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// TARGET_BACKEND: JS_IR
|
|
||||||
// CHECK_TYPESCRIPT_DECLARATIONS
|
// CHECK_TYPESCRIPT_DECLARATIONS
|
||||||
// RUN_PLAIN_BOX_FUNCTION
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
// SKIP_NODE_JS
|
||||||
|
|
||||||
// TODO fix statics export in DCE-driven mode
|
// TODO fix statics export in DCE-driven mode
|
||||||
// SKIP_DCE_DRIVEN
|
// SKIP_DCE_DRIVEN
|
||||||
|
|||||||
@@ -32,12 +32,33 @@ public expect annotation class JsName(val name: String)
|
|||||||
public annotation class ExperimentalJsExport
|
public annotation class ExperimentalJsExport
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports top-level declaration.
|
* Exports top-level declaration on JS platform.
|
||||||
*
|
*
|
||||||
* Compiler exports from the module those top-level declarations that are marked with this annotation.
|
* Compiled module exposes declarations that are marked with this annotation without name mangling.
|
||||||
* There is no effect if this annotation is applied to a non-top-level declaration.
|
|
||||||
*
|
*
|
||||||
* This annotation has effect only on top-level declarations and only in IR-based JS backend.
|
* This annotation can be applied to either files or top-level declarations.
|
||||||
|
*
|
||||||
|
* It is currently prohibited to export the following kinds of declarations:
|
||||||
|
*
|
||||||
|
* * `expect` declarations
|
||||||
|
* * inline functions with reified type parameters
|
||||||
|
* * suspend functions
|
||||||
|
* * secondary constructors without `@JsName`
|
||||||
|
* * extension properties
|
||||||
|
* * enum classes
|
||||||
|
* * annotation classes
|
||||||
|
*
|
||||||
|
* Signatures of exported declarations must only contain "exportable" types:
|
||||||
|
*
|
||||||
|
* * `dynamic`, `Any`, `String`, `Boolean`, `Byte`, `Short`, `Int`, `Float`, `Double`
|
||||||
|
* * `BooleanArray`, `ByteArray`, `ShortArray`, `IntArray`, `FloatArray`, `DoubleArray`
|
||||||
|
* * `Array<exportable-type>`
|
||||||
|
* * Function types with exportable parameters and return types
|
||||||
|
* * `external` or `@JsExport` classes and interfaces
|
||||||
|
* * Nullable counterparts of types above
|
||||||
|
* * Unit return type. Must not be nullable
|
||||||
|
*
|
||||||
|
* This annotation is experimental, meaning that restrictions mentioned above are subject to change.
|
||||||
*/
|
*/
|
||||||
@ExperimentalJsExport
|
@ExperimentalJsExport
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
|||||||
@@ -162,12 +162,33 @@ public annotation class JsNonModule
|
|||||||
public annotation class JsQualifier(val value: String)
|
public annotation class JsQualifier(val value: String)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports top-level declaration.
|
* Exports top-level declaration on JS platform.
|
||||||
*
|
*
|
||||||
* Compiler exports from the module those top-level declarations that are marked with this annotation.
|
* Compiled module exposes declarations that are marked with this annotation without name mangling.
|
||||||
* There is no effect if this annotation is applied to a non-top-level declaration.
|
|
||||||
*
|
*
|
||||||
* This annotation has effect only on top-level declarations and only in IR-based JS backend.
|
* This annotation can be applied to either files or top-level declarations.
|
||||||
|
*
|
||||||
|
* It is currently prohibited to export the following kinds of declarations:
|
||||||
|
*
|
||||||
|
* * `expect` declarations
|
||||||
|
* * inline functions with reified type parameters
|
||||||
|
* * suspend functions
|
||||||
|
* * secondary constructors without `@JsName`
|
||||||
|
* * extension properties
|
||||||
|
* * enum classes
|
||||||
|
* * annotation classes
|
||||||
|
*
|
||||||
|
* Signatures of exported declarations must only contain "exportable" types:
|
||||||
|
*
|
||||||
|
* * `dynamic`, `Any`, `String`, `Boolean`, `Byte`, `Short`, `Int`, `Float`, `Double`
|
||||||
|
* * `BooleanArray`, `ByteArray`, `ShortArray`, `IntArray`, `FloatArray`, `DoubleArray`
|
||||||
|
* * `Array<exportable-type>`
|
||||||
|
* * Function types with exportable parameters and return types
|
||||||
|
* * `external` or `@JsExport` classes and interfaces
|
||||||
|
* * Nullable counterparts of types above
|
||||||
|
* * Unit return type. Must not be nullable
|
||||||
|
*
|
||||||
|
* This annotation is experimental, meaning that restrictions mentioned above are subject to change.
|
||||||
*/
|
*/
|
||||||
@ExperimentalJsExport
|
@ExperimentalJsExport
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
|||||||
Reference in New Issue
Block a user