From ad4fb44827ed2318db251fa8933fa3ac1997b354 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 25 Jan 2017 12:46:41 +0300 Subject: [PATCH] JS: report about using of external interfaces in class literals --- .../native/rtti/nativeInterfaceClassLiteral.kt | 5 +++++ .../native/rtti/nativeInterfaceClassLiteral.txt | 9 +++++++++ .../DiagnosticsTestWithJsStdLibGenerated.java | 6 ++++++ .../resolve/diagnostics/DefaultErrorMessagesJs.kt | 1 + .../kotlin/js/resolve/diagnostics/ErrorsJs.java | 1 + .../js/resolve/diagnostics/JsNativeRttiChecker.kt | 14 +++++++++++++- 6 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceClassLiteral.kt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceClassLiteral.txt diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceClassLiteral.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceClassLiteral.kt new file mode 100644 index 00000000000..1ee34e36e04 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceClassLiteral.kt @@ -0,0 +1,5 @@ +external interface I + +fun box() { + println(I::class) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceClassLiteral.txt b/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceClassLiteral.txt new file mode 100644 index 00000000000..d99ac69d7a0 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceClassLiteral.txt @@ -0,0 +1,9 @@ +package + +public fun box(): kotlin.Unit + +public external 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJsStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJsStdLibGenerated.java index f9928d49e08..59699687597 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJsStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJsStdLibGenerated.java @@ -955,6 +955,12 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes doTest(fileName); } + @TestMetadata("nativeInterfaceClassLiteral.kt") + public void testNativeInterfaceClassLiteral() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/nativeInterfaceClassLiteral.kt"); + doTest(fileName); + } + @TestMetadata("whenIsNativeInterface.kt") public void testWhenIsNativeInterface() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/native/rtti/whenIsNativeInterface.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 f64a81e00b9..bf39f3b2e05 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 @@ -72,6 +72,7 @@ private val DIAGNOSTIC_FACTORY_TO_RENDERER by lazy { put(ErrorsJs.CANNOT_CHECK_FOR_NATIVE_INTERFACE, "Cannot check for native interface: {0}", RENDER_TYPE) put(ErrorsJs.UNCHECKED_CAST_TO_NATIVE_INTERFACE, "Unchecked cast to native interface: {0} to {1}", RENDER_TYPE, RENDER_TYPE) put(ErrorsJs.NATIVE_INTERFACE_AS_REIFIED_TYPE_ARGUMENT, "Cannot pass native interface {0} for reified type parameter", RENDER_TYPE) + put(ErrorsJs.NATIVE_INTERFACE_AS_CLASS_LITERAL, "Can't refer to native interface from class literal") put(ErrorsJs.EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE, "External type extends non-external type") put(ErrorsJs.WRONG_OPERATION_WITH_DYNAMIC, "Wrong operation with dynamic value: {0}", Renderers.STRING) 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 4cd214adb47..8da03bbd879 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 @@ -73,6 +73,7 @@ public interface ErrorsJs { DiagnosticFactory1 CANNOT_CHECK_FOR_NATIVE_INTERFACE = DiagnosticFactory1.create(ERROR); DiagnosticFactory2 UNCHECKED_CAST_TO_NATIVE_INTERFACE = DiagnosticFactory2.create(WARNING); DiagnosticFactory1 NATIVE_INTERFACE_AS_REIFIED_TYPE_ARGUMENT = DiagnosticFactory1.create(ERROR); + DiagnosticFactory0 NATIVE_INTERFACE_AS_CLASS_LITERAL = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE = DiagnosticFactory0.create( ERROR, PositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT); diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsNativeRttiChecker.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsNativeRttiChecker.kt index ce033a59706..af2babe649d 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsNativeRttiChecker.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsNativeRttiChecker.kt @@ -17,13 +17,18 @@ package org.jetbrains.kotlin.js.resolve.diagnostics import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils +import org.jetbrains.kotlin.psi.KtClassLiteralExpression import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.calls.checkers.RttiExpressionChecker import org.jetbrains.kotlin.resolve.calls.checkers.RttiExpressionInformation import org.jetbrains.kotlin.resolve.calls.checkers.RttiOperation +import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.expressions.ClassLiteralChecker -class JsNativeRttiChecker : RttiExpressionChecker { +class JsNativeRttiChecker : RttiExpressionChecker, ClassLiteralChecker { override fun check(rttiInformation: RttiExpressionInformation, reportOn: PsiElement, trace: BindingTrace) { val sourceType = rttiInformation.sourceType val targetType = rttiInformation.targetType @@ -38,4 +43,11 @@ class JsNativeRttiChecker : RttiExpressionChecker { } } } + + override fun check(expression: KtClassLiteralExpression, type: KotlinType, context: ResolutionContext<*>) { + val descriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return + if (AnnotationsUtils.isNativeInterface(descriptor)) { + context.trace.report(ErrorsJs.NATIVE_INTERFACE_AS_CLASS_LITERAL.on(expression)) + } + } }