From 9869ae10e525525b2357b733a3756ea66241bd5a Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Fri, 26 Dec 2014 19:10:12 +0300 Subject: [PATCH] JS frontend: allow to omit body for native functions and initializer for native properties. Additionally suppress UNUSED_PARAM for new nativeX annotations too. --- .../jet/lang/resolve/kotlin/native.kt | 18 +---- .../SuppressDiagnosticsByAnnotations.kt | 54 ++++++++++++++ .../testData/cli/js/nativeDeclarations.args | 3 - .../testData/cli/js/nativeDeclarations.out | 1 - .../native/optionlBody/native.kt | 71 ++++++++++++++++++ .../native/optionlBody/native.txt | 74 +++++++++++++++++++ .../native/optionlBody/nativeGetter.kt | 13 ++++ .../native/optionlBody/nativeGetter.txt | 12 +++ .../native/optionlBody/nativeInvoke.kt | 13 ++++ .../native/optionlBody/nativeInvoke.txt | 22 ++++++ .../native/optionlBody/nativeSetter.kt | 13 ++++ .../native/optionlBody/nativeSetter.txt | 13 ++++ .../native/unusedParam/native.kt} | 5 +- .../native/unusedParam/native.txt | 44 +++++++++++ .../native/unusedParam/nativeGetter.kt | 19 +++++ .../native/unusedParam/nativeGetter.txt | 43 +++++++++++ .../native/unusedParam/nativeInvoke.kt | 19 +++++ .../native/unusedParam/nativeInvoke.txt | 43 +++++++++++ .../native/unusedParam/nativeSetter.kt | 19 +++++ .../native/unusedParam/nativeSetter.txt | 43 +++++++++++ ...tDiagnosticsTestWithJsStdLibGenerated.java | 68 ++++++++++++++++- .../cli/KotlincExecutableTestGenerated.java | 6 -- .../org/jetbrains/jet/cli/js/K2JsCliTest.java | 7 -- idea/src/META-INF/extensions/kotlin2js.xml | 2 + .../k2js/analyze/suppressWarnings.kt | 34 ++++++--- 25 files changed, 616 insertions(+), 43 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/diagnostics/SuppressDiagnosticsByAnnotations.kt delete mode 100644 compiler/testData/cli/js/nativeDeclarations.args delete mode 100644 compiler/testData/cli/js/nativeDeclarations.out create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/native.kt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/native.txt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeGetter.kt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeGetter.txt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeInvoke.kt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeInvoke.txt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeSetter.kt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeSetter.txt rename compiler/testData/{cli/js/nativeDeclarations.kt => diagnostics/testsWithJsStdLib/native/unusedParam/native.kt} (81%) create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/native.txt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeGetter.kt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeGetter.txt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeInvoke.kt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeInvoke.txt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeSetter.kt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeSetter.txt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/native.kt b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/native.kt index a1195d3fe32..606261b21dd 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/native.kt +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/native.kt @@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.kotlin.nativeDeclarations import org.jetbrains.jet.lang.resolve.diagnostics.DiagnosticsWithSuppression import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor import org.jetbrains.jet.lang.resolve.DescriptorUtils -import org.jetbrains.jet.lang.diagnostics.Errors import org.jetbrains.jet.lang.resolve.AnnotationChecker import org.jetbrains.jet.lang.psi.JetDeclaration import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor @@ -30,6 +29,8 @@ import org.jetbrains.jet.lang.descriptors.Modality import org.jetbrains.jet.lang.resolve.java.diagnostics.ErrorsJvm import org.jetbrains.jet.lang.psi.JetDeclarationWithBody import org.jetbrains.jet.lang.resolve.annotations.hasInlineAnnotation +import org.jetbrains.jet.lang.resolve.diagnostics.SuppressDiagnosticsByAnnotations +import org.jetbrains.jet.lang.resolve.diagnostics.FUNCTION_NO_BODY_ERRORS private val NATIVE_ANNOTATION_CLASS_NAME = FqName("kotlin.jvm.native") @@ -37,20 +38,7 @@ public fun DeclarationDescriptor.hasNativeAnnotation(): Boolean { return getAnnotations().findAnnotation(NATIVE_ANNOTATION_CLASS_NAME) != null } -class SuppressNoBodyErrorsForNativeDeclarations : DiagnosticsWithSuppression.SuppressStringProvider { - override fun get(annotationDescriptor: AnnotationDescriptor): List { - val descriptor = DescriptorUtils.getClassDescriptorForType(annotationDescriptor.getType()) - if (NATIVE_ANNOTATION_CLASS_NAME.asString() == DescriptorUtils.getFqName(descriptor).asString()) { - return listOf( - Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY.getName().toLowerCase(), - Errors.NON_MEMBER_FUNCTION_NO_BODY.getName().toLowerCase(), - Errors.FINAL_FUNCTION_WITH_NO_BODY.getName().toLowerCase() - ) - } - - return listOf() - } -} +public class SuppressNoBodyErrorsForNativeDeclarations : SuppressDiagnosticsByAnnotations(FUNCTION_NO_BODY_ERRORS, NATIVE_ANNOTATION_CLASS_NAME) public class NativeFunChecker : AnnotationChecker { override fun check(declaration: JetDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/diagnostics/SuppressDiagnosticsByAnnotations.kt b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/diagnostics/SuppressDiagnosticsByAnnotations.kt new file mode 100644 index 00000000000..bfe6f6cb7a4 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/diagnostics/SuppressDiagnosticsByAnnotations.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.diagnostics + +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.jet.lang.diagnostics.Errors +import org.jetbrains.jet.lang.resolve.DescriptorUtils +import org.jetbrains.jet.lang.diagnostics.Diagnostic +import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory +import org.jetbrains.jet.lang.resolve.name.FqName +import org.jetbrains.jet.lang.psi.JetFunction +import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor +import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1 +import org.jetbrains.jet.lang.psi.JetProperty +import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory0 + +public val FUNCTION_NO_BODY_ERRORS: List> = + listOf(Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, Errors.NON_MEMBER_FUNCTION_NO_BODY, Errors.FINAL_FUNCTION_WITH_NO_BODY) + +public val PROPERTY_NOT_INITIALIZED_ERRORS: List> = + listOf(Errors.MUST_BE_INITIALIZED, Errors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT) + +public abstract class SuppressDiagnosticsByAnnotations( + diagnosticsToSuppress: List>, + vararg annotationsFqName: FqName +) : DiagnosticsWithSuppression.SuppressStringProvider { + + private val annotationsFqName = annotationsFqName + private val stringsToSuppress = diagnosticsToSuppress.map { it.getName().toLowerCase() } + private val expectedFqNames = annotationsFqName.map { it.toString() } + + override fun get(annotationDescriptor: AnnotationDescriptor): List { + val descriptor = DescriptorUtils.getClassDescriptorForType(annotationDescriptor.getType()) + val actualFqName = DescriptorUtils.getFqName(descriptor).asString() + + if (expectedFqNames.any { it == actualFqName }) return stringsToSuppress + + return listOf() + } +} diff --git a/compiler/testData/cli/js/nativeDeclarations.args b/compiler/testData/cli/js/nativeDeclarations.args deleted file mode 100644 index 906adc2ec6d..00000000000 --- a/compiler/testData/cli/js/nativeDeclarations.args +++ /dev/null @@ -1,3 +0,0 @@ -$TESTDATA_DIR$/nativeDeclarations.kt --output -$TEMP_DIR$/out.js \ No newline at end of file diff --git a/compiler/testData/cli/js/nativeDeclarations.out b/compiler/testData/cli/js/nativeDeclarations.out deleted file mode 100644 index a0aba9318ad..00000000000 --- a/compiler/testData/cli/js/nativeDeclarations.out +++ /dev/null @@ -1 +0,0 @@ -OK \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/native.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/native.kt new file mode 100644 index 00000000000..931d7883fd8 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/native.kt @@ -0,0 +1,71 @@ +native +val baz: Int +native +val boo: Int = noImpl + +native +val Int.baz: Int + +native +fun foo() +native +fun bar() {} + +native +fun String.foo(): Int +native +fun String.bar(): Int = noImpl + +native +trait T { + val baz: Int + + fun foo() + fun bar() {} + + class object { + val baz: Int + val boo: Int = noImpl + + fun foo() + fun bar(): String = noImpl + } +} + +native +class C { + val baz: Int + val boo: Int = noImpl + + fun foo() + fun bar() {} + + class object { + val baz: Int + val boo: Int = noImpl + + fun foo() + fun bar(): String = noImpl + } +} + +native +object O { + val baz: Int + val boo: Int = noImpl + + fun foo(s: String): String + fun bar(s: String): String = noImpl +} + +fun test() { + [native] + class Local { + val baz: Int + val boo: Int = noImpl + + fun foo() + fun bar() {} + } +} + diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/native.txt b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/native.txt new file mode 100644 index 00000000000..6a0fac8df7b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/native.txt @@ -0,0 +1,74 @@ +package + +kotlin.js.native() internal val baz: kotlin.Int +kotlin.js.native() internal val boo: kotlin.Int +kotlin.js.native() internal val kotlin.Int.baz: kotlin.Int +kotlin.js.native() internal fun bar(): kotlin.Unit +kotlin.js.native() internal fun foo(): kotlin.Unit +internal fun test(): kotlin.Unit +kotlin.js.native() internal fun kotlin.String.bar(): kotlin.Int +kotlin.js.native() internal fun kotlin.String.foo(): kotlin.Int + +kotlin.js.native() internal final class C { + public constructor C() + internal final val baz: kotlin.Int + internal final val boo: kotlin.Int + internal final fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + internal class object { + private constructor () + internal final val baz: kotlin.Int + internal final val boo: kotlin.Int + internal final fun bar(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +kotlin.js.native() internal object O { + private constructor O() + internal final val baz: kotlin.Int + internal final val boo: kotlin.Int + internal final fun bar(/*0*/ s: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final fun foo(/*0*/ s: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public class object : O { + private constructor () + internal final override /*1*/ /*fake_override*/ val baz: kotlin.Int + internal final override /*1*/ /*fake_override*/ val boo: kotlin.Int + internal final override /*1*/ /*fake_override*/ fun bar(/*0*/ s: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final override /*1*/ /*fake_override*/ fun foo(/*0*/ s: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +kotlin.js.native() internal trait T { + internal abstract val baz: kotlin.Int + internal open fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal abstract fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + internal class object { + private constructor () + internal final val baz: kotlin.Int + internal final val boo: kotlin.Int + internal final fun bar(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final fun foo(): kotlin.Unit + 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/optionlBody/nativeGetter.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeGetter.kt new file mode 100644 index 00000000000..013d2ca2bdd --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeGetter.kt @@ -0,0 +1,13 @@ +nativeGetter +fun String.foo(n: Int): Int? +nativeGetter +fun String.bar(n: Int): Int? = noImpl + + +native +trait T { + nativeGetter + fun foo(d: Double): String? + nativeGetter + fun bar(d: Double): String? = noImpl +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeGetter.txt b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeGetter.txt new file mode 100644 index 00000000000..21f48ba82b0 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeGetter.txt @@ -0,0 +1,12 @@ +package + +kotlin.js.nativeGetter() internal fun kotlin.String.bar(/*0*/ n: kotlin.Int): kotlin.Int? +kotlin.js.nativeGetter() internal fun kotlin.String.foo(/*0*/ n: kotlin.Int): kotlin.Int? + +kotlin.js.native() internal trait T { + kotlin.js.nativeGetter() internal open fun bar(/*0*/ d: kotlin.Double): kotlin.String? + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + kotlin.js.nativeGetter() internal abstract fun foo(/*0*/ d: kotlin.Double): kotlin.String? + 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/optionlBody/nativeInvoke.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeInvoke.kt new file mode 100644 index 00000000000..55900e9bd9a --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeInvoke.kt @@ -0,0 +1,13 @@ +nativeInvoke +fun String.foo(): Int +nativeInvoke +fun String.bar(): Int = noImpl + + +native +object O { + nativeInvoke + fun foo() + nativeInvoke + fun bar() {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeInvoke.txt b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeInvoke.txt new file mode 100644 index 00000000000..c49b99bdf11 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeInvoke.txt @@ -0,0 +1,22 @@ +package + +kotlin.js.nativeInvoke() internal fun kotlin.String.bar(): kotlin.Int +kotlin.js.nativeInvoke() internal fun kotlin.String.foo(): kotlin.Int + +kotlin.js.native() internal object O { + private constructor O() + kotlin.js.nativeInvoke() internal final fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + kotlin.js.nativeInvoke() internal final fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public class object : O { + private constructor () + kotlin.js.nativeInvoke() internal final override /*1*/ /*fake_override*/ fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + kotlin.js.nativeInvoke() internal final override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit + 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/optionlBody/nativeSetter.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeSetter.kt new file mode 100644 index 00000000000..3505007ac94 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeSetter.kt @@ -0,0 +1,13 @@ +nativeSetter +fun String.foo(n: Int, v: Any) +nativeSetter +fun String.bar(n: Int, v: Any) {} + + +native +class C { + nativeSetter + fun foo(d: Double, v: Any): String? + nativeSetter + fun bar(d: Double, v: Any): String? = noImpl +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeSetter.txt b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeSetter.txt new file mode 100644 index 00000000000..d829c4c9850 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeSetter.txt @@ -0,0 +1,13 @@ +package + +kotlin.js.nativeSetter() internal fun kotlin.String.bar(/*0*/ n: kotlin.Int, /*1*/ v: kotlin.Any): kotlin.Unit +kotlin.js.nativeSetter() internal fun kotlin.String.foo(/*0*/ n: kotlin.Int, /*1*/ v: kotlin.Any): kotlin.Unit + +kotlin.js.native() internal final class C { + public constructor C() + kotlin.js.nativeSetter() internal final fun bar(/*0*/ d: kotlin.Double, /*1*/ v: kotlin.Any): kotlin.String? + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + kotlin.js.nativeSetter() internal final fun foo(/*0*/ d: kotlin.Double, /*1*/ v: kotlin.Any): kotlin.String? + 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/cli/js/nativeDeclarations.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/native.kt similarity index 81% rename from compiler/testData/cli/js/nativeDeclarations.kt rename to compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/native.kt index 06965517d66..afd5534978f 100644 --- a/compiler/testData/cli/js/nativeDeclarations.kt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/native.kt @@ -1,6 +1,9 @@ native fun foo(a: String): Int = noImpl +native +fun Int.foo(a: String): Int = noImpl + native class Bar(b: Int, c: Char) { fun baz(d: Int) {} @@ -12,4 +15,4 @@ object Obj { object Nested { fun test2(g: Int) {} } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/native.txt b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/native.txt new file mode 100644 index 00000000000..060fbece900 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/native.txt @@ -0,0 +1,44 @@ +package + +kotlin.js.native() internal fun foo(/*0*/ a: kotlin.String): kotlin.Int +kotlin.js.native() internal fun kotlin.Int.foo(/*0*/ a: kotlin.String): kotlin.Int + +kotlin.js.native() internal final class Bar { + public constructor Bar(/*0*/ b: kotlin.Int, /*1*/ c: kotlin.Char) + internal final fun baz(/*0*/ d: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +kotlin.js.native() internal object Obj { + private constructor Obj() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + internal final fun test1(/*0*/ e: kotlin.String): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public class object : Obj { + private constructor () + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + internal final override /*1*/ /*fake_override*/ fun test1(/*0*/ e: kotlin.String): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + internal object Nested { + private constructor Nested() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + internal final fun test2(/*0*/ g: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public class object : Obj.Nested { + private constructor () + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + internal final override /*1*/ /*fake_override*/ fun test2(/*0*/ g: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeGetter.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeGetter.kt new file mode 100644 index 00000000000..21446517c54 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeGetter.kt @@ -0,0 +1,19 @@ +nativeGetter +fun Int.foo(a: String): Int? = noImpl + +native +class Bar(b: Int, c: Char) { + nativeGetter + fun baz(d: Int): Any? = noImpl +} + +native +object Obj { + nativeGetter + fun test1(e: String): String? = noImpl + + object Nested { + nativeGetter + fun test2(g: Int): Any? = noImpl + } +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeGetter.txt b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeGetter.txt new file mode 100644 index 00000000000..3f4bb6b75c1 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeGetter.txt @@ -0,0 +1,43 @@ +package + +kotlin.js.nativeGetter() internal fun kotlin.Int.foo(/*0*/ a: kotlin.String): kotlin.Int? + +kotlin.js.native() internal final class Bar { + public constructor Bar(/*0*/ b: kotlin.Int, /*1*/ c: kotlin.Char) + kotlin.js.nativeGetter() internal final fun baz(/*0*/ d: kotlin.Int): kotlin.Any? + 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.native() internal object Obj { + private constructor Obj() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.js.nativeGetter() internal final fun test1(/*0*/ e: kotlin.String): kotlin.String? + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public class object : Obj { + private constructor () + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.js.nativeGetter() internal final override /*1*/ /*fake_override*/ fun test1(/*0*/ e: kotlin.String): kotlin.String? + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + internal object Nested { + private constructor Nested() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.js.nativeGetter() internal final fun test2(/*0*/ g: kotlin.Int): kotlin.Any? + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public class object : Obj.Nested { + private constructor () + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.js.nativeGetter() internal final override /*1*/ /*fake_override*/ fun test2(/*0*/ g: kotlin.Int): kotlin.Any? + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeInvoke.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeInvoke.kt new file mode 100644 index 00000000000..ae2a1a14c75 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeInvoke.kt @@ -0,0 +1,19 @@ +nativeInvoke +fun Int.foo(a: String): Int = noImpl + +native +class Bar(b: Int, c: Char) { + nativeInvoke + fun baz(d: Int) {} +} + +native +object Obj { + nativeInvoke + fun test1(e: String) {} + + object Nested { + nativeInvoke + fun test2(g: Int) {} + } +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeInvoke.txt b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeInvoke.txt new file mode 100644 index 00000000000..ce642a9e5c4 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeInvoke.txt @@ -0,0 +1,43 @@ +package + +kotlin.js.nativeInvoke() internal fun kotlin.Int.foo(/*0*/ a: kotlin.String): kotlin.Int + +kotlin.js.native() internal final class Bar { + public constructor Bar(/*0*/ b: kotlin.Int, /*1*/ c: kotlin.Char) + kotlin.js.nativeInvoke() internal final fun baz(/*0*/ d: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +kotlin.js.native() internal object Obj { + private constructor Obj() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.js.nativeInvoke() internal final fun test1(/*0*/ e: kotlin.String): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public class object : Obj { + private constructor () + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.js.nativeInvoke() internal final override /*1*/ /*fake_override*/ fun test1(/*0*/ e: kotlin.String): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + internal object Nested { + private constructor Nested() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.js.nativeInvoke() internal final fun test2(/*0*/ g: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public class object : Obj.Nested { + private constructor () + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.js.nativeInvoke() internal final override /*1*/ /*fake_override*/ fun test2(/*0*/ g: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeSetter.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeSetter.kt new file mode 100644 index 00000000000..700a3d9e51b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeSetter.kt @@ -0,0 +1,19 @@ +nativeSetter +fun Int.foo(a: String, v: Int): Int = noImpl + +native +class Bar(b: Int, c: Char) { + nativeSetter + fun baz(d: Int, v: Int) {} +} + +native +object Obj { + nativeSetter + fun test1(e: String, v: Any) {} + + object Nested { + nativeSetter + fun test2(g: Int, v: Any) {} + } +} diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeSetter.txt b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeSetter.txt new file mode 100644 index 00000000000..4f6eaa5f0c1 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeSetter.txt @@ -0,0 +1,43 @@ +package + +kotlin.js.nativeSetter() internal fun kotlin.Int.foo(/*0*/ a: kotlin.String, /*1*/ v: kotlin.Int): kotlin.Int + +kotlin.js.native() internal final class Bar { + public constructor Bar(/*0*/ b: kotlin.Int, /*1*/ c: kotlin.Char) + kotlin.js.nativeSetter() internal final fun baz(/*0*/ d: kotlin.Int, /*1*/ v: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +kotlin.js.native() internal object Obj { + private constructor Obj() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.js.nativeSetter() internal final fun test1(/*0*/ e: kotlin.String, /*1*/ v: kotlin.Any): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public class object : Obj { + private constructor () + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.js.nativeSetter() internal final override /*1*/ /*fake_override*/ fun test1(/*0*/ e: kotlin.String, /*1*/ v: kotlin.Any): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + internal object Nested { + private constructor Nested() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.js.nativeSetter() internal final fun test2(/*0*/ g: kotlin.Int, /*1*/ v: kotlin.Any): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public class object : Obj.Nested { + private constructor () + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + kotlin.js.nativeSetter() internal final override /*1*/ /*fake_override*/ fun test2(/*0*/ g: kotlin.Int, /*1*/ v: kotlin.Any): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithJsStdLibGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithJsStdLibGenerated.java index b9f677b9328..060ae060973 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithJsStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithJsStdLibGenerated.java @@ -228,7 +228,7 @@ public class JetDiagnosticsTestWithJsStdLibGenerated extends AbstractJetDiagnost @TestMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native") @TestDataPath("$PROJECT_ROOT") - @InnerTestClasses({Native.NativeGetter.class, Native.NativeInvoke.class, Native.NativeSetter.class}) + @InnerTestClasses({Native.NativeGetter.class, Native.NativeInvoke.class, Native.NativeSetter.class, Native.OptionlBody.class, Native.UnusedParam.class}) @RunWith(JUnit3RunnerWithInners.class) public static class Native extends AbstractJetDiagnosticsTestWithJsStdLib { public void testAllFilesPresentInNative() throws Exception { @@ -441,5 +441,71 @@ public class JetDiagnosticsTestWithJsStdLibGenerated extends AbstractJetDiagnost doTest(fileName); } } + + @TestMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class OptionlBody extends AbstractJetDiagnosticsTestWithJsStdLib { + public void testAllFilesPresentInOptionlBody() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("native.kt") + public void testNative() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/native.kt"); + doTest(fileName); + } + + @TestMetadata("nativeGetter.kt") + public void testNativeGetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeGetter.kt"); + doTest(fileName); + } + + @TestMetadata("nativeInvoke.kt") + public void testNativeInvoke() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeInvoke.kt"); + doTest(fileName); + } + + @TestMetadata("nativeSetter.kt") + public void testNativeSetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeSetter.kt"); + doTest(fileName); + } + } + + @TestMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class UnusedParam extends AbstractJetDiagnosticsTestWithJsStdLib { + public void testAllFilesPresentInUnusedParam() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("native.kt") + public void testNative() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/native.kt"); + doTest(fileName); + } + + @TestMetadata("nativeGetter.kt") + public void testNativeGetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeGetter.kt"); + doTest(fileName); + } + + @TestMetadata("nativeInvoke.kt") + public void testNativeInvoke() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeInvoke.kt"); + doTest(fileName); + } + + @TestMetadata("nativeSetter.kt") + public void testNativeSetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/unusedParam/nativeSetter.kt"); + doTest(fileName); + } + } } } diff --git a/compiler/tests/org/jetbrains/jet/cli/KotlincExecutableTestGenerated.java b/compiler/tests/org/jetbrains/jet/cli/KotlincExecutableTestGenerated.java index 7a90a7c9ba0..ffa5d3a2c3e 100644 --- a/compiler/tests/org/jetbrains/jet/cli/KotlincExecutableTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/cli/KotlincExecutableTestGenerated.java @@ -192,12 +192,6 @@ public class KotlincExecutableTestGenerated extends AbstractKotlincExecutableTes doJsTest(fileName); } - @TestMetadata("nativeDeclarations.args") - public void testNativeDeclarations() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/cli/js/nativeDeclarations.args"); - doJsTest(fileName); - } - @TestMetadata("notValidLibraryDir.args") public void testNotValidLibraryDir() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/cli/js/notValidLibraryDir.args"); diff --git a/compiler/tests/org/jetbrains/jet/cli/js/K2JsCliTest.java b/compiler/tests/org/jetbrains/jet/cli/js/K2JsCliTest.java index 21a6001d6ec..be34e124187 100644 --- a/compiler/tests/org/jetbrains/jet/cli/js/K2JsCliTest.java +++ b/compiler/tests/org/jetbrains/jet/cli/js/K2JsCliTest.java @@ -56,13 +56,6 @@ public class K2JsCliTest extends CliBaseTest { executeCompilerCompareOutputJS(); } - @Test - public void nativeDeclarations() throws Exception { - executeCompilerCompareOutputJS(); - - Assert.assertTrue(new File(tmpdir.getTmpDir(), "out.js").isFile()); - } - @Test public void withLib() throws Exception { executeCompilerCompareOutputJS(); diff --git a/idea/src/META-INF/extensions/kotlin2js.xml b/idea/src/META-INF/extensions/kotlin2js.xml index d2a35ef4803..a503deeda3a 100644 --- a/idea/src/META-INF/extensions/kotlin2js.xml +++ b/idea/src/META-INF/extensions/kotlin2js.xml @@ -4,6 +4,8 @@ + + diff --git a/js/js.frontend/src/org/jetbrains/k2js/analyze/suppressWarnings.kt b/js/js.frontend/src/org/jetbrains/k2js/analyze/suppressWarnings.kt index 6ab03402a97..b5fe9d3e80c 100644 --- a/js/js.frontend/src/org/jetbrains/k2js/analyze/suppressWarnings.kt +++ b/js/js.frontend/src/org/jetbrains/k2js/analyze/suppressWarnings.kt @@ -20,24 +20,40 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor import org.jetbrains.jet.lang.resolve.DescriptorUtils import org.jetbrains.jet.lang.diagnostics.Errors import org.jetbrains.jet.lang.resolve.diagnostics.DiagnosticsWithSuppression -import org.jetbrains.k2js.PredefinedAnnotation +import org.jetbrains.k2js.PredefinedAnnotation.* import org.jetbrains.jet.lang.diagnostics.Diagnostic import org.jetbrains.jet.lang.diagnostics.Severity import org.jetbrains.jet.lang.psi.JetFile import org.jetbrains.k2js.config.LibrarySourcesConfig +import org.jetbrains.jet.lang.psi.JetSimpleNameExpression +import org.jetbrains.jet.lang.descriptors.VariableDescriptor +import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1 +import org.jetbrains.k2js.translate.utils.AnnotationsUtils +import org.jetbrains.jet.lang.resolve.diagnostics.DiagnosticsWithSuppression +import org.jetbrains.jet.lang.resolve.diagnostics.SuppressDiagnosticsByAnnotations +import org.jetbrains.jet.lang.resolve.diagnostics.FUNCTION_NO_BODY_ERRORS +import org.jetbrains.jet.lang.resolve.diagnostics.PROPERTY_NOT_INITIALIZED_ERRORS -class SuppressUnusedParameterForJsNative : DiagnosticsWithSuppression.SuppressStringProvider { - override fun get(annotationDescriptor: AnnotationDescriptor): List { - val descriptor = DescriptorUtils.getClassDescriptorForType(annotationDescriptor.getType()) - if (PredefinedAnnotation.NATIVE.fqName.asString() == DescriptorUtils.getFqName(descriptor).asString()) { - return listOf(Errors.UNUSED_PARAMETER.getName().toLowerCase()) - } +private val NATIVE_ANNOTATIONS = array(NATIVE.fqName, NATIVE_INVOKE.fqName, NATIVE_GETTER.fqName, NATIVE_SETTER.fqName) - return listOf() +public class SuppressUnusedParameterForJsNative : SuppressDiagnosticsByAnnotations(listOf(Errors.UNUSED_PARAMETER), *NATIVE_ANNOTATIONS) + +public class SuppressNoBodyErrorsForNativeDeclarations : SuppressDiagnosticsByAnnotations(FUNCTION_NO_BODY_ERRORS + PROPERTY_NOT_INITIALIZED_ERRORS, *NATIVE_ANNOTATIONS) + +public class SuppressUninitializedErrorsForNativeDeclarations : DiagnosticsWithSuppression.DiagnosticSuppressor { + override fun isSuppressed(diagnostic: Diagnostic): Boolean { + if (diagnostic.getFactory() != Errors.UNINITIALIZED_VARIABLE) return false + + [suppress("UNCHECKED_CAST")] + val diagnosticWithParameters = diagnostic as DiagnosticWithParameters1 + + val variableDescriptor = diagnosticWithParameters.getA() + + return AnnotationsUtils.isNativeObject(variableDescriptor) } } -class SuppressWarningsFromExternalModules : DiagnosticsWithSuppression.DiagnosticSuppressor { +public class SuppressWarningsFromExternalModules : DiagnosticsWithSuppression.DiagnosticSuppressor { override fun isSuppressed(diagnostic: Diagnostic): Boolean { val file = diagnostic.getPsiFile() return diagnostic.getSeverity() == Severity.WARNING &&