FIR IDE: quickfix for WrapWithSafeLetCall
There is some behavior change regarding the new WrapWithSafeLetCall quickfix
1. it now works correctly on binary expressions by wrapping it with `()`
2. it now looks for a nullable position upward and do the modification there,
if possible. For example, consider the following code
```
fun bar(s: String): String = s
fun test(s: String?) {
bar(bar(bar(<caret>s)))
}
```
After applying this fix, FE1.0 yields
```
bar(bar(s?.let { bar(it) }))
```
while the new implementation yields
```
s?.let { bar(bar(bar(it))) }
```
This behavior aligns with FE1.0 if `bar` accepts nullable values.
This commit is contained in:
committed by
Ilya Kirillov
parent
0eaab6d8a2
commit
e1b542314a
@@ -0,0 +1,12 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface Foo {
|
||||
val f: ((() -> Unit) -> String)?
|
||||
}
|
||||
|
||||
fun test(foo: Foo) {
|
||||
bar(foo.<caret>f {})
|
||||
}
|
||||
|
||||
fun bar(s: String) {}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface Foo {
|
||||
val f: ((() -> Unit) -> String)?
|
||||
}
|
||||
|
||||
fun test(foo: Foo) {
|
||||
foo.f?<caret>.let { bar(it {}) }
|
||||
}
|
||||
|
||||
fun bar(s: String) {}
|
||||
@@ -0,0 +1,14 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
// ERROR: Type mismatch: inferred type is String? but String was expected
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface Foo {
|
||||
val f: ((() -> Unit) -> String)?
|
||||
}
|
||||
|
||||
fun test(foo: Foo) {
|
||||
bar(foo.<caret>f {})
|
||||
}
|
||||
|
||||
fun bar(s: String) {}
|
||||
@@ -0,0 +1,14 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
// ERROR: Type mismatch: inferred type is String? but String was expected
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface Foo {
|
||||
val f: ((() -> Unit) -> String)?
|
||||
}
|
||||
|
||||
fun test(foo: Foo) {
|
||||
bar(foo.f?.let { it {} })
|
||||
}
|
||||
|
||||
fun bar(s: String) {}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun Int.foo(x: Int) = this + x
|
||||
|
||||
val arg: Int? = 42
|
||||
|
||||
val res = 24.hashCode().foo(<caret>arg) + 1
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun Int.foo(x: Int) = this + x
|
||||
|
||||
val arg: Int? = 42
|
||||
|
||||
val res = arg?.let { 24.hash<caret>Code().foo(it) + 1 }
|
||||
@@ -1,8 +1,9 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
// ERROR: Operator call corresponds to a dot-qualified call 'arg?.let { 24.hashCode().foo(it) }.plus(1)' which is not allowed on a nullable receiver 'arg?.let { 24.hashCode().foo(it) }'.
|
||||
|
||||
fun Int.foo(x: Int) = this + x
|
||||
|
||||
val arg: Int? = 42
|
||||
|
||||
val res = 24.hashCode().foo(<caret>arg)
|
||||
val res = 24.hashCode().foo(<caret>arg) + 1
|
||||
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
// ERROR: Operator call corresponds to a dot-qualified call 'arg?.let { 24.hashCode().foo(it) }.plus(1)' which is not allowed on a nullable receiver 'arg?.let { 24.hashCode().foo(it) }'.
|
||||
|
||||
fun Int.foo(x: Int) = this + x
|
||||
|
||||
val arg: Int? = 42
|
||||
|
||||
val res = arg?.let { 24.hashCode().foo(it) }
|
||||
val res = arg?.let { 24.hashCode().foo(it) } + 1
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
// ERROR: Operator call corresponds to a dot-qualified call 'arg?.let { 24.hashCode().foo(it) }.plus(1)' which is not allowed on a nullable receiver 'arg?.let { 24.hashCode().foo(it) }'.
|
||||
|
||||
fun Int.foo(x: Int) = this + x
|
||||
|
||||
val arg: Int? = 42
|
||||
|
||||
val res: Int = 24.hashCode().foo(<caret>arg) + 1
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
// ERROR: Operator call corresponds to a dot-qualified call 'arg?.let { 24.hashCode().foo(it) }.plus(1)' which is not allowed on a nullable receiver 'arg?.let { 24.hashCode().foo(it) }'.
|
||||
|
||||
fun Int.foo(x: Int) = this + x
|
||||
|
||||
val arg: Int? = 42
|
||||
|
||||
val res: Int = arg?.let { 24.hashCode().foo(it) } + 1
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// ACTION: Add non-null asserted (!!) call
|
||||
// ACTION: Replace overloaded operator with function call
|
||||
// ACTION: Replace with safe (?.) call
|
||||
// ACTION: Surround with null check
|
||||
|
||||
fun test(l: List<String>?, s: String) {
|
||||
if (s <caret>in l) {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// ACTION: Add non-null asserted (!!) call
|
||||
// ACTION: Replace overloaded operator with function call
|
||||
// ACTION: Replace with safe (?.) call
|
||||
// ACTION: Surround with null check
|
||||
|
||||
fun test(l: List<String>?, s: String) {
|
||||
l?.let<caret> { if (s in it) {} }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Wrap with '?.let { ... }' call" "false"
|
||||
// ACTION: Add non-null asserted (!!) call
|
||||
// ACTION: Replace overloaded operator with function call
|
||||
// ACTION: Replace with safe (?.) call
|
||||
// ACTION: Surround with null check
|
||||
// ERROR: Operator call corresponds to a dot-qualified call 'l.contains(s)' which is not allowed on a nullable receiver 'l'.
|
||||
|
||||
fun test(l: List<String>?, s: String) {
|
||||
if (s <caret>in l) {}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo(x: String?, y: String) {
|
||||
y.let { bar(<caret>x, it) }
|
||||
}
|
||||
|
||||
fun bar(s: String, t: String) = s.hashCode() + t.hashCode()
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo(x: String?, y: String) {
|
||||
y.let { x?.l<caret>et { s -> bar(s, it) } }
|
||||
}
|
||||
|
||||
fun bar(s: String, t: String) = s.hashCode() + t.hashCode()
|
||||
@@ -0,0 +1,11 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
val it = ""
|
||||
|
||||
fun test(s: String?) {
|
||||
val name = ""
|
||||
bar(<caret>s)
|
||||
}
|
||||
|
||||
fun bar(name: String) {}
|
||||
@@ -0,0 +1,11 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
val it = ""
|
||||
|
||||
fun test(s: String?) {
|
||||
val name = ""
|
||||
s?.let { it1 -> bar(it1) }
|
||||
}
|
||||
|
||||
fun bar(name: String) {}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface A
|
||||
|
||||
operator fun A?.plus(a: A?): A? = this
|
||||
|
||||
fun test(a1: A, a2: A) {
|
||||
notNull(<caret>a1 + a2)
|
||||
}
|
||||
|
||||
fun notNull(t: A): A = t
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface A
|
||||
|
||||
operator fun A?.plus(a: A?): A? = this
|
||||
|
||||
fun test(a1: A, a2: A) {
|
||||
(a1 + a2<caret>)?.let { notNull(it) }
|
||||
}
|
||||
|
||||
fun notNull(t: A): A = t
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface A
|
||||
|
||||
operator fun A?.plus(a: A?): A? = this
|
||||
|
||||
fun test(a1: A, a2: A) {
|
||||
notNull(<caret>a1 + a2)
|
||||
}
|
||||
|
||||
fun notNull(t: A): A = t
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface A
|
||||
|
||||
operator fun A?.plus(a: A?): A? = this
|
||||
|
||||
fun test(a1: A, a2: A) {
|
||||
a1 + a2?.let { notNull(it) }
|
||||
}
|
||||
|
||||
fun notNull(t: A): A = t
|
||||
@@ -0,0 +1,16 @@
|
||||
// "Wrap with '?.let { ... }' call" "false"
|
||||
// ACTION: Add non-null asserted (!!) call
|
||||
// ACTION: Convert to run
|
||||
// ACTION: Convert to with
|
||||
// ACTION: Replace with safe (?.) call
|
||||
// ACTION: Surround with null check
|
||||
// ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type B?
|
||||
// WITH_RUNTIME
|
||||
|
||||
class A {
|
||||
fun foo() {}
|
||||
}
|
||||
class B(val a: A)
|
||||
fun test(b: B?) {
|
||||
b<caret>.a.foo() // b.a is UNSAFE_CALL
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface Str {
|
||||
val foo: (() -> Unit)?
|
||||
}
|
||||
|
||||
object Str2 {
|
||||
val foo2: (Str.() -> Unit)? = null
|
||||
|
||||
fun bar(s: Str) {
|
||||
s.<caret>foo()
|
||||
}
|
||||
}
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface Str {
|
||||
val foo: (() -> Unit)?
|
||||
}
|
||||
|
||||
object Str2 {
|
||||
val foo2: (Str.() -> Unit)? = null
|
||||
|
||||
fun bar(s: Str) {
|
||||
s.foo?.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface Str {
|
||||
val foo: (() -> Unit)?
|
||||
}
|
||||
|
||||
object Str2 {
|
||||
val foo2: (Str.() -> Unit)? = null
|
||||
|
||||
fun bar(s: Str) {
|
||||
s.<caret>foo2()
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface Str {
|
||||
val foo: (() -> Unit)?
|
||||
}
|
||||
|
||||
object Str2 {
|
||||
val foo2: (Str.() -> Unit)? = null
|
||||
|
||||
fun bar(s: Str) {
|
||||
fo<caret>o2?.let { s.it() }
|
||||
}
|
||||
}
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface Str {
|
||||
val foo: (() -> Unit)?
|
||||
}
|
||||
|
||||
object Str2 {
|
||||
val foo2: (Str.() -> Unit)? = null
|
||||
|
||||
fun bar(s: Str) {
|
||||
s.<caret>foo2()
|
||||
}
|
||||
}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// ERROR: Expression 'it' of type 'Unit' cannot be invoked as a function. The function 'invoke()' is not found
|
||||
// ERROR: Function invocation 'foo2()' expected
|
||||
// ERROR: Reference has a nullable type '(Str.() -> Unit)?', use explicit '?.invoke()' to make a function-like call instead
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface Str {
|
||||
val foo: (() -> Unit)?
|
||||
}
|
||||
|
||||
object Str2 {
|
||||
val foo2: (Str.() -> Unit)? = null
|
||||
|
||||
fun bar(s: Str) {
|
||||
s.foo2?.let { it() }
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Wrap with '?.let { ... }' call" "false"
|
||||
// ACTION: Add 's =' to argument
|
||||
// ACTION: Add non-null asserted (!!) call
|
||||
// ACTION: Replace with safe (?.) call
|
||||
// ACTION: Surround with null check
|
||||
// DISABLE-ERRORS
|
||||
// WITH_RUNTIME
|
||||
fun foo(s: String?) {}
|
||||
|
||||
fun bar(s: String?) {
|
||||
foo(s<caret>.substring(1))
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?) {
|
||||
nullable(nullable(notNull(notNull(<caret>s))))
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
fun nullable(name: String?): String = ""
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?) {
|
||||
nullable(nullable(s?.let { notNull<caret>(notNull(it)) }))
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
fun nullable(name: String?): String = ""
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?) {
|
||||
nullable(nullable(notNull(notNull(<caret>s))))
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
fun nullable(name: String?): String = ""
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
// ERROR: Type mismatch: inferred type is String? but String was expected
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?) {
|
||||
nullable(nullable(notNull(s?.let { notNull(it) })))
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
fun nullable(name: String?): String = ""
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?) {
|
||||
val s2 = notNull(notNull(<caret>s))
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?) {
|
||||
val s2 = s?.let { notNull<caret>(notNull(it)) }
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?) {
|
||||
val s2 = notNull(notNull(<caret>s))
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
// ERROR: Type mismatch: inferred type is String? but String was expected
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?) {
|
||||
val s2 = notNull(s?.let { notNull(it) })
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?) {
|
||||
notNull(notNull(<caret>s))
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?) {
|
||||
s?.let { notNull<caret>(notNull(it)) }
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?) {
|
||||
notNull(notNull(<caret>s))
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
// ERROR: Type mismatch: inferred type is String? but String was expected
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?) {
|
||||
notNull(s?.let { notNull(it) })
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?): String? {
|
||||
if (true) {
|
||||
notNull(notNull(<caret>s))
|
||||
}
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?): String? {
|
||||
if (true) {
|
||||
s?.let { notNull<caret>(notNull(it)) }
|
||||
}
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?): String? {
|
||||
if (true) {
|
||||
notNull(notNull(<caret>s))
|
||||
}
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
// ERROR: A 'return' expression required in a function with a block body ('{...}')
|
||||
// ERROR: Type mismatch: inferred type is String? but String was expected
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?): String? {
|
||||
if (true) {
|
||||
notNull(s?.let { notNull(it) })
|
||||
}
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?): String {
|
||||
while (true) notNull(notNull(<caret>s))
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?): String {
|
||||
while (true) s?.let { notNull<caret>(notNull(it)) }
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?): String {
|
||||
while (true) notNull(notNull(<caret>s))
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
// ERROR: Type mismatch: inferred type is String? but String was expected
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test(s: String?): String {
|
||||
while (true) notNull(s?.let { notNull(it) })
|
||||
}
|
||||
|
||||
fun notNull(name: String): String = name
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// ACTION: Add 'a =' to argument
|
||||
// ACTION: Add non-null asserted (!!) call
|
||||
// ACTION: Flip '+'
|
||||
// ACTION: Introduce local variable
|
||||
// ACTION: Replace overloaded operator with function call
|
||||
// ACTION: Replace with safe (?.) call
|
||||
// ACTION: Surround with null check
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface A {
|
||||
operator fun plus(a: A): A = this
|
||||
}
|
||||
|
||||
fun test(a1: A?, a2: A) {
|
||||
notNull(a1 <caret>+ a2)
|
||||
}
|
||||
|
||||
fun notNull(a: A): A = a
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// "Wrap with '?.let { ... }' call" "true"
|
||||
// ACTION: Add 'a =' to argument
|
||||
// ACTION: Add non-null asserted (!!) call
|
||||
// ACTION: Flip '+'
|
||||
// ACTION: Introduce local variable
|
||||
// ACTION: Replace overloaded operator with function call
|
||||
// ACTION: Replace with safe (?.) call
|
||||
// ACTION: Surround with null check
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface A {
|
||||
operator fun plus(a: A): A = this
|
||||
}
|
||||
|
||||
fun test(a1: A?, a2: A) {
|
||||
a1?.let { n<caret>otNull(it + a2) }
|
||||
}
|
||||
|
||||
fun notNull(a: A): A = a
|
||||
@@ -0,0 +1,21 @@
|
||||
// "Wrap with '?.let { ... }' call" "false"
|
||||
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
|
||||
// ACTION: Add 'a =' to argument
|
||||
// ACTION: Add non-null asserted (!!) call
|
||||
// ACTION: Flip '+'
|
||||
// ACTION: Introduce local variable
|
||||
// ACTION: Replace overloaded operator with function call
|
||||
// ACTION: Replace with safe (?.) call
|
||||
// ACTION: Surround with null check
|
||||
// ERROR: Operator call corresponds to a dot-qualified call 'a1.plus(a2)' which is not allowed on a nullable receiver 'a1'.
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface A {
|
||||
operator fun plus(a: A): A = this
|
||||
}
|
||||
|
||||
fun test(a1: A?, a2: A) {
|
||||
notNull(a1 <caret>+ a2)
|
||||
}
|
||||
|
||||
fun notNull(a: A): A = a
|
||||
Reference in New Issue
Block a user