[FIR-TEST] Add new testdata generated after changes in previous commit

This commit is contained in:
Dmitriy Novozhilov
2019-12-11 16:16:22 +03:00
parent e9c02a1cca
commit 2536fa0cd5
4578 changed files with 104067 additions and 1 deletions
@@ -0,0 +1,8 @@
// !WITH_NEW_INFERENCE
fun calc(x: List<String>?, y: Int?): Int {
x?.get(y!! - 1)
// y!! above should not provide smart cast here
val yy: Int = y
return yy + (x?.size ?: 0)
}
@@ -0,0 +1,6 @@
fun calc(x: List<String>?): Int {
// After KT-5840 fix !! assertion should become unnecessary here
x?.get(x!!.size - 1)
// x?. or x!! above should not provide smart cast here
return x.<!INAPPLICABLE_CANDIDATE!>size<!>
}
@@ -0,0 +1,6 @@
fun calc(x: List<String>?): Int {
// x should be non-null in arguments list, despite of a chain
x?.subList(0, 1)?.get(x.size)
// But not here!
return x!!.size
}
@@ -0,0 +1,6 @@
fun calc(x: List<String>?, y: List<Int>?) {
// x and y should be non-null in arguments list, despite of a chains
x?.subList(y?.subList(1, 2)?.get(y.size) ?: 0,
y?.get(0) ?: 1) // But safe call is NECESSARY here for y
?.get(x.size)
}
@@ -0,0 +1,5 @@
fun calc(x: List<String>?): Int {
// x is not-null only inside subList
x?.subList(0, x.size - 1).<!INAPPLICABLE_CANDIDATE!>get<!>(x.<!INAPPLICABLE_CANDIDATE!>size<!>)
return x!!.size
}
@@ -0,0 +1,6 @@
fun calc(x: List<String>?): Int {
// x should be non-null in arguments list, including inner call
x?.get(x.get(x.size - 1).length)
// but not also here!
return x.<!INAPPLICABLE_CANDIDATE!>size<!>
}
@@ -0,0 +1,6 @@
fun String.foo(arg: Int) = this[arg]
fun calc(x: String?) {
// x should be non-null in arguments list
x?.foo(x.length - 1)
}
@@ -0,0 +1,6 @@
fun String.bar(s: String) = s
fun foo(s: String?) {
s?.bar(s)
s?.get(s.length)
}
@@ -0,0 +1,7 @@
fun foo(y: Int) = y
fun calc(x: List<String>?): Int {
foo(x!!.size)
// Here we should have smart cast because of x!!, despite of KT-7204 fixed
return x.size
}
@@ -0,0 +1,4 @@
fun calc(x: List<String>?, y: Int?) {
// Smart cast should work here despite of KT-7204 fixed
x?.subList(0, y!!)?.get(y)
}
@@ -0,0 +1,7 @@
fun String.foo(y: Int) = y
fun calc(x: List<String>?): Int {
"abc".foo(x!!.size)
// Here we should have smart cast because of x!!, despite of KT-7204 fixed
return x.size
}
@@ -0,0 +1,7 @@
// !WITH_NEW_INFERENCE
fun calc(x: List<String>?, y: Int?): Int {
x?.subList(y!! - 1, y)
// y!! above should not provide smart cast here
return y
}
@@ -0,0 +1,8 @@
fun foo(x: String): String? = x
fun calc(x: String?, y: String?): Int {
// Smart cast because of y!! in receiver
x?.subSequence(y!!.subSequence(0, 1).length, y.length)
// No smart cast possible
return y.<!INAPPLICABLE_CANDIDATE!>length<!>
}
@@ -0,0 +1,8 @@
fun foo(y: Int): Int {
return y + 1
}
fun calc(x: List<String>?): Int {
// x should be non-null in arguments list
return foo(x?.get(x.size - 1)!!.length)
}
@@ -0,0 +1,43 @@
// See KT-11007: Wrong smart cast to not-null type after safe calls in if / when expression
val String.copy: String
get() = this
fun foo() {
val s: String? = null
val ss = if (true) {
s?.length
} else {
s?.length
}
ss.<!INAPPLICABLE_CANDIDATE!>hashCode<!>() // Smart-cast to Int, should be unsafe call
val sss = if (true) {
s?.copy
}
else {
s?.copy
}
sss.<!INAPPLICABLE_CANDIDATE!>length<!>
}
class My {
val String.copy2: String
get() = this
fun foo() {
val s: String? = null
val ss = if (true) {
s?.length
} else {
s?.length
}
ss.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
val sss = if (true) {
s?.copy2
}
else {
s?.copy2
}
sss.<!INAPPLICABLE_CANDIDATE!>length<!>
}
}
@@ -0,0 +1,6 @@
fun calc(x: List<String>?) {
// x should be non-null in arguments list, despite of a chain
x?.subList(0, x.size)?.
subList(0, x.size)?.
get(x.size)
}
@@ -0,0 +1,13 @@
// See KT-10056
class Foo(val bar: String)
fun test(foo: Foo?) {
foo?.bar.let {
// Error, foo?.bar is nullable
it.<!INAPPLICABLE_CANDIDATE!>length<!>
// Error, foo is nullable
foo.<!INAPPLICABLE_CANDIDATE!>bar<!>.<!UNRESOLVED_REFERENCE!>length<!>
// Correct
foo?.bar?.length
}
}
@@ -0,0 +1,42 @@
class Bar(val gav: String)
class Foo(val bar: Bar, val nbar: Bar?) {
fun baz(s: String) = if (s != "") Bar(s) else null
}
fun String?.call(f: (String?) -> String?) = f(this)
fun String.notNullLet(f: (String) -> Unit) = f(this)
fun test(foo: Foo?) {
foo?.bar?.gav.let {
// Error, foo?.bar?.gav is nullable
it.<!INAPPLICABLE_CANDIDATE!>length<!>
// Error, foo is nullable
foo.<!INAPPLICABLE_CANDIDATE!>bar<!>.<!UNRESOLVED_REFERENCE!>gav<!>.<!UNRESOLVED_REFERENCE!>length<!>
// Correct
foo?.bar?.gav?.length
}
foo?.bar?.gav.call { it }?.notNullLet {
foo.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
foo.<!INAPPLICABLE_CANDIDATE!>bar<!>.<!UNRESOLVED_REFERENCE!>hashCode<!>()
}
}
fun testNotNull(foo: Foo) {
val s: String? = ""
foo.baz(s!!)?.gav.let {
it.<!INAPPLICABLE_CANDIDATE!>length<!>
// Ok because of foo.
s.length.hashCode()
}
}
fun testNullable(foo: Foo?) {
val s: String? = ""
foo?.baz(s!!)?.gav.let {
it.<!INAPPLICABLE_CANDIDATE!>length<!>
// Ok because of foo?.
s?.length?.hashCode()
}
}
@@ -0,0 +1,11 @@
class Foo(val bar: String?)
fun test(foo: Foo?) {
foo!!.bar.let {
// Correct
foo.bar?.length
// Unnecessary
foo?.bar?.length
}
foo.bar?.length
}
@@ -0,0 +1,25 @@
// FILE: Foo.java
public class Foo {
public String bar;
private Foo(String bar) {
this.bar = bar;
}
public static Foo create(String bar) {
return new Foo(bar);
}
}
// FILE: Test.kt
fun test() {
val foo = Foo.create(null)
foo?.bar.let {
// Error, foo?.bar is nullable
it.<!INAPPLICABLE_CANDIDATE!>length<!>
// Foo is nullable but flexible, so call is considered safe here
foo.bar.length
// Correct
foo?.bar?.length
}
}
@@ -0,0 +1,6 @@
data class MyClass(val x: String?)
fun foo(y: MyClass): Int {
val z = y.x?.subSequence(0, y.x.length)
return z?.length ?: -1
}
@@ -0,0 +1,14 @@
// See KT-7290
class MyClass(val x: String?)
fun foo(y: MyClass?): Int {
// x here is smartcast but y is not
val z = y?.x?.subSequence(0, y.x.length)
// !! is necessary here
y!!.x
return z?.length ?: -1
}
fun bar(y: MyClass?) {
y?.x!!.length
// !! is NOT necessary here, because y?.x != null
y!!.x
}
@@ -0,0 +1,8 @@
fun foo(x: String): String? = x
fun calc(x: String?): Int {
// Smart cast because of x!! in receiver
foo(x!!)?.subSequence(0, x.length)
// Smart cast because of x!! in receiver
return x.length
}
@@ -0,0 +1,8 @@
fun foo(x: String): String? = x
fun calc(x: String?): Int {
// Smart cast because of x!! in receiver
foo(x!!)?.subSequence(0, x.length)?.length
// Smart cast because of x!! in receiver
return x.length
}
@@ -0,0 +1,10 @@
// !WITH_NEW_INFERENCE
fun foo(x: String): String? = x
fun calc(x: String?, y: Int?): Int {
// Smart cast because of x!! in receiver
foo(x!!)?.subSequence(y!!, x.length)?.length
// No smart cast possible
return y
}
@@ -0,0 +1,136 @@
// !WITH_NEW_INFERENCE
// !LANGUAGE: -SafeCastCheckBoundSmartCasts -BooleanElvisBoundSmartCasts
// A set of examples for
// "If the result of a safe call is not null, understand that its receiver is not null"
// and some other improvements for nullability detection
fun kt6840_1(s: String?) {
val hash = s?.hashCode()
if (hash != null) {
s.<!INAPPLICABLE_CANDIDATE!>length<!>
}
}
fun kt6840_2(s: String?) {
if (s?.hashCode() != null) {
s.length
}
}
fun kt1635(s: String?) {
s?.hashCode()!!
s.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
}
fun kt2127() {
val s: String? = ""
if (s?.length != null) {
s.hashCode()
}
}
fun kt3356(s: String?): Int {
if (s?.length != 1) return 0
return s.length
}
open class SomeClass(val data: Any)
class SubClass(val extra: Any, data: Any) : SomeClass(data)
fun kt4565_1(a: SomeClass?) {
val data = a?.data
if (data != null) {
data.hashCode()
a.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
a.<!INAPPLICABLE_CANDIDATE!>data<!>.<!UNRESOLVED_REFERENCE!>hashCode<!>()
}
if (a?.data != null) {
// To be supported (?!)
data.hashCode()
a.hashCode()
a.data.hashCode()
}
if (a?.data is String) {
a.<!INAPPLICABLE_CANDIDATE!>data<!>.<!UNRESOLVED_REFERENCE!>length<!>
data.length
}
}
fun kt4565_2(a: SomeClass?) {
// To be supported
if (a as? SubClass != null) {
a.extra.hashCode()
}
val extra = (a as? SubClass)?.extra
if (extra != null) {
a.<!UNRESOLVED_REFERENCE!>extra<!>.<!UNRESOLVED_REFERENCE!>hashCode<!>()
}
}
class A(val y: Int)
fun kt7491_1() {
val x: A? = A(42)
val z = x?.y ?: return
x.y
}
fun getA(): A? = null
fun useA(a: A): Int = a.hashCode()
fun kt7491_2() {
val a = getA()
(a?.let { useA(a) } ?: a.<!INAPPLICABLE_CANDIDATE!>y<!> ).toString()
}
fun String.correct() = true
fun kt8492(s: String?) {
if (s?.correct() ?: false) {
// To be supported
s.<!INAPPLICABLE_CANDIDATE!>length<!>
}
}
fun kt11085(prop: String?) {
when (prop?.hashCode()) {
1 -> prop.length
}
}
class HttpExchange(val code: String)
fun kt11313(arg: HttpExchange?) {
when (arg?.code) {
"GET" -> handleGet(arg)
"POST" -> handlePost(arg)
}
}
fun handleGet(arg: HttpExchange) = arg
fun handlePost(arg: HttpExchange) = arg
class Wrapper {
fun unwrap(): String? = "Something not consistent"
}
fun falsePositive(w: Wrapper) {
if (w.unwrap() != null) {
// Here we should NOT have smart cast
w.unwrap().<!INAPPLICABLE_CANDIDATE!>length<!>
}
}
class Invokable(val x: String) {
operator fun invoke() = x
}
class InvokableProperty(val i: Invokable)
fun checkInvokable(ip: InvokableProperty?) {
if (ip?.i() == "Hello") {
ip.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
}
}
@@ -0,0 +1,6 @@
fun calc(x: List<String>?): Int {
// x should be non-null in arguments list
x?.get(x.size - 1)
// but not also here!
return x.<!INAPPLICABLE_CANDIDATE!>size<!>
}
@@ -0,0 +1,6 @@
fun Any?.foo(my: My) = my === this
class My(val x: Any)
// my is nullable in brackets because Any?.foo has nullable receiver
fun foo(my: My?) = my?.x.foo(my)
@@ -0,0 +1,6 @@
fun calc(x: List<String>?): Int {
// x should be non-null in arguments list
x?.subList(x.size - 1, x.size)
// but not also here!
return x.<!INAPPLICABLE_CANDIDATE!>size<!>
}