Add IDEA data-flow analysis to guess nullability

Add "if return..." folding to "return if"
This commit is contained in:
Simon Ogorodnik
2017-05-25 15:54:10 +03:00
parent 1f26353de4
commit e41c027c9a
24 changed files with 261 additions and 40 deletions
@@ -0,0 +1,53 @@
public class SomeServiceUsage {
public SomeService getService() {
return SomeService.getInstanceNotNull();
}
public SomeService getServiceNullable() {
return SomeService.getInstanceNullable();
}
// elvis
public SomeService getServiceNotNullByDataFlow() {
SomeService s = SomeService.getInstanceNullable();
return s == null ? SomeService.getInstanceNotNull() : s;
}
// nullable, bang-bang
public String aString1() {
return getServiceNullable().nullableString();
}
// nullable
public String aString2() {
return getService().nullableString();
}
// not nullable
public String aString3() {
return getService().notNullString();
}
// nullable, no bang-bang
public String aString4() {
return getServiceNotNullByDataFlow().nullableString();
}
// not nullable, no bang-bang
public String aString5() {
return getServiceNotNullByDataFlow().notNullString();
}
// nullable, safe-call
public String aString6() {
SomeService s = getServiceNullable();
if (s != null) {
return s.nullableString();
} else {
return null;
}
}
}
@@ -0,0 +1,47 @@
class SomeServiceUsage {
val service: SomeService
get() = SomeService.getInstanceNotNull()
val serviceNullable: SomeService?
get() = SomeService.getInstanceNullable()
// elvis
val serviceNotNullByDataFlow: SomeService
get() {
val s = SomeService.getInstanceNullable()
return s ?: SomeService.getInstanceNotNull()
}
// nullable, bang-bang
fun aString1(): String? {
return serviceNullable!!.nullableString()
}
// nullable
fun aString2(): String? {
return service.nullableString()
}
// not nullable
fun aString3(): String {
return service.notNullString()
}
// nullable, no bang-bang
fun aString4(): String? {
return serviceNotNullByDataFlow.nullableString()
}
// not nullable, no bang-bang
fun aString5(): String {
return serviceNotNullByDataFlow.notNullString()
}
// nullable, safe-call
fun aString6(): String? {
val s = serviceNullable
return s?.nullableString()
}
}
@@ -0,0 +1,26 @@
public class SomeService {
public static SomeService getInstanceNotNull() {
return new SomeService();
}
public static SomeService getInstanceNullable() {
if (Math.random() > 0.5)
return null;
return new SomeService();
}
public String nullableString() {
if (Math.random() < 0.5)
return null;
return Math.random() + "";
}
public String notNullString() {
String s = nullableString();
if (s != null)
return s;
return "null";
}
}
@@ -0,0 +1,26 @@
public class SomeService {
public static SomeService getInstanceNotNull() {
return new SomeService();
}
public static SomeService getInstanceNullable() {
if (Math.random() > 0.5)
return null;
return new SomeService();
}
public String nullableString() {
if (Math.random() < 0.5)
return null;
return Math.random() + "";
}
public String notNullString() {
String s = nullableString();
if (s != null)
return s;
return "null";
}
}