[FIR JS] Support 2 JS diagnostics
The change in `FirDiagnosticsHandler` ensures `DEBUG_INFO_DYNAMIC` is still reported in `FirPsiJsOldFrontendDiagnosticsTestGenerated.testConventions`. Support `SPREAD_OPERATOR_IN_DYNAMIC_CALL` and `WRONG_OPERATION_WITH_DYNAMIC`
This commit is contained in:
committed by
Space Team
parent
57568770b4
commit
03e2152957
+13
@@ -5063,6 +5063,19 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirJsErrors.SPREAD_OPERATOR_IN_DYNAMIC_CALL) { firDiagnostic ->
|
||||||
|
SpreadOperatorInDynamicCallImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirJsErrors.WRONG_OPERATION_WITH_DYNAMIC) { firDiagnostic ->
|
||||||
|
WrongOperationWithDynamicImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirSyntaxErrors.SYNTAX) { firDiagnostic ->
|
add(FirSyntaxErrors.SYNTAX) { firDiagnostic ->
|
||||||
SyntaxImpl(
|
SyntaxImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+9
@@ -3523,6 +3523,15 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = DelegationByDynamic::class
|
override val diagnosticClass get() = DelegationByDynamic::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class SpreadOperatorInDynamicCall : KtFirDiagnostic<KtElement>() {
|
||||||
|
override val diagnosticClass get() = SpreadOperatorInDynamicCall::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class WrongOperationWithDynamic : KtFirDiagnostic<KtElement>() {
|
||||||
|
override val diagnosticClass get() = WrongOperationWithDynamic::class
|
||||||
|
abstract val operation: String
|
||||||
|
}
|
||||||
|
|
||||||
abstract class Syntax : KtFirDiagnostic<PsiElement>() {
|
abstract class Syntax : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = Syntax::class
|
override val diagnosticClass get() = Syntax::class
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -4262,6 +4262,17 @@ internal class DelegationByDynamicImpl(
|
|||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
) : KtFirDiagnostic.DelegationByDynamic(), KtAbstractFirDiagnostic<KtElement>
|
) : KtFirDiagnostic.DelegationByDynamic(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
|
internal class SpreadOperatorInDynamicCallImpl(
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: KtLifetimeToken,
|
||||||
|
) : KtFirDiagnostic.SpreadOperatorInDynamicCall(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
|
internal class WrongOperationWithDynamicImpl(
|
||||||
|
override val operation: String,
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: KtLifetimeToken,
|
||||||
|
) : KtFirDiagnostic.WrongOperationWithDynamic(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
internal class SyntaxImpl(
|
internal class SyntaxImpl(
|
||||||
override val firDiagnostic: KtPsiDiagnostic,
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
|
|||||||
+4
@@ -117,5 +117,9 @@ object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") {
|
|||||||
|
|
||||||
val DYNAMICS by object : DiagnosticGroup("Dynamics") {
|
val DYNAMICS by object : DiagnosticGroup("Dynamics") {
|
||||||
val DELEGATION_BY_DYNAMIC by error<KtElement>()
|
val DELEGATION_BY_DYNAMIC by error<KtElement>()
|
||||||
|
val SPREAD_OPERATOR_IN_DYNAMIC_CALL by error<KtElement>(PositioningStrategy.SPREAD_OPERATOR)
|
||||||
|
val WRONG_OPERATION_WITH_DYNAMIC by error<KtElement> {
|
||||||
|
parameter<String>("operation")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -89,6 +89,8 @@ object FirJsErrors {
|
|||||||
|
|
||||||
// Dynamics
|
// Dynamics
|
||||||
val DELEGATION_BY_DYNAMIC by error0<KtElement>()
|
val DELEGATION_BY_DYNAMIC by error0<KtElement>()
|
||||||
|
val SPREAD_OPERATOR_IN_DYNAMIC_CALL by error0<KtElement>(SourceElementPositioningStrategies.SPREAD_OPERATOR)
|
||||||
|
val WRONG_OPERATION_WITH_DYNAMIC by error1<KtElement, String>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
RootDiagnosticRendererFactory.registerFactory(FirJsErrorsDefaultMessages)
|
RootDiagnosticRendererFactory.registerFactory(FirJsErrorsDefaultMessages)
|
||||||
|
|||||||
+4
@@ -53,6 +53,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.OVERRIDING_E
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.RUNTIME_ANNOTATION_NOT_SUPPORTED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.RUNTIME_ANNOTATION_NOT_SUPPORTED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.RUNTIME_ANNOTATION_ON_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.RUNTIME_ANNOTATION_ON_EXTERNAL_DECLARATION
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.SPREAD_OPERATOR_IN_DYNAMIC_CALL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.UNCHECKED_CAST_TO_EXTERNAL_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.UNCHECKED_CAST_TO_EXTERNAL_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_BODY_OF_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_BODY_OF_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER
|
||||||
@@ -61,6 +62,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_EXTERN
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_JS_QUALIFIER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_JS_QUALIFIER
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_MULTIPLE_INHERITANCE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_MULTIPLE_INHERITANCE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_OPERATION_WITH_DYNAMIC
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||||
@@ -78,6 +80,8 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
FirDiagnosticRenderers.SYMBOL
|
FirDiagnosticRenderers.SYMBOL
|
||||||
)
|
)
|
||||||
map.put(DELEGATION_BY_DYNAMIC, "Can't delegate to dynamic value")
|
map.put(DELEGATION_BY_DYNAMIC, "Can't delegate to dynamic value")
|
||||||
|
map.put(SPREAD_OPERATOR_IN_DYNAMIC_CALL, "Can't apply spread operator in dynamic call")
|
||||||
|
map.put(WRONG_OPERATION_WITH_DYNAMIC, "Wrong operation with dynamic value: {0}", CommonRenderers.STRING)
|
||||||
map.put(IMPLEMENTING_FUNCTION_INTERFACE, "Implementing function interface is prohibited in JavaScript")
|
map.put(IMPLEMENTING_FUNCTION_INTERFACE, "Implementing function interface is prohibited in JavaScript")
|
||||||
map.put(OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS, "Overriding `external` function with optional parameters")
|
map.put(OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS, "Overriding `external` function with optional parameters")
|
||||||
map.put(
|
map.put(
|
||||||
|
|||||||
+6
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.analysis.js.checkers
|
package org.jetbrains.kotlin.fir.analysis.js.checkers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.*
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.*
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.declaration.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.js.checkers.expression.*
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.expression.*
|
||||||
|
|
||||||
object JsExpressionCheckers : ExpressionCheckers() {
|
object JsExpressionCheckers : ExpressionCheckers() {
|
||||||
@@ -19,4 +20,9 @@ object JsExpressionCheckers : ExpressionCheckers() {
|
|||||||
FirJsDefinedExternallyCallChecker,
|
FirJsDefinedExternallyCallChecker,
|
||||||
FirJsNativeRttiChecker,
|
FirJsNativeRttiChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
override val functionCallCheckers: Set<FirFunctionCallChecker>
|
||||||
|
get() = setOf(
|
||||||
|
FirJsDynamicCallChecker,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+107
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.analysis.js.checkers.declaration
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.resolved
|
||||||
|
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeDynamicType
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
|
private val nameToOperator = mapOf(
|
||||||
|
OperatorNameConventions.CONTAINS to "in",
|
||||||
|
OperatorNameConventions.RANGE_TO to "..",
|
||||||
|
OperatorNameConventions.RANGE_UNTIL to "..<",
|
||||||
|
)
|
||||||
|
|
||||||
|
object FirJsDynamicCallChecker : FirFunctionCallChecker() {
|
||||||
|
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
val callee = expression.calleeReference.resolved ?: return
|
||||||
|
|
||||||
|
if (callee.resolvedSymbol.origin !is FirDeclarationOrigin.DynamicScope) {
|
||||||
|
return checkSpreadOperator(expression, context, reporter)
|
||||||
|
}
|
||||||
|
|
||||||
|
val symbol = callee.toResolvedCallableSymbol()
|
||||||
|
?: error("Resolved call callee without a callable symbol")
|
||||||
|
|
||||||
|
when {
|
||||||
|
expression.isArrayAccessWithMultipleIndices -> reporter.reportOn(
|
||||||
|
expression.source, FirJsErrors.WRONG_OPERATION_WITH_DYNAMIC, "indexed access with more than one index", context
|
||||||
|
)
|
||||||
|
expression.isInOperator -> reporter.reportOn(
|
||||||
|
expression.source, FirJsErrors.WRONG_OPERATION_WITH_DYNAMIC, "`in` operation", context
|
||||||
|
)
|
||||||
|
expression.isRangeOperator -> reporter.reportOn(
|
||||||
|
expression.source, FirJsErrors.WRONG_OPERATION_WITH_DYNAMIC, "`${nameToOperator[symbol.name]}` operation", context
|
||||||
|
)
|
||||||
|
expression is FirComponentCall -> reporter.reportOn(
|
||||||
|
expression.source, FirJsErrors.WRONG_OPERATION_WITH_DYNAMIC, "`destructuring declaration", context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
forAllSpreadArgumentsOf(expression) {
|
||||||
|
reporter.reportOn(it.source, FirJsErrors.SPREAD_OPERATOR_IN_DYNAMIC_CALL, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val FirCall.isArrayAccessWithMultipleIndices: Boolean
|
||||||
|
get() {
|
||||||
|
val callee = calleeReference as? FirNamedReference
|
||||||
|
?: return false
|
||||||
|
|
||||||
|
if (callee.source?.kind != KtFakeSourceElementKind.ArrayAccessNameReference) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val arguments = (arguments.singleOrNull() as? FirVarargArgumentsExpression)?.arguments
|
||||||
|
?: return false
|
||||||
|
|
||||||
|
return callee.name == OperatorNameConventions.GET && arguments.size >= 2
|
||||||
|
|| callee.name == OperatorNameConventions.SET && arguments.size >= 3
|
||||||
|
}
|
||||||
|
|
||||||
|
private val FirFunctionCall.isInOperator
|
||||||
|
get() = calleeReference.resolved?.name == OperatorNameConventions.CONTAINS && origin == FirFunctionCallOrigin.Operator
|
||||||
|
|
||||||
|
private val FirFunctionCall.isRangeOperator
|
||||||
|
get(): Boolean {
|
||||||
|
val name = calleeReference.resolved?.name
|
||||||
|
return (name == OperatorNameConventions.RANGE_TO || name == OperatorNameConventions.RANGE_UNTIL)
|
||||||
|
&& origin == FirFunctionCallOrigin.Operator
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkSpreadOperator(expression: FirCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
forAllSpreadArgumentsOf(expression) {
|
||||||
|
if (it.typeRef.coneType is ConeDynamicType) {
|
||||||
|
reporter.reportOn(it.source, FirJsErrors.WRONG_OPERATION_WITH_DYNAMIC, "spread operator", context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun forAllSpreadArgumentsOf(call: FirCall, callback: (FirExpression) -> Unit) {
|
||||||
|
for (argument in call.argumentList.arguments) {
|
||||||
|
if (argument !is FirVarargArgumentsExpression) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for (it in argument.arguments) {
|
||||||
|
if (it is FirSpreadArgumentExpression) {
|
||||||
|
callback(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2399,11 +2399,13 @@ open class RawFirBuilder(
|
|||||||
return leftArgument.generateLazyLogicalOperation(rightArgument, operationToken == ANDAND, source)
|
return leftArgument.generateLazyLogicalOperation(rightArgument, operationToken == ANDAND, source)
|
||||||
in OperatorConventions.IN_OPERATIONS ->
|
in OperatorConventions.IN_OPERATIONS ->
|
||||||
return rightArgument.generateContainsOperation(
|
return rightArgument.generateContainsOperation(
|
||||||
leftArgument, operationToken == NOT_IN, source, expression.operationReference.toFirSourceElement(),
|
leftArgument, operationToken == NOT_IN, source,
|
||||||
|
expression.operationReference.toFirSourceElement(),
|
||||||
)
|
)
|
||||||
in OperatorConventions.COMPARISON_OPERATIONS ->
|
in OperatorConventions.COMPARISON_OPERATIONS ->
|
||||||
return leftArgument.generateComparisonExpression(
|
return leftArgument.generateComparisonExpression(
|
||||||
rightArgument, operationToken, source, expression.operationReference.toFirSourceElement(),
|
rightArgument, operationToken, source,
|
||||||
|
expression.operationReference.toFirSourceElement(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val conventionCallName = operationToken.toBinaryName()
|
val conventionCallName = operationToken.toBinaryName()
|
||||||
|
|||||||
+3
-3
@@ -1,17 +1,17 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
for ((x, y) in A()) {
|
for ((<!WRONG_OPERATION_WITH_DYNAMIC!>x<!>, <!WRONG_OPERATION_WITH_DYNAMIC!>y<!>) in A()) {
|
||||||
println(x + y)
|
println(x + y)
|
||||||
}
|
}
|
||||||
|
|
||||||
bar { (x, y) ->
|
bar { (<!WRONG_OPERATION_WITH_DYNAMIC!>x<!>, <!WRONG_OPERATION_WITH_DYNAMIC!>y<!>) ->
|
||||||
println(x + y)
|
println(x + y)
|
||||||
}
|
}
|
||||||
|
|
||||||
val x: dynamic = Any()
|
val x: dynamic = Any()
|
||||||
|
|
||||||
val (y, z) = x
|
val (<!WRONG_OPERATION_WITH_DYNAMIC!>y<!>, <!WRONG_OPERATION_WITH_DYNAMIC!>z<!>) = x
|
||||||
println(y + z)
|
println(y + z)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -1,12 +1,12 @@
|
|||||||
fun foo() {
|
fun foo() {
|
||||||
val a: dynamic = Any()
|
val a: dynamic = Any()
|
||||||
println(a in setOf(1, 2))
|
println(a in setOf(1, 2))
|
||||||
println(1 in a)
|
println(<!WRONG_OPERATION_WITH_DYNAMIC!>1 in a<!>)
|
||||||
println(1 !in a)
|
println(<!WRONG_OPERATION_WITH_DYNAMIC!>1 !in a<!>)
|
||||||
when (2) {
|
when (2) {
|
||||||
in a -> println("ok")
|
<!WRONG_OPERATION_WITH_DYNAMIC!>in a<!> -> println("ok")
|
||||||
}
|
}
|
||||||
when (3) {
|
when (3) {
|
||||||
!in a -> println("ok")
|
<!WRONG_OPERATION_WITH_DYNAMIC!>!in a<!> -> println("ok")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
fun foo() {
|
fun foo() {
|
||||||
val a: dynamic = Any()
|
val a: dynamic = Any()
|
||||||
println(a[0])
|
println(a[0])
|
||||||
println(a[0, 1])
|
println(<!WRONG_OPERATION_WITH_DYNAMIC!>a[0, 1]<!>)
|
||||||
|
|
||||||
a[0] = 23
|
a[0] = 23
|
||||||
a[0, 1] = 42
|
<!WRONG_OPERATION_WITH_DYNAMIC!>a[0, 1] = 42<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ fun foo() {
|
|||||||
val a: dynamic = Any()
|
val a: dynamic = Any()
|
||||||
val b: dynamic = Any()
|
val b: dynamic = Any()
|
||||||
val c = C()
|
val c = C()
|
||||||
println(a..b)
|
println(<!WRONG_OPERATION_WITH_DYNAMIC!>a..b<!>)
|
||||||
println(c..a)
|
println(c..a)
|
||||||
println(a.rangeTo(b))
|
println(a.rangeTo(b))
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ fun foo() {
|
|||||||
val a: dynamic = Any()
|
val a: dynamic = Any()
|
||||||
val b: dynamic = Any()
|
val b: dynamic = Any()
|
||||||
val c = C()
|
val c = C()
|
||||||
println(a..<b)
|
println(<!WRONG_OPERATION_WITH_DYNAMIC!>a..<b<!>)
|
||||||
println(c..<a)
|
println(c..<a)
|
||||||
println(a.rangeUntil(b))
|
println(a.rangeUntil(b))
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -1,22 +1,22 @@
|
|||||||
fun test(d: dynamic) {
|
fun test(d: dynamic) {
|
||||||
val a = arrayOf(1, 2, 3)
|
val a = arrayOf(1, 2, 3)
|
||||||
|
|
||||||
d.foo(*d)
|
d.foo(<!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>d)
|
||||||
d.foo(*a)
|
d.foo(<!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a)
|
||||||
d.foo(1, "2", *a)
|
d.foo(1, "2", <!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a)
|
||||||
d.foo(1, *a) <!VARARG_OUTSIDE_PARENTHESES!>{ }<!>
|
d.foo(1, *a) <!VARARG_OUTSIDE_PARENTHESES!>{ }<!>
|
||||||
d.foo(*a) <!VARARG_OUTSIDE_PARENTHESES!>{ "" }<!>
|
d.foo(*a) <!VARARG_OUTSIDE_PARENTHESES!>{ "" }<!>
|
||||||
d.foo(*a, *a)
|
d.foo(<!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a, <!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a)
|
||||||
d.foo(*a, *a) <!VARARG_OUTSIDE_PARENTHESES!>{ "" }<!>
|
d.foo(*a, *a) <!VARARG_OUTSIDE_PARENTHESES!>{ "" }<!>
|
||||||
d.foo(*a, 1, { "" }, *a)
|
d.foo(<!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a, 1, { "" }, <!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a)
|
||||||
d.foo(*a, 1)
|
d.foo(<!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a, 1)
|
||||||
d.foo(*a, *a, { "" })
|
d.foo(<!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a, <!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a, { "" })
|
||||||
|
|
||||||
bar(d)
|
bar(d)
|
||||||
bar(d, d)
|
bar(d, d)
|
||||||
bar(*d)
|
bar(<!WRONG_OPERATION_WITH_DYNAMIC!>*d<!>)
|
||||||
bar(*d, *d)
|
bar(<!WRONG_OPERATION_WITH_DYNAMIC!>*d<!>, <!WRONG_OPERATION_WITH_DYNAMIC!>*d<!>)
|
||||||
bar(*d, 23, *d)
|
bar(<!WRONG_OPERATION_WITH_DYNAMIC!>*d<!>, 23, <!WRONG_OPERATION_WITH_DYNAMIC!>*d<!>)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar(vararg x: Int): Unit = TODO("$x")
|
fun bar(vararg x: Int): Unit = TODO("$x")
|
||||||
|
|||||||
Reference in New Issue
Block a user