JS: prohibit .. operation on dynamic type. See KT-15184

This commit is contained in:
Alexey Andreev
2016-12-26 16:42:50 +03:00
parent e6be418dd3
commit 31d0e0b7c4
7 changed files with 51 additions and 7 deletions
@@ -7,7 +7,6 @@ public final fun minus(/*0*/ p0: dynamic): dynamic
public final fun times(/*0*/ p0: dynamic): dynamic
public final fun div(/*0*/ p0: dynamic): dynamic
public final fun rem(/*0*/ p0: dynamic): dynamic
public final fun rangeTo(/*0*/ p0: dynamic): dynamic
public final fun and(/*0*/ p0: dynamic): dynamic
public final fun get(/*0*/ p0: dynamic): dynamic
public final fun set(/*0*/ p0: dynamic, /*1*/ p1: dynamic): dynamic
@@ -16,8 +16,6 @@ fun test(d: dynamic) {
d <!DEBUG_INFO_DYNAMIC!>/<!> d
d <!DEBUG_INFO_DYNAMIC!>%<!> d
d<!DEBUG_INFO_DYNAMIC!>..<!>d
d <!DEBUG_INFO_DYNAMIC!>and<!> d
<!DEBUG_INFO_DYNAMIC!>d[1]<!>
@@ -0,0 +1,2 @@
public final fun rangeTo(/*0*/ p0: dynamic): dynamic
public final fun rangeTo(/*0*/ p0: dynamic): dynamic
@@ -0,0 +1,14 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun foo() {
val a: dynamic = Any()
val b: dynamic = Any()
val c = C()
println(a<!WRONG_OPERATION_WITH_DYNAMIC!>..<!>b)
println(c..a)
println(a.rangeTo(b))
}
class C {
operator fun rangeTo(other: dynamic): ClosedRange<dynamic> = TODO("not implemented")
}
@@ -0,0 +1,11 @@
package
public fun foo(): kotlin.Unit
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 final operator fun rangeTo(/*0*/ other: dynamic): kotlin.ranges.ClosedRange<dynamic>
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -242,6 +242,12 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
doTest(fileName);
}
@TestMetadata("rangeExpression.kt")
public void testRangeExpression() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/rangeExpression.kt");
doTest(fileName);
}
@TestMetadata("reified.kt")
public void testReified() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/reified.kt");
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.js.resolve.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtWhenConditionInRange
@@ -36,10 +37,23 @@ object JsDynamicCallChecker : CallChecker {
context.trace.report(ErrorsJs.WRONG_OPERATION_WITH_DYNAMIC.on(reportOn, "indexed access with more than one index"))
}
if (element is KtBinaryExpression && element.operationToken in OperatorConventions.IN_OPERATIONS ||
element is KtWhenConditionInRange
) {
context.trace.report(ErrorsJs.WRONG_OPERATION_WITH_DYNAMIC.on(reportOn, "`in` operation"))
if (element is KtWhenConditionInRange) {
reportInOperation(context, reportOn)
}
else if (element is KtBinaryExpression) {
val token = element.operationToken
when (token) {
in OperatorConventions.IN_OPERATIONS -> {
reportInOperation(context, reportOn)
}
KtTokens.RANGE -> {
context.trace.report(ErrorsJs.WRONG_OPERATION_WITH_DYNAMIC.on(reportOn, "`..` operation"))
}
}
}
}
private fun reportInOperation(context: CallCheckerContext, reportOn: PsiElement) {
context.trace.report(ErrorsJs.WRONG_OPERATION_WITH_DYNAMIC.on(reportOn, "`in` operation"))
}
}