Refactoring: make "if-then to safe access" an inspection

This commit is contained in:
Mikhail Glukhikh
2017-12-19 15:41:09 +03:00
parent 91bcfb97c6
commit a8b01a6b00
86 changed files with 433 additions and 410 deletions
@@ -1 +0,0 @@
org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.IfThenToSafeAccessIntention
@@ -1,11 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun main(args: Array<String>) {
val foo: String? = "abc"
if (foo != null<caret>) {
doSomething ("Hello")
foo.length
}
else null
}
@@ -1,9 +0,0 @@
// IS_APPLICABLE: false
fun main(args: Array<String>) {
var foo: String? = "foo"
var bar: String? = "bar"
if (foo != null<caret>) {
bar?.length
}
else null
}
@@ -1,8 +0,0 @@
// IS_APPLICABLE: false
fun main(args: Array<String>) {
val foo = "foo"
if (null == <caret>null) {
foo.length
}
else null
}
@@ -1,10 +0,0 @@
// IS_APPLICABLE: false
operator fun <T> T.compareTo(a: T): Int = 0
fun main(args: Array<String>) {
val foo = "foo"
if (foo > null<caret>) {
foo.length
}
else null
}
@@ -1,10 +0,0 @@
// IS_APPLICABLE: false
operator fun String?.times(a: Int): Boolean = a == 0
fun main(args: Array<String>) {
val foo: String = "foo"
if (foo * 10<caret>) {
foo.length
}
else null
}
@@ -1,16 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun <T> doSomething(a: T) {}
fun main(args: Array<String>) {
val foo = maybeFoo()
doSomething(foo)
if (foo != null<caret>) {
foo.length
}
else {
null
}
}
@@ -1,11 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun <T> doSomething(a: T) {}
fun main(args: Array<String>) {
val foo = maybeFoo()
doSomething(foo)
foo?.length
}
@@ -1,13 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
val x = maybeFoo()
fun main(args: Array<String>) {
if (x !=<caret> null) {
x.length
} else {
null
}
}
@@ -1,9 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
val x = maybeFoo()
fun main(args: Array<String>) {
x?.length
}
@@ -1,8 +0,0 @@
// IS_APPLICABLE: false
fun main(args: Array<String>) {
val foo = "foo"
if (<caret>) {
foo.length
}
else null
}
@@ -1,15 +0,0 @@
// IS_APPLICABLE: false
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
val foo = maybeFoo()
if (foo != null<caret>) {
foo.length
}
else {
}
}
@@ -1,14 +0,0 @@
// IS_APPLICABLE: false
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
val foo = maybeFoo()
if (foo == null<caret>) {
}
else {
foo.length
}
}
@@ -1,13 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
val foo = maybeFoo()
if (foo != null<caret>) {
foo.length
}
else {
null
}
}
@@ -1,7 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
maybeFoo()?.length
}
@@ -1,11 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
val foo = maybeFoo()
if (foo != null<caret>)
foo.length
else
null
}
@@ -1,7 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
maybeFoo()?.length
}
@@ -1,13 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
val foo = maybeFoo()
val x = if (foo == null<caret>) {
null
}
else {
foo.length
}
}
@@ -1,7 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
val x = maybeFoo()?.length
}
@@ -1,2 +0,0 @@
// WITH_RUNTIME
fun String?.foo() = <caret>if (this == null) null else isEmpty()
@@ -1,2 +0,0 @@
// WITH_RUNTIME
fun String?.foo() = this?.isEmpty()
@@ -1,170 +0,0 @@
<problems>
<problem>
<file>rhsNotEqualsNull.kt</file>
<line>7</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/rhsNotEqualsNull.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>rhsEqualsNull.kt</file>
<line>7</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/rhsEqualsNull.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>noThenBlock.kt</file>
<line>7</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/noThenBlock.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>noElseBlock.kt</file>
<line>7</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/noElseBlock.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>lhsNotEqualsNull.kt</file>
<line>7</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/lhsNotEqualsNull.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>lhsEqualsNull.kt</file>
<line>7</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/lhsEqualsNull.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>ifAsExpression.kt</file>
<line>7</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/ifAsExpression.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>ifAndElseNotInBlocks.kt</file>
<line>7</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/ifAndElseNotInBlocks.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>ifAndElseBothInBlocks.kt</file>
<line>7</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/ifAndElseBothInBlocks.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>doesNotinlineValueOutsideOfScope.kt</file>
<line>8</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/doesNotInlineValueOutsideOfScope.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>doesNotinlineValueIfUsedMoreThanOnce.kt</file>
<line>10</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/doesNotInlineValueIfUsedMoreThanOnce.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>willNotInlineClassProperty.kt</file>
<line>3</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/willNotInlineClassProperty.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>isCondition.kt</file>
<line>1</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/isCondition.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>isNotCondition.kt</file>
<line>1</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/src/isNotCondition.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>nullCheckWithSelectorCallChain.kt</file>
<line>5</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/nullCheckWithSelectorCallChain.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>isCheckWithSelectorChain.kt</file>
<line>4</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/isCheckWithSelectorChain.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>isCheckSimple.kt</file>
<line>4</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/isCheckSimple.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe cast expression</description>
</problem>
<problem>
<file>nullCheckSimple.kt</file>
<line>2</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/nullCheckSimple.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Remove redundant 'if' expression</description>
</problem>
<problem>
<file>implicitReceiver.kt</file>
<line>2</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/implicitReceiver.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe access expression</description>
</problem>
<problem>
<file>property.kt</file>
<line>10</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/property.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Replace 'if' expression with safe cast expression</description>
</problem>
<problem>
<file>propertyNotNull.kt</file>
<line>9</line>
<module>light_idea_test_case</module>
<entry_point TYPE="file" FQNAME="temp:///src/propertyNotNull.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If-Then foldable to '?.'</problem_class>
<description>Remove redundant 'if' expression</description>
</problem>
</problems>
@@ -1,2 +0,0 @@
// INSPECTION_CLASS: org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.IfThenToSafeAccessInspection
// WITH_RUNTIME
@@ -1,5 +0,0 @@
class My(val x: Int)
fun foo(arg: Any?): My? {
return if (<caret>arg is My) arg else null
}
@@ -1,5 +0,0 @@
class My(val x: Int)
fun foo(arg: Any?): My? {
return arg as? My
}
@@ -1,5 +0,0 @@
class My(val x: Int)
fun foo(arg: Any?): Int? {
return if (<caret>arg is My) arg.x.hashCode() else null
}
@@ -1,5 +0,0 @@
class My(val x: Int)
fun foo(arg: Any?): Int? {
return (arg as? My)?.x?.hashCode()
}
@@ -1 +0,0 @@
fun foo(arg: Any) = if (arg is String<caret>) arg.length else null
@@ -1 +0,0 @@
fun foo(arg: Any) = (arg as? String)?.length
@@ -1 +0,0 @@
fun foo(arg: Any) = if (arg !is String<caret>) null else arg.length
@@ -1 +0,0 @@
fun foo(arg: Any) = (arg as? String)?.length
@@ -1,2 +0,0 @@
// IS_APPLICABLE: false
fun foo(arg: Any) = if (arg !is String?<caret>) null else arg?.length
@@ -1,2 +0,0 @@
// IS_APPLICABLE: false
fun foo(arg: Any) = if (arg is String?<caret>) arg?.length else null
@@ -1,11 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
val foo = maybeFoo()
if (foo == null<caret>)
null
else
foo.length
}
@@ -1,7 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
maybeFoo()?.length
}
@@ -1,11 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
val foo = maybeFoo()
if (foo != null<caret>)
foo.length
else
null
}
@@ -1,7 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
maybeFoo()?.length
}
@@ -1,7 +0,0 @@
// IS_APPLICABLE: false
fun main(args: Array<String>) {
val foo = null
if (foo == null<caret>) {
null
}
}
@@ -1,7 +0,0 @@
// IS_APPLICABLE: false
fun main(args: Array<String>) {
val foo = null
if (foo != null<caret>)
else {
}
}
@@ -1,8 +0,0 @@
// IS_APPLICABLE: false
// ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
fun main(args: Array<String>) {
val foo: String? = "foo"
if<caret> {
foo.length
} else null
}
@@ -1,10 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
val foo = maybeFoo()
if (foo != null<caret>) {
foo.length
}
}
@@ -1,7 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
maybeFoo()?.length
}
@@ -1,14 +0,0 @@
// IS_APPLICABLE: false
// ERROR: 'if' must have both main and 'else' branches if used as an expression
// ERROR: Type mismatch: inferred type is Unit but Int was expected
fun maybeFoo(): String? {
return "foo"
}
fun bar(): Int {
val foo = maybeFoo()
return if (foo != null<caret>) {
foo.length
}
}
@@ -1,9 +0,0 @@
// IS_APPLICABLE: false
fun main(args: Array<String>) {
val foo: String? = "foo"
val bar: String? = null
if (foo == bar<caret>) {
foo?.length
}
else null
}
@@ -1,9 +0,0 @@
// IS_APPLICABLE: false
fun main(args: Array<String>) {
val foo: String? = "foo"
val bar: String? = null
if (foo == bar<caret>) {
bar?.length
}
else null
}
@@ -1,10 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
val foo = maybeFoo()
if (foo == null<caret>) else {
foo.length
}
}
@@ -1,7 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
maybeFoo()?.length
}
@@ -1,11 +0,0 @@
//IS_APPLICABLE: false
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
if (maybeFoo() == null<caret>)
null
else
maybeFoo()?.length
}
@@ -1,12 +0,0 @@
//IS_APPLICABLE: false
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
var foo = maybeFoo()
if (foo == null<caret>)
null
else
foo?.length
}
@@ -1,3 +0,0 @@
fun foo(arg: Any?): Any? {
return if (<caret>arg != null) arg else null
}
@@ -1,3 +0,0 @@
fun foo(arg: Any?): Any? {
return arg
}
@@ -1,9 +0,0 @@
// WITH_RUNTIME
val nullableString: String? = "abc"
val foo = if (<caret>nullableString != null) {
nullableString.toUpperCase().toLowerCase()
} else {
null
}
@@ -1,5 +0,0 @@
// WITH_RUNTIME
val nullableString: String? = "abc"
val foo = nullableString?.toUpperCase()?.toLowerCase()
@@ -1,13 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun main(args: Array<String>) {
val foo: String? = "abc"
if (foo != null<caret>) {
foo.length
}
else {
doSomething("Hi")
null
}
}
@@ -1,11 +0,0 @@
// IS_APPLICABLE: true
// INTENTION_TEXT: Replace 'if' expression with safe cast expression
interface Foo
interface Bar : Foo
data class Data(val foo: Foo)
fun handle(data: Data) {
val bar = <caret>if (data.foo is Bar) data.foo else null
}
@@ -1,11 +0,0 @@
// IS_APPLICABLE: true
// INTENTION_TEXT: Replace 'if' expression with safe cast expression
interface Foo
interface Bar : Foo
data class Data(val foo: Foo)
fun handle(data: Data) {
val bar = data.foo as? Bar
}
@@ -1,10 +0,0 @@
// IS_APPLICABLE: true
// INTENTION_TEXT: Remove redundant 'if' expression
interface Bar
data class Data(val bar: Bar?)
fun handle(data: Data) {
val bar = <caret>if (data.bar != null) data.bar else null
}
@@ -1,10 +0,0 @@
// IS_APPLICABLE: true
// INTENTION_TEXT: Remove redundant 'if' expression
interface Bar
data class Data(val bar: Bar?)
fun handle(data: Data) {
val bar = data.bar
}
@@ -1,13 +0,0 @@
// IS_APPLICABLE: false
interface Foo
interface Bar : Foo {
val x: String
}
data class Data(val foo: Foo)
fun handle(data: Data) {
// Not available yet (possible in principle)
val bar = <caret>if (data.foo is Bar) data.foo.x else null
}
@@ -1,11 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
val foo = maybeFoo()
if (null == foo<caret>)
null
else
foo.length
}
@@ -1,7 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
maybeFoo()?.length
}
@@ -1,11 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
val foo = maybeFoo()
if (null != foo<caret>)
foo.length
else
null
}
@@ -1,7 +0,0 @@
fun maybeFoo(): String? {
return "foo"
}
fun main(args: Array<String>) {
maybeFoo()?.length
}
@@ -1,10 +0,0 @@
// IS_APPLICABLE: false
fun main(args: Array<String>) {
val foo: String? = "foo"
<caret>if (foo == null) {
null
}
else {
null
}
}
@@ -1,11 +0,0 @@
// IS_APPLICABLE: false
// ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
fun main(args: Array<String>) {
val foo: String? = "foo"
if (foo == null<caret>) {
foo.length
}
else {
foo.length
}
}
@@ -1,10 +0,0 @@
// IS_APPLICABLE: false
fun main(args: Array<String>) {
val foo: String? = "foo"
if (foo == null<caret>) {
null
}
else {
}
}
@@ -1,10 +0,0 @@
// IS_APPLICABLE: false
fun main(args: Array<String>) {
val foo: String? = "foo"
if (foo != null<caret>) {
}
else {
null
}
}
@@ -1,7 +0,0 @@
// IS_APPLICABLE: false
fun main(args: Array<String>) {
val foo: String? = "foo"
if (foo == null<caret>) {
null
}
}
@@ -1,9 +0,0 @@
// IS_APPLICABLE: false
fun main(args: Array<String>) {
val foo: String? = "foo"
if (foo != null<caret>)
else {
null
}
}
@@ -1,8 +0,0 @@
class F(a: Int?) {
val b = a
val c = if (b !=<caret> null) b.toString() else null
}
fun main(args: Array<String>) {
F(1).c
}
@@ -1,8 +0,0 @@
class F(a: Int?) {
val b = a
val c = b?.toString()
}
fun main(args: Array<String>) {
F(1).c
}