From ecb498717a171cac8af690c59cdcf774f69f6b9a Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 28 Nov 2016 17:09:47 +0300 Subject: [PATCH] JS: rework diagnostics names. Prohibit external inner classes (see KT-14027) --- .../native/extensionFunctionAndProperty.kt | 10 ++--- .../testsWithJsStdLib/native/innerClass.kt | 9 +++++ .../testsWithJsStdLib/native/innerClass.txt | 39 +++++++++++++++++++ .../native/privateMembers.kt | 31 +++++++++------ .../native/privateMembers.txt | 8 ++++ .../testsWithJsStdLib/native/wrongTarget.kt | 10 ++--- .../DiagnosticsTestWithJsStdLibGenerated.java | 6 +++ .../diagnostics/DefaultErrorMessagesJs.kt | 4 +- .../js/resolve/diagnostics/ErrorsJs.java | 2 +- .../resolve/diagnostics/JsExternalChecker.kt | 13 ++++--- js/js.libraries/src/builtins/hacks.kt | 2 +- .../testData/box/native/nestedElements.kt | 12 +----- .../testData/box/nestedTypes/outerNative.kt | 10 ----- 13 files changed, 104 insertions(+), 52 deletions(-) create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/innerClass.kt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/innerClass.txt diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/extensionFunctionAndProperty.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/extensionFunctionAndProperty.kt index c36054ff069..58de281fa11 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/native/extensionFunctionAndProperty.kt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/extensionFunctionAndProperty.kt @@ -1,10 +1,10 @@ class A -external fun A.foo(): Unit = noImpl +external fun A.foo(): Unit = noImpl -external var A.bar: String +external var A.bar: String get() = noImpl - set(value) = noImpl + set(value) = noImpl -external val A.baz: String - get() = noImpl \ No newline at end of file +external val A.baz: String + get() = noImpl \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/innerClass.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/innerClass.kt new file mode 100644 index 00000000000..021c3a2fe82 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/innerClass.kt @@ -0,0 +1,9 @@ +external class C { + inner class Inner +} + +external enum class E { + X; + + inner class Inner +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/innerClass.txt b/compiler/testData/diagnostics/testsWithJsStdLib/native/innerClass.txt new file mode 100644 index 00000000000..2e1c1ee129b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/innerClass.txt @@ -0,0 +1,39 @@ +package + +public external 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 + + public final inner class Inner { + public constructor Inner() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public external final enum class E : kotlin.Enum { + enum entry X + + private constructor E() + 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: E): 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 + + public final inner class Inner { + public constructor Inner() + 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 + } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): E + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/privateMembers.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/privateMembers.kt index e6701d0602e..504c67f003c 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/native/privateMembers.kt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/privateMembers.kt @@ -1,17 +1,22 @@ // !DIAGNOSTICS: -NOTHING_TO_INLINE // TODO: should we disable NOTHING_TO_INLINE in JS backend? +// TODO: uncomment declarations in case we decide to implement KT-14031 external class C { - private fun a(): Int + private fun a(): Int - private val b: String + private val b: String - private var c: Float + private var c: Float - private var d: Float + private var d: Float get set + var e: Float + get + private set + private inline fun inline_a(): Int = 23 private inline val inline_prop: Int @@ -19,13 +24,13 @@ external class C { } external object O { - private fun a(): Int + private fun a(): Int - private val b: String + private val b: String - private var c: Float + private var c: Float - private var d: Float + private var d: Float get set @@ -37,13 +42,13 @@ external object O { external class Outer { class Inner { - private fun a(): Int + private fun a(): Int - private val b: String + private val b: String - private var c: Float + private var c: Float - private var d: Float + private var d: Float get set @@ -52,4 +57,6 @@ external class Outer { private inline val inline_prop: Int get() = 42 } + + private class PrivateInner } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/privateMembers.txt b/compiler/testData/diagnostics/testsWithJsStdLib/native/privateMembers.txt index 67a13a760c4..c48a5e50c03 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/native/privateMembers.txt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/privateMembers.txt @@ -5,6 +5,7 @@ public final class C { private final val b: kotlin.String private final var c: kotlin.Float private final var d: kotlin.Float + public final var e: kotlin.Float private final val inline_prop: kotlin.Int private final fun a(): kotlin.Int public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean @@ -44,4 +45,11 @@ public final class Outer { private final inline fun inline_a(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } + + private final class PrivateInner { + public constructor PrivateInner() + 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 + } } diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/wrongTarget.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/wrongTarget.kt index 21306d94020..cfc40b9e737 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/native/wrongTarget.kt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/wrongTarget.kt @@ -1,19 +1,19 @@ -external annotation class A +external annotation class A val x: Int - external get() = noImpl + external get() = noImpl class B val B.x: Int - external get() = noImpl + external get() = noImpl class C { val a: Int - external get() = noImpl + external get() = noImpl } external class D { val a: Int - external get() = noImpl + external get() = noImpl } \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJsStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJsStdLibGenerated.java index 63f1616cf7d..696da523ef3 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJsStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJsStdLibGenerated.java @@ -533,6 +533,12 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes doTest(fileName); } + @TestMetadata("innerClass.kt") + public void testInnerClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/innerClass.kt"); + doTest(fileName); + } + @TestMetadata("nested.kt") public void testNested() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/nested.kt"); diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/DefaultErrorMessagesJs.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/DefaultErrorMessagesJs.kt index 645d7906aa4..2a742b6cf83 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/DefaultErrorMessagesJs.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/DefaultErrorMessagesJs.kt @@ -38,7 +38,7 @@ private val DIAGNOSTIC_FACTORY_TO_RENDERER by lazy { put(ErrorsJs.REFERENCE_TO_BUILTIN_MEMBERS_NOT_SUPPORTED, "Callable references for builtin members are not supported yet: ''{0}''", RenderFirstLineOfElementText) put(ErrorsJs.JSCODE_NO_JAVASCRIPT_PRODUCED, "Argument must be non-empty JavaScript code") put(ErrorsJs.NESTED_EXTERNAL_DECLARATION, "Non top-level `external` declaration") - put(ErrorsJs.EXTERNAL_CLASS_PRIVATE_MEMBER, "Private non-inline members of external classes are prohibited") + put(ErrorsJs.WRONG_EXTERNAL_DECLARATION, "Declaration of such kind ({0}) can't be external", Renderers.STRING) put(ErrorsJs.JS_NAME_CLASH, "JavaScript name ({0}) generated for this declaration clashes with another declaration: {1}", Renderers.STRING, Renderers.COMPACT) put(ErrorsJs.JS_FAKE_NAME_CLASH, "JavaScript name {0} is generated for different inherited members: {1} and {2}", @@ -48,7 +48,7 @@ private val DIAGNOSTIC_FACTORY_TO_RENDERER by lazy { put(ErrorsJs.JS_NAME_IS_NOT_ON_ALL_ACCESSORS, "@JsName should be on all of the property accessors") put(ErrorsJs.JS_NAME_PROHIBITED_FOR_OVERRIDE, "@JsName is prohibited for overridden members") put(ErrorsJs.JS_NAME_PROHIBITED_FOR_EXTENSION_PROPERTY, "@JsName is prohibited for extension properties") - put(ErrorsJs.JS_NAME_PROHIBITED_FOR_NAMED_NATIVE, "@JsName is prohibited for @native declaration with explicit name") + put(ErrorsJs.JS_NAME_PROHIBITED_FOR_NAMED_NATIVE, "@JsName is prohibited for external declaration with explicit name") put(ErrorsJs.JS_MODULE_PROHIBITED_ON_VAR, "@JsModule and @JsNonModule annotations prohibited for 'var' declarations. " + "Use 'val' instead.") put(ErrorsJs.JS_MODULE_PROHIBITED_ON_NON_NATIVE, "@JsModule and @JsNonModule annotations prohibited for non-external declarations.") diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/ErrorsJs.java b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/ErrorsJs.java index b6797e85b7f..ca83ad072e2 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/ErrorsJs.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/ErrorsJs.java @@ -41,7 +41,7 @@ public interface ErrorsJs { DiagnosticFactory1 NOT_SUPPORTED = DiagnosticFactory1.create(ERROR, DEFAULT); DiagnosticFactory1 REFERENCE_TO_BUILTIN_MEMBERS_NOT_SUPPORTED = DiagnosticFactory1.create(ERROR, DEFAULT); DiagnosticFactory0 JSCODE_NO_JAVASCRIPT_PRODUCED = DiagnosticFactory0.create(ERROR, DEFAULT); - DiagnosticFactory0 EXTERNAL_CLASS_PRIVATE_MEMBER = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); + DiagnosticFactory1 WRONG_EXTERNAL_DECLARATION = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); DiagnosticFactory0 NESTED_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); DiagnosticFactory2 JS_NAME_CLASH = DiagnosticFactory2.create( ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsExternalChecker.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsExternalChecker.kt index a753dcb8a6c..947d2e62146 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsExternalChecker.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsExternalChecker.kt @@ -41,13 +41,16 @@ class JsExternalChecker : SimpleDeclarationChecker { } if (DescriptorUtils.isAnnotationClass(descriptor)) { - diagnosticHolder.report(Errors.WRONG_MODIFIER_TARGET.on(declaration, KtTokens.EXTERNAL_KEYWORD, "annotation class")) + diagnosticHolder.report(ErrorsJs.WRONG_EXTERNAL_DECLARATION.on(declaration, "annotation class")) } else if (descriptor is PropertyAccessorDescriptor && isDirectlyExternal(declaration, descriptor)) { - diagnosticHolder.report(Errors.WRONG_MODIFIER_TARGET.on(declaration, KtTokens.EXTERNAL_KEYWORD, "property accessor")) + diagnosticHolder.report(ErrorsJs.WRONG_EXTERNAL_DECLARATION.on(declaration, "property accessor")) + } + else if (descriptor is ClassDescriptor && descriptor.isInner) { + diagnosticHolder.report(ErrorsJs.WRONG_EXTERNAL_DECLARATION.on(declaration, "inner class")) } else if (isPrivateNonInlineMemberOfExternalClass(descriptor)) { - diagnosticHolder.report(ErrorsJs.EXTERNAL_CLASS_PRIVATE_MEMBER.on(declaration)) + diagnosticHolder.report(ErrorsJs.WRONG_EXTERNAL_DECLARATION.on(declaration, "private member of class")) } if (descriptor !is PropertyAccessorDescriptor && descriptor.isExtension) { @@ -56,7 +59,7 @@ class JsExternalChecker : SimpleDeclarationChecker { is PropertyDescriptor -> "extension property" else -> "extension member" } - diagnosticHolder.report(Errors.WRONG_MODIFIER_TARGET.on(declaration, KtTokens.EXTERNAL_KEYWORD, target)) + diagnosticHolder.report(ErrorsJs.WRONG_EXTERNAL_DECLARATION.on(declaration, target)) } } @@ -68,7 +71,7 @@ class JsExternalChecker : SimpleDeclarationChecker { } private fun isPrivateNonInlineMemberOfExternalClass(descriptor: DeclarationDescriptor): Boolean { - if (descriptor is PropertyAccessorDescriptor) return false + if (descriptor is PropertyAccessorDescriptor && descriptor.visibility == descriptor.correspondingProperty.visibility) return false if (descriptor !is MemberDescriptor || descriptor.visibility != Visibilities.PRIVATE) return false if (descriptor is FunctionDescriptor && descriptor.isInline) return false if (descriptor is PropertyDescriptor && descriptor.accessors.all { it.isInline }) return false diff --git a/js/js.libraries/src/builtins/hacks.kt b/js/js.libraries/src/builtins/hacks.kt index 31d7f8a346a..f2764d4205f 100644 --- a/js/js.libraries/src/builtins/hacks.kt +++ b/js/js.libraries/src/builtins/hacks.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -@file:Suppress("WRONG_MODIFIER_TARGET") +@file:Suppress("WRONG_EXTERNAL_DECLARATION") package kotlin.js import kotlin.annotation.AnnotationTarget.* diff --git a/js/js.translator/testData/box/native/nestedElements.kt b/js/js.translator/testData/box/native/nestedElements.kt index 912ec91433f..4be1187936d 100644 --- a/js/js.translator/testData/box/native/nestedElements.kt +++ b/js/js.translator/testData/box/native/nestedElements.kt @@ -44,11 +44,6 @@ fun box(): String { assertEquals("Class.Class.b", Class.Class.b) assertEquals(88, Class.Class.test()) - //TODO inner class -// assertEquals("Class.InnerClass().a", Class().InnerClass("Class.InnerClass().a").a) -// assertEquals("Class.InnerClass().b", Class().InnerClass("something").b) -// assertEquals(66, Class().InnerClass("something").test()) - assertEquals("Class.Trait.a", Class.Trait.a) assertEquals("Class.Trait.b", Class.Trait.b) assertEquals(55, Class.Trait.test()) @@ -59,7 +54,7 @@ fun box(): String { assertEquals("Class.b", Class.b) assertEquals(77, Class.test()) - // in trit + // in trait assertEquals("Trait.Object.a", Trait.Object.a) assertEquals("Trait.Object.b", Trait.Object.b) @@ -151,11 +146,6 @@ external class Class { } } - inner class InnerClass(val a: String) { - var b: String = noImpl - fun test(): Int = noImpl - } - interface Trait { val a: String var b: String diff --git a/js/js.translator/testData/box/nestedTypes/outerNative.kt b/js/js.translator/testData/box/nestedTypes/outerNative.kt index 1933f7a7e2e..4086869d30b 100644 --- a/js/js.translator/testData/box/nestedTypes/outerNative.kt +++ b/js/js.translator/testData/box/nestedTypes/outerNative.kt @@ -10,22 +10,12 @@ external class A(x: Int) { class B(val value: Int) { fun bar(): Int = noImpl } - - inner class C(val value: Int) { - fun bar(): Int = noImpl - fun dec(): Unit = noImpl - } } fun box(): String { var b = A.B(23) if (b.bar() != 10023) return "failed1: ${b.bar()}" - var c = A(11).C(23) - if (c.bar() != 10034) return "failed2: ${c.bar()}" - c.dec() - if (c.bar() != 10033) return "failed3: ${c.bar()}" - return "OK" }