New diagnostic for non-local return annotation

This commit is contained in:
Michael Bogdanov
2014-06-10 11:34:06 +04:00
parent 8092717da4
commit da01a11137
26 changed files with 689 additions and 91 deletions
@@ -1,4 +1,4 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -ONLY_LOCAL_RETURN
fun <T, U> Function1<T, U>.minusAssign(p: Function1<T, U>) {}
@@ -0,0 +1,7 @@
inline fun <R> onlyLocal(p: () -> R) {
inlineAll(<!USAGE_IS_NOT_INLINABLE!>p<!>)
}
<!NOTHING_TO_INLINE!>inline fun <R> inlineAll(noinline p: () -> R)<!> {
p()
}
@@ -0,0 +1,24 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE
import kotlin.InlineOption.*
inline fun <R> inlineFunOnlyLocal(inlineOptions(ONLY_LOCAL_RETURN)p: () -> R) {
val s = object {
val z = p()
fun a() {
p()
}
}
}
inline fun <R> inlineFun(p: () -> R) {
val s = object {
val z = <!NON_LOCAL_RETURN_NOT_ALLOWED!>p<!>()
fun a() {
<!NON_LOCAL_RETURN_NOT_ALLOWED!>p<!>()
}
}
}
@@ -0,0 +1,49 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE
import kotlin.InlineOption.*
inline fun <R> inlineFunOnlyLocal(inlineOptions(ONLY_LOCAL_RETURN)p: () -> R) {
val s = object {
val z = p();
{
doCall {
p()
}
}
fun a() {
doCall {
p()
}
p()
}
}
}
inline fun <R> inlineFun(p: () -> R) {
val s = object {
val z = <!NON_LOCAL_RETURN_NOT_ALLOWED!>p<!>();
{
doCall {
<!NON_LOCAL_RETURN_NOT_ALLOWED!>p<!>()
}
}
fun a() {
doCall {
<!NON_LOCAL_RETURN_NOT_ALLOWED!>p<!>()
}
<!NON_LOCAL_RETURN_NOT_ALLOWED!>p<!>()
}
}
}
inline fun <R> doCall(p: () -> R) {
p()
}
@@ -0,0 +1,43 @@
fun inlineCallExplicitError(): String {
inlineFun @lamba {
if (true) {
<!RETURN_NOT_ALLOWED_EXPLICIT_RETURN_TYPE_REQUIRED!>return@lamba 2<!>
}
1
}
return "x"
}
fun inlineCall(): String {
inlineFun @lamba {
(): Int ->
if (true) {
return@lamba 2
}
1
}
return "x"
}
inline fun inlineFun(s: () -> Int) {
s()
}
fun noInlineCall(): String {
noInline @lambda {
(): Int ->
if (true) {
return@lambda 2
}
1
}
return "x"
}
fun noInline(s: () -> Int) {
s()
}
@@ -0,0 +1,9 @@
import kotlin.InlineOption.*
inline fun <R> onlyLocal(inlineOptions(ONLY_LOCAL_RETURN)p: () -> R) {
inlineAll(p)
}
inline fun <R> inlineAll(p: () -> R) {
p()
}
@@ -0,0 +1,17 @@
import kotlin.InlineOption.*
inline fun <R> inlineFunWithAnnotation(inlineOptions(ONLY_LOCAL_RETURN) p: () -> R) {
inlineFun {
p()
}
}
inline fun <R> inlineFun2(p: () -> R) {
inlineFun {
p()
}
}
inline fun <R> inlineFun(p: () -> R) {
p()
}
@@ -0,0 +1,31 @@
fun inlineCall(): String {
inlineFun {
if (true) {
return@inlineCall ""
}
1
}
return "x"
}
inline fun inlineFun(s: ()->Int) {
s()
}
fun noInlineCall(): String {
noInline {
if (true) {
<!RETURN_NOT_ALLOWED!>return@noInlineCall ""<!>
}
1
}
return "x"
}
fun noInline(s: ()->Int) {
s()
}
@@ -0,0 +1,16 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE
import kotlin.InlineOption.*
inline fun <R> inlineFunOnlyLocal(inlineOptions(ONLY_LOCAL_RETURN)p: () -> R) {
<!NOT_YET_SUPPORTED_IN_INLINE!>fun a() {
val z = p()
}<!>
a()
}
inline fun <R> inlineFun(p: () -> R) {
<!NOT_YET_SUPPORTED_IN_INLINE!>fun a() {
<!NON_LOCAL_RETURN_NOT_ALLOWED!>p<!>()
}<!>
a()
}
@@ -0,0 +1,43 @@
import Kind.EXT_RETURN
import Kind.GLOBAL_RETURN
enum class Kind {
LOCAL
EXT_RETURN
GLOBAL_RETURN
}
class Internal(val value: String)
class External(val value: String)
class Global(val value: String)
fun test1(intKind: Kind, extKind: Kind): Global {
var externalResult = doCall @ext {
() : External ->
val internalResult = doCall @int {
() : Internal ->
if (intKind == Kind.LOCAL) {
return@test1 Global("internal to global")
} else if (intKind == EXT_RETURN) {
return@ext External("internal to external")
}
return@int Internal("internal to local")
}
if (extKind == GLOBAL_RETURN || extKind == EXT_RETURN) {
return Global("external to global")
}
External(internalResult.value + " to local");
}
return Global(externalResult.value + " to exit")
}
public inline fun <R> doCall(block: ()-> R) : R {
return block()
}
@@ -0,0 +1,14 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE
import kotlin.InlineOption.*
inline fun <R> inlineFunOnlyLocal(inlineOptions(ONLY_LOCAL_RETURN)p: () -> R) {
{
p()
}()
}
inline fun <R> inlineFun(p: () -> R) {
{
<!NON_LOCAL_RETURN_NOT_ALLOWED!>p<!>()
}()
}
@@ -0,0 +1,24 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE
import kotlin.InlineOption.*
inline fun <R> inlineFunOnlyLocal(inlineOptions(ONLY_LOCAL_RETURN)p: () -> R) {
<!NOT_YET_SUPPORTED_IN_INLINE!>class A {
val z = p()
fun a() {
p()
}
}<!>
}
inline fun <R> inlineFun(p: () -> R) {
<!NOT_YET_SUPPORTED_IN_INLINE!>class A {
val z = <!NON_LOCAL_RETURN_NOT_ALLOWED!>p<!>()
fun a() {
<!NON_LOCAL_RETURN_NOT_ALLOWED!>p<!>()
}
}<!>
}
@@ -0,0 +1,24 @@
inline fun <R> doCall(p: () -> R) {
p()
}
inline fun <R> doCallInt(p: () -> R): R {
return p()
}
class A {
var result: Int = doCallInt { <!RETURN_NOT_ALLOWED!>return this<!> };
var field: Int
get() {
doCall { return 1 }
return 2
}
set(v: Int) {
doCall {
result = v / 2
return
}
result = v
}
}
@@ -0,0 +1,9 @@
import kotlin.InlineOption.*
inline fun <R> toOnlyLocal(inlineOptions(ONLY_LOCAL_RETURN) p: () -> R) {
p()
}
inline fun <R> inlineAll(p: () -> R) {
toOnlyLocal(<!NON_LOCAL_RETURN_NOT_ALLOWED!>p<!>)
}