Fix 'infix call' diagnostic for in operation
#KT-8845 Fixed
This commit is contained in:
@@ -784,7 +784,8 @@ public interface Errors {
|
|||||||
|
|
||||||
DiagnosticFactory1<PsiElement, KotlinType> UNSAFE_CALL = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, KotlinType> UNSAFE_CALL = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory1<PsiElement, KotlinType> UNSAFE_IMPLICIT_INVOKE_CALL = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, KotlinType> UNSAFE_IMPLICIT_INVOKE_CALL = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory3<KtExpression, String, String, String> UNSAFE_INFIX_CALL = DiagnosticFactory3.create(ERROR);
|
DiagnosticFactory3<KtExpression, PsiElement, String, PsiElement> UNSAFE_INFIX_CALL = DiagnosticFactory3.create(ERROR);
|
||||||
|
DiagnosticFactory3<KtExpression, PsiElement, String, PsiElement> UNSAFE_OPERATOR_CALL = DiagnosticFactory3.create(ERROR);
|
||||||
DiagnosticFactory1<PsiElement, KotlinType> UNNECESSARY_SAFE_CALL = DiagnosticFactory1.create(WARNING);
|
DiagnosticFactory1<PsiElement, KotlinType> UNNECESSARY_SAFE_CALL = DiagnosticFactory1.create(WARNING);
|
||||||
DiagnosticFactory0<PsiElement> UNEXPECTED_SAFE_CALL = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<PsiElement> UNEXPECTED_SAFE_CALL = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory1<PsiElement, KotlinType> UNNECESSARY_NOT_NULL_ASSERTION = DiagnosticFactory1.create(WARNING);
|
DiagnosticFactory1<PsiElement, KotlinType> UNNECESSARY_NOT_NULL_ASSERTION = DiagnosticFactory1.create(WARNING);
|
||||||
|
|||||||
+4
-1
@@ -717,7 +717,10 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(UNSAFE_INFIX_CALL,
|
MAP.put(UNSAFE_INFIX_CALL,
|
||||||
"Infix call corresponds to a dot-qualified call ''{0}.{1}({2})'' which is not allowed on a nullable receiver ''{0}''. " +
|
"Infix call corresponds to a dot-qualified call ''{0}.{1}({2})'' which is not allowed on a nullable receiver ''{0}''. " +
|
||||||
"Use ''?.''-qualified call instead",
|
"Use ''?.''-qualified call instead",
|
||||||
STRING, STRING, STRING);
|
ELEMENT_TEXT, STRING, ELEMENT_TEXT);
|
||||||
|
MAP.put(UNSAFE_OPERATOR_CALL,
|
||||||
|
"Operator call corresponds to a dot-qualified call ''{0}.{1}({2})'' which is not allowed on a nullable receiver ''{0}''.",
|
||||||
|
ELEMENT_TEXT, STRING, ELEMENT_TEXT);
|
||||||
|
|
||||||
MAP.put(OVERLOAD_RESOLUTION_AMBIGUITY, "Overload resolution ambiguity: {0}", AMBIGUOUS_CALLS);
|
MAP.put(OVERLOAD_RESOLUTION_AMBIGUITY, "Overload resolution ambiguity: {0}", AMBIGUOUS_CALLS);
|
||||||
MAP.put(NONE_APPLICABLE, "None of the following functions can be called with the arguments supplied: {0}", AMBIGUOUS_CALLS);
|
MAP.put(NONE_APPLICABLE, "None of the following functions can be called with the arguments supplied: {0}", AMBIGUOUS_CALLS);
|
||||||
|
|||||||
+26
-13
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -173,18 +173,7 @@ public abstract class AbstractTracingStrategy implements TracingStrategy {
|
|||||||
else {
|
else {
|
||||||
PsiElement callElement = call.getCallElement();
|
PsiElement callElement = call.getCallElement();
|
||||||
if (callElement instanceof KtBinaryExpression) {
|
if (callElement instanceof KtBinaryExpression) {
|
||||||
KtBinaryExpression binaryExpression = (KtBinaryExpression)callElement;
|
reportUnsafeCallOnBinaryExpression(trace, (KtBinaryExpression) callElement);
|
||||||
KtSimpleNameExpression operationReference = binaryExpression.getOperationReference();
|
|
||||||
|
|
||||||
Name operationString = operationReference.getReferencedNameElementType() == KtTokens.IDENTIFIER ?
|
|
||||||
Name.identifier(operationReference.getText()) :
|
|
||||||
OperatorConventions.getNameForOperationSymbol((KtToken) operationReference.getReferencedNameElementType());
|
|
||||||
|
|
||||||
KtExpression left = binaryExpression.getLeft();
|
|
||||||
KtExpression right = binaryExpression.getRight();
|
|
||||||
if (left != null && right != null) {
|
|
||||||
trace.report(UNSAFE_INFIX_CALL.on(reference, left.getText(), operationString.asString(), right.getText()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (isCallForImplicitInvoke) {
|
else if (isCallForImplicitInvoke) {
|
||||||
trace.report(UNSAFE_IMPLICIT_INVOKE_CALL.on(reference, type));
|
trace.report(UNSAFE_IMPLICIT_INVOKE_CALL.on(reference, type));
|
||||||
@@ -195,6 +184,30 @@ public abstract class AbstractTracingStrategy implements TracingStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void reportUnsafeCallOnBinaryExpression(@NotNull BindingTrace trace, @NotNull KtBinaryExpression binaryExpression) {
|
||||||
|
KtSimpleNameExpression operationReference = binaryExpression.getOperationReference();
|
||||||
|
boolean isInfixCall = operationReference.getReferencedNameElementType() == KtTokens.IDENTIFIER;
|
||||||
|
Name operationString = isInfixCall ?
|
||||||
|
Name.identifier(operationReference.getText()) :
|
||||||
|
OperatorConventions.getNameForOperationSymbol((KtToken) operationReference.getReferencedNameElementType());
|
||||||
|
|
||||||
|
if (operationString == null) return;
|
||||||
|
|
||||||
|
KtExpression left = binaryExpression.getLeft();
|
||||||
|
KtExpression right = binaryExpression.getRight();
|
||||||
|
if (left == null || right == null) return;
|
||||||
|
|
||||||
|
if (isInfixCall) {
|
||||||
|
trace.report(UNSAFE_INFIX_CALL.on(reference, left, operationString.asString(), right));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
boolean inOperation = KtPsiUtil.isInOrNotInOperation(binaryExpression);
|
||||||
|
KtExpression receiver = inOperation ? right : left;
|
||||||
|
KtExpression argument = inOperation ? left : right;
|
||||||
|
trace.report(UNSAFE_OPERATOR_CALL.on(reference, receiver, operationString.asString(), argument));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invisibleMember(@NotNull BindingTrace trace, @NotNull DeclarationDescriptorWithVisibility descriptor) {
|
public void invisibleMember(@NotNull BindingTrace trace, @NotNull DeclarationDescriptorWithVisibility descriptor) {
|
||||||
trace.report(INVISIBLE_MEMBER.on(call.getCallElement(), descriptor, descriptor.getVisibility(), descriptor));
|
trace.report(INVISIBLE_MEMBER.on(call.getCallElement(), descriptor, descriptor.getVisibility(), descriptor));
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
class A() {
|
class A() {
|
||||||
override fun equals(other : Any?) : Boolean = false
|
override fun equals(other : Any?) : Boolean = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun f(): Unit {
|
fun f(): Unit {
|
||||||
var x: Int? = <!VARIABLE_WITH_REDUNDANT_INITIALIZER!>1<!>
|
var x: Int? = <!VARIABLE_WITH_REDUNDANT_INITIALIZER!>1<!>
|
||||||
x = null
|
x = null
|
||||||
<!DEBUG_INFO_CONSTANT!>x<!> + 1
|
<!DEBUG_INFO_CONSTANT!>x<!> + 1
|
||||||
<!DEBUG_INFO_CONSTANT!>x<!> <!INFIX_MODIFIER_REQUIRED!>plus<!> 1
|
<!DEBUG_INFO_CONSTANT!>x<!> <!INFIX_MODIFIER_REQUIRED!>plus<!> 1
|
||||||
<!DEBUG_INFO_CONSTANT!>x<!> <!UNSAFE_INFIX_CALL!><<!> 1
|
<!DEBUG_INFO_CONSTANT!>x<!> <!UNSAFE_OPERATOR_CALL!><<!> 1
|
||||||
<!TYPE_MISMATCH!><!DEBUG_INFO_CONSTANT!>x<!> += 1<!>
|
<!TYPE_MISMATCH!><!DEBUG_INFO_CONSTANT!>x<!> += 1<!>
|
||||||
|
|
||||||
<!DEBUG_INFO_CONSTANT!>x<!> == 1
|
<!DEBUG_INFO_CONSTANT!>x<!> == 1
|
||||||
<!DEBUG_INFO_CONSTANT!>x<!> != 1
|
<!DEBUG_INFO_CONSTANT!>x<!> != 1
|
||||||
|
|
||||||
<!EQUALITY_NOT_APPLICABLE!>A() == 1<!>
|
<!EQUALITY_NOT_APPLICABLE!>A() == 1<!>
|
||||||
|
|
||||||
<!EQUALITY_NOT_APPLICABLE!><!DEBUG_INFO_CONSTANT!>x<!> === "1"<!>
|
<!EQUALITY_NOT_APPLICABLE!><!DEBUG_INFO_CONSTANT!>x<!> === "1"<!>
|
||||||
<!EQUALITY_NOT_APPLICABLE!><!DEBUG_INFO_CONSTANT!>x<!> !== "1"<!>
|
<!EQUALITY_NOT_APPLICABLE!><!DEBUG_INFO_CONSTANT!>x<!> !== "1"<!>
|
||||||
|
|
||||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!><!DEBUG_INFO_CONSTANT!>x<!> === 1<!>
|
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!><!DEBUG_INFO_CONSTANT!>x<!> === 1<!>
|
||||||
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!><!DEBUG_INFO_CONSTANT!>x<!> !== 1<!>
|
<!IMPLICIT_BOXING_IN_IDENTITY_EQUALS!><!DEBUG_INFO_CONSTANT!>x<!> !== 1<!>
|
||||||
|
|
||||||
<!DEBUG_INFO_CONSTANT!>x<!><!UNSAFE_INFIX_CALL!>..<!>2
|
<!DEBUG_INFO_CONSTANT!>x<!><!UNSAFE_OPERATOR_CALL!>..<!>2
|
||||||
<!TYPE_MISMATCH, DEBUG_INFO_CONSTANT!>x<!> in 1..2
|
<!TYPE_MISMATCH, DEBUG_INFO_CONSTANT!>x<!> in 1..2
|
||||||
|
|
||||||
val y : Boolean? = true
|
val y : Boolean? = true
|
||||||
<!UNUSED_EXPRESSION!>false || <!TYPE_MISMATCH!>y<!><!>
|
<!UNUSED_EXPRESSION!>false || <!TYPE_MISMATCH!>y<!><!>
|
||||||
<!UNUSED_EXPRESSION!><!TYPE_MISMATCH!>y<!> && true<!>
|
<!UNUSED_EXPRESSION!><!TYPE_MISMATCH!>y<!> && true<!>
|
||||||
<!UNUSED_EXPRESSION!><!TYPE_MISMATCH!>y<!> && <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!><!>
|
<!UNUSED_EXPRESSION!><!TYPE_MISMATCH!>y<!> && <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!><!>
|
||||||
}
|
}
|
||||||
+7
-7
@@ -1,7 +1,7 @@
|
|||||||
class A() {
|
class A() {
|
||||||
operator infix fun plus(<!UNUSED_PARAMETER!>i<!> : Int) {}
|
operator infix fun plus(<!UNUSED_PARAMETER!>i<!> : Int) {}
|
||||||
operator fun unaryMinus() {}
|
operator fun unaryMinus() {}
|
||||||
operator infix fun contains(<!UNUSED_PARAMETER!>a<!> : Any?) : Boolean = true
|
operator infix fun contains(<!UNUSED_PARAMETER!>a<!> : Any?) : Boolean = true
|
||||||
}
|
}
|
||||||
|
|
||||||
operator infix fun A.div(<!UNUSED_PARAMETER!>i<!> : Int) {}
|
operator infix fun A.div(<!UNUSED_PARAMETER!>i<!> : Int) {}
|
||||||
@@ -10,7 +10,7 @@ operator infix fun A?.times(<!UNUSED_PARAMETER!>i<!> : Int) {}
|
|||||||
fun test(x : Int?, a : A?) {
|
fun test(x : Int?, a : A?) {
|
||||||
x<!UNSAFE_CALL!>.<!>plus(1)
|
x<!UNSAFE_CALL!>.<!>plus(1)
|
||||||
x?.plus(1)
|
x?.plus(1)
|
||||||
x <!UNSAFE_INFIX_CALL!>+<!> 1
|
x <!UNSAFE_OPERATOR_CALL!>+<!> 1
|
||||||
<!UNSAFE_CALL!>-<!>x
|
<!UNSAFE_CALL!>-<!>x
|
||||||
x<!UNSAFE_CALL!>.<!>unaryMinus()
|
x<!UNSAFE_CALL!>.<!>unaryMinus()
|
||||||
x?.unaryMinus()
|
x?.unaryMinus()
|
||||||
@@ -18,13 +18,13 @@ fun test(x : Int?, a : A?) {
|
|||||||
a<!UNSAFE_CALL!>.<!>plus(1)
|
a<!UNSAFE_CALL!>.<!>plus(1)
|
||||||
a?.plus(1)
|
a?.plus(1)
|
||||||
a <!UNSAFE_INFIX_CALL!>plus<!> 1
|
a <!UNSAFE_INFIX_CALL!>plus<!> 1
|
||||||
a <!UNSAFE_INFIX_CALL!>+<!> 1
|
a <!UNSAFE_OPERATOR_CALL!>+<!> 1
|
||||||
<!UNSAFE_CALL!>-<!>a
|
<!UNSAFE_CALL!>-<!>a
|
||||||
a<!UNSAFE_CALL!>.<!>unaryMinus()
|
a<!UNSAFE_CALL!>.<!>unaryMinus()
|
||||||
a?.unaryMinus()
|
a?.unaryMinus()
|
||||||
|
|
||||||
a<!UNSAFE_CALL!>.<!>div(1)
|
a<!UNSAFE_CALL!>.<!>div(1)
|
||||||
a <!UNSAFE_INFIX_CALL!>/<!> 1
|
a <!UNSAFE_OPERATOR_CALL!>/<!> 1
|
||||||
a <!UNSAFE_INFIX_CALL!>div<!> 1
|
a <!UNSAFE_INFIX_CALL!>div<!> 1
|
||||||
a?.div(1)
|
a?.div(1)
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ fun test(x : Int?, a : A?) {
|
|||||||
a times 1
|
a times 1
|
||||||
a?.times(1)
|
a?.times(1)
|
||||||
|
|
||||||
1 <!UNSAFE_INFIX_CALL!>in<!> a
|
1 <!UNSAFE_OPERATOR_CALL!>in<!> a
|
||||||
a <!UNSAFE_INFIX_CALL!>contains<!> 1
|
a <!UNSAFE_INFIX_CALL!>contains<!> 1
|
||||||
a<!UNSAFE_CALL!>.<!>contains(1)
|
a<!UNSAFE_CALL!>.<!>contains(1)
|
||||||
a?.contains(1)
|
a?.contains(1)
|
||||||
|
|||||||
@@ -7,15 +7,15 @@ fun baz(a: Int, b: Int, c: Int, d: Int) = a + b + c + d
|
|||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val x: Int? = 0
|
val x: Int? = 0
|
||||||
|
|
||||||
bar(if (x != null) x else return, x)
|
bar(if (x != null) x else return, x)
|
||||||
x + 2
|
x + 2
|
||||||
bar(x, x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
|
bar(x, x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
|
||||||
|
|
||||||
val y: Int? = 0
|
val y: Int? = 0
|
||||||
val z: Int? = 0
|
val z: Int? = 0
|
||||||
bar(if (y != null) y else <!TYPE_MISMATCH!>z<!>, <!TYPE_MISMATCH!>y<!>)
|
bar(if (y != null) y else <!TYPE_MISMATCH!>z<!>, <!TYPE_MISMATCH!>y<!>)
|
||||||
y <!UNSAFE_INFIX_CALL!>+<!> 2
|
y <!UNSAFE_OPERATOR_CALL!>+<!> 2
|
||||||
baz(<!TYPE_MISMATCH!>y<!>, <!TYPE_MISMATCH!>y<!>, if (y == null) return else y, y)
|
baz(<!TYPE_MISMATCH!>y<!>, <!TYPE_MISMATCH!>y<!>, if (y == null) return else y, y)
|
||||||
baz(y, z!!, z, y)
|
baz(y, z!!, z, y)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -37,7 +37,7 @@ fun test() {
|
|||||||
1 + platformJ
|
1 + platformJ
|
||||||
|
|
||||||
platformNN + 1
|
platformNN + 1
|
||||||
platformN <!UNSAFE_INFIX_CALL!>+<!> 1
|
platformN <!UNSAFE_OPERATOR_CALL!>+<!> 1
|
||||||
platformJ + 1
|
platformJ + 1
|
||||||
|
|
||||||
1 <!INFIX_MODIFIER_REQUIRED!>plus<!> platformNN
|
1 <!INFIX_MODIFIER_REQUIRED!>plus<!> platformNN
|
||||||
@@ -49,6 +49,6 @@ fun test() {
|
|||||||
platformJ <!INFIX_MODIFIER_REQUIRED!>plus<!> 1
|
platformJ <!INFIX_MODIFIER_REQUIRED!>plus<!> 1
|
||||||
|
|
||||||
platformNN += 1
|
platformNN += 1
|
||||||
platformN <!UNSAFE_INFIX_CALL!>+=<!> 1
|
platformN <!UNSAFE_OPERATOR_CALL!>+=<!> 1
|
||||||
platformJ += 1
|
platformJ += 1
|
||||||
}
|
}
|
||||||
@@ -11,8 +11,8 @@ operator fun Int?.contains(<!UNUSED_PARAMETER!>x<!> : Int) : Boolean = false
|
|||||||
fun f(): Unit {
|
fun f(): Unit {
|
||||||
var set : Set? = null
|
var set : Set? = null
|
||||||
val i : Int? = null
|
val i : Int? = null
|
||||||
i <!UNSAFE_INFIX_CALL!>+<!> 1
|
i <!UNSAFE_OPERATOR_CALL!>+<!> 1
|
||||||
set + 1
|
set + 1
|
||||||
1 <!UNSAFE_INFIX_CALL!>in<!> set
|
1 <!UNSAFE_OPERATOR_CALL!>in<!> set
|
||||||
1 in 2
|
1 in 2
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -22,13 +22,13 @@ fun testDataFlowInfo1(a: Int?, b: Int?) {
|
|||||||
val c: Int = a ?: b!!
|
val c: Int = a ?: b!!
|
||||||
doInt(c)
|
doInt(c)
|
||||||
// b is nullable if a != null
|
// b is nullable if a != null
|
||||||
b <!UNSAFE_INFIX_CALL!>+<!> 1
|
b <!UNSAFE_OPERATOR_CALL!>+<!> 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testDataFlowInfo2(a: Int?, b: Int?) {
|
fun testDataFlowInfo2(a: Int?, b: Int?) {
|
||||||
doInt(a ?: b!!)
|
doInt(a ?: b!!)
|
||||||
// b is nullable if a != null
|
// b is nullable if a != null
|
||||||
b <!UNSAFE_INFIX_CALL!>+<!> 1
|
b <!UNSAFE_OPERATOR_CALL!>+<!> 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testTypeMismatch(a: String?, b: Any) {
|
fun testTypeMismatch(a: String?, b: Any) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ fun foo(): Int {
|
|||||||
k.run()
|
k.run()
|
||||||
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
|
val d: Int = <!DEBUG_INFO_SMARTCAST!>c<!>
|
||||||
// a is not null because of k constructor, but we do not know it
|
// a is not null because of k constructor, but we do not know it
|
||||||
return a <!UNSAFE_INFIX_CALL!>+<!> d
|
return a <!UNSAFE_OPERATOR_CALL!>+<!> d
|
||||||
}
|
}
|
||||||
else return -1
|
else return -1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -498,6 +498,7 @@ fun main(args: Array<String>) {
|
|||||||
model("checker/scripts", extension = "kts")
|
model("checker/scripts", extension = "kts")
|
||||||
model("checker/duplicateJvmSignature")
|
model("checker/duplicateJvmSignature")
|
||||||
model("checker/infos", testMethod = "doTestWithInfos")
|
model("checker/infos", testMethod = "doTestWithInfos")
|
||||||
|
model("checker/diagnosticsMessage")
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractJavaAgainstKotlinSourceCheckerTest> {
|
testClass<AbstractJavaAgainstKotlinSourceCheckerTest> {
|
||||||
|
|||||||
@@ -215,18 +215,22 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
UNSAFE_CALL.registerFactory(SurroundWithNullCheckFix)
|
UNSAFE_CALL.registerFactory(SurroundWithNullCheckFix)
|
||||||
UNSAFE_IMPLICIT_INVOKE_CALL.registerFactory(SurroundWithNullCheckFix)
|
UNSAFE_IMPLICIT_INVOKE_CALL.registerFactory(SurroundWithNullCheckFix)
|
||||||
UNSAFE_INFIX_CALL.registerFactory(SurroundWithNullCheckFix)
|
UNSAFE_INFIX_CALL.registerFactory(SurroundWithNullCheckFix)
|
||||||
|
UNSAFE_OPERATOR_CALL.registerFactory(SurroundWithNullCheckFix)
|
||||||
ITERATOR_ON_NULLABLE.registerFactory(SurroundWithNullCheckFix.IteratorOnNullableFactory)
|
ITERATOR_ON_NULLABLE.registerFactory(SurroundWithNullCheckFix.IteratorOnNullableFactory)
|
||||||
TYPE_MISMATCH.registerFactory(SurroundWithNullCheckFix.TypeMismatchFactory)
|
TYPE_MISMATCH.registerFactory(SurroundWithNullCheckFix.TypeMismatchFactory)
|
||||||
|
|
||||||
UNSAFE_CALL.registerFactory(WrapWithSafeLetCallFix.UnsafeFactory)
|
UNSAFE_CALL.registerFactory(WrapWithSafeLetCallFix.UnsafeFactory)
|
||||||
UNSAFE_IMPLICIT_INVOKE_CALL.registerFactory(WrapWithSafeLetCallFix.UnsafeFactory)
|
UNSAFE_IMPLICIT_INVOKE_CALL.registerFactory(WrapWithSafeLetCallFix.UnsafeFactory)
|
||||||
UNSAFE_INFIX_CALL.registerFactory(WrapWithSafeLetCallFix.UnsafeFactory)
|
UNSAFE_INFIX_CALL.registerFactory(WrapWithSafeLetCallFix.UnsafeFactory)
|
||||||
|
UNSAFE_OPERATOR_CALL.registerFactory(WrapWithSafeLetCallFix.UnsafeFactory)
|
||||||
TYPE_MISMATCH.registerFactory(WrapWithSafeLetCallFix.TypeMismatchFactory)
|
TYPE_MISMATCH.registerFactory(WrapWithSafeLetCallFix.TypeMismatchFactory)
|
||||||
|
|
||||||
UNSAFE_CALL.registerFactory(AddExclExclCallFix)
|
UNSAFE_CALL.registerFactory(AddExclExclCallFix)
|
||||||
UNSAFE_INFIX_CALL.registerFactory(AddExclExclCallFix)
|
UNSAFE_INFIX_CALL.registerFactory(AddExclExclCallFix)
|
||||||
|
UNSAFE_OPERATOR_CALL.registerFactory(AddExclExclCallFix)
|
||||||
UNNECESSARY_NOT_NULL_ASSERTION.registerFactory(RemoveExclExclCallFix)
|
UNNECESSARY_NOT_NULL_ASSERTION.registerFactory(RemoveExclExclCallFix)
|
||||||
UNSAFE_INFIX_CALL.registerFactory(ReplaceInfixOrOperatorCallFix)
|
UNSAFE_INFIX_CALL.registerFactory(ReplaceInfixOrOperatorCallFix)
|
||||||
|
UNSAFE_OPERATOR_CALL.registerFactory(ReplaceInfixOrOperatorCallFix)
|
||||||
UNSAFE_CALL.registerFactory(ReplaceInfixOrOperatorCallFix) // [] only
|
UNSAFE_CALL.registerFactory(ReplaceInfixOrOperatorCallFix) // [] only
|
||||||
UNSAFE_IMPLICIT_INVOKE_CALL.registerFactory(ReplaceInfixOrOperatorCallFix)
|
UNSAFE_IMPLICIT_INVOKE_CALL.registerFactory(ReplaceInfixOrOperatorCallFix)
|
||||||
UNSAFE_CALL.registerFactory(ReplaceWithSafeCallForScopeFunctionFix)
|
UNSAFE_CALL.registerFactory(ReplaceWithSafeCallForScopeFunctionFix)
|
||||||
|
|||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
fun call() {
|
||||||
|
val list : String? = "sdfknsdkfm"
|
||||||
|
"x" <error descr="[UNSAFE_OPERATOR_CALL] Operator call corresponds to a dot-qualified call 'list.contains(\"x\")' which is not allowed on a nullable receiver 'list'.">in</error> list
|
||||||
|
|
||||||
|
"x" <error descr="[UNSAFE_OPERATOR_CALL] Operator call corresponds to a dot-qualified call 'list.contains(\"x\")' which is not allowed on a nullable receiver 'list'.">!in</error> list
|
||||||
|
}
|
||||||
|
|
||||||
|
<error>operator</error> fun CharSequence.contains(<warning>other</warning>: CharSequence, <warning>ignoreCase</warning>: Boolean = false): Boolean = true
|
||||||
@@ -977,4 +977,19 @@ public class PsiCheckerTestGenerated extends AbstractPsiCheckerTest {
|
|||||||
doTestWithInfos(fileName);
|
doTestWithInfos(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/checker/diagnosticsMessage")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class DiagnosticsMessage extends AbstractPsiCheckerTest {
|
||||||
|
public void testAllFilesPresentInDiagnosticsMessage() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/checker/diagnosticsMessage"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("operatorCallDiagnosticsOnInOperator.kt")
|
||||||
|
public void testOperatorCallDiagnosticsOnInOperator() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/diagnosticsMessage/operatorCallDiagnosticsOnInOperator.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user