JS: report about using of external interfaces in class literals

This commit is contained in:
Alexey Andreev
2017-01-25 12:46:41 +03:00
parent deaac83e70
commit ad4fb44827
6 changed files with 35 additions and 1 deletions
@@ -0,0 +1,5 @@
external interface I
fun box() {
println(<!NATIVE_INTERFACE_AS_CLASS_LITERAL!>I::class<!>)
}
@@ -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
}
@@ -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");
@@ -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)
@@ -73,6 +73,7 @@ public interface ErrorsJs {
DiagnosticFactory1<PsiElement, KotlinType> CANNOT_CHECK_FOR_NATIVE_INTERFACE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory2<PsiElement, KotlinType, KotlinType> UNCHECKED_CAST_TO_NATIVE_INTERFACE = DiagnosticFactory2.create(WARNING);
DiagnosticFactory1<PsiElement, KotlinType> NATIVE_INTERFACE_AS_REIFIED_TYPE_ARGUMENT = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<PsiElement> NATIVE_INTERFACE_AS_CLASS_LITERAL = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtElement> EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE = DiagnosticFactory0.create(
ERROR, PositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT);
@@ -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))
}
}
}