From c449c0d080905753d629d17c7a39b195656a3ec1 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 9 Sep 2015 12:35:19 +0300 Subject: [PATCH] Deprecate `inlineOption` in favor of `crossinline` modifier --- .../diagnostics/rendering/DefaultErrorMessages.java | 2 +- .../src/org/jetbrains/kotlin/lexer/JetTokens.java | 7 ++++--- .../src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt | 3 ++- .../org/jetbrains/kotlin/resolve/inline/InlineUtil.java | 3 ++- compiler/testData/builtin-classes.txt | 6 +++++- .../tests/inline/nonLocalReturns/anonymousObjects.kt | 4 ++-- .../tests/inline/nonLocalReturns/anonymousObjects.txt | 2 +- .../inline/nonLocalReturns/anonymousObjectsNested.kt | 4 ++-- .../inline/nonLocalReturns/anonymousObjectsNested.txt | 2 +- .../tests/inline/nonLocalReturns/fromOnlyLocal.kt | 4 ++-- .../tests/inline/nonLocalReturns/fromOnlyLocal.txt | 2 +- .../tests/inline/nonLocalReturns/inlineLambda.kt | 4 ++-- .../tests/inline/nonLocalReturns/inlineLambda.txt | 2 +- .../lambdaWithGlobalReturnsInsideOnlyLocalOne.kt | 4 ++-- .../lambdaWithGlobalReturnsInsideOnlyLocalOne.txt | 2 +- .../diagnostics/tests/inline/nonLocalReturns/localFun.kt | 4 ++-- .../tests/inline/nonLocalReturns/localFun.txt | 2 +- .../tests/inline/nonLocalReturns/noInlineLambda.kt | 4 ++-- .../tests/inline/nonLocalReturns/noInlineLambda.txt | 2 +- .../tests/inline/nonLocalReturns/nonInlinedClass.kt | 4 ++-- .../tests/inline/nonLocalReturns/nonInlinedClass.txt | 2 +- .../inline/nonLocalReturns/onlyLocalReturnLambda.kt | 4 ++-- .../inline/nonLocalReturns/onlyLocalReturnLambda.txt | 2 +- .../nonLocalReturns/onlyLocalReturnLambdaBinaryExpr.kt | 4 ++-- .../nonLocalReturns/onlyLocalReturnLambdaBinaryExpr.txt | 2 +- .../tests/inline/nonLocalReturns/toOnlyLocal.kt | 2 +- .../tests/inline/nonLocalReturns/toOnlyLocal.txt | 2 +- core/builtins/src/kotlin/Inline.kt | 9 +++++++++ .../org/jetbrains/kotlin/builtins/KotlinBuiltIns.java | 1 + .../kotlin/descriptors/annotations/annotationUtil.kt | 2 +- .../testData/keywords/AfterClassProperty.kt | 1 + idea/idea-completion/testData/keywords/AfterClasses.kt | 1 + idea/idea-completion/testData/keywords/AfterFuns.kt | 1 + .../testData/keywords/GlobalPropertyAccessors.kt | 1 + .../testData/keywords/InClassBeforeFun.kt | 1 + idea/idea-completion/testData/keywords/InClassScope.kt | 1 + .../testData/keywords/InTopScopeAfterPackage.kt | 1 + .../testData/keywords/PropertyAccessors.kt | 1 + .../testData/keywords/PropertyAccessors2.kt | 1 + idea/idea-completion/testData/keywords/PropertySetter.kt | 1 + idea/idea-completion/testData/keywords/TopScope.kt | 1 + 41 files changed, 68 insertions(+), 40 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index f8e19fdec10..6470453f508 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -629,7 +629,7 @@ public class DefaultErrorMessages { MAP.put(NULLABLE_INLINE_PARAMETER, "Inline-parameter ''{0}'' of ''{1}'' must not be nullable. Annotate the parameter with [noinline] or make not nullable", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES); MAP.put(RECURSION_IN_INLINE, "Inline-function ''{1}'' can't be recursive", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES); //Inline non Locals - MAP.put(NON_LOCAL_RETURN_NOT_ALLOWED, "Can''t inline ''{0}'' here: it may contain non-local returns. Annotate parameter declaration ''{0}'' with ''inlineOptions(ONLY_LOCAL_RETURN)''", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES); + MAP.put(NON_LOCAL_RETURN_NOT_ALLOWED, "Can''t inline ''{0}'' here: it may contain non-local returns. Add ''crossinline'' modifier to parameter declaration ''{0}''", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES); MAP.put(INLINE_CALL_CYCLE, "The ''{0}'' invocation is a part of inline cycle", NAME); MAP.put(NON_LOCAL_RETURN_IN_DISABLED_INLINE, "Non-local returns are not allowed with inlining disabled"); MAP.put(ACCESS_TO_PRIVATE_TOP_LEVEL_FROM_ANOTHER_FILE, "Access to private top-level declarations from another file will soon be forbidden: ''{0}'' is ''{1}'' in ''{2}''", NAME, TO_STRING, RENDER_FILE); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/lexer/JetTokens.java b/compiler/frontend/src/org/jetbrains/kotlin/lexer/JetTokens.java index b0732ceef4c..7974b75d717 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/lexer/JetTokens.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/lexer/JetTokens.java @@ -176,6 +176,7 @@ public interface JetTokens { JetModifierKeywordToken TAILREC_KEYWORD = JetModifierKeywordToken.softKeywordModifier("tailrec"); JetModifierKeywordToken EXTERNAL_KEYWORD = JetModifierKeywordToken.softKeywordModifier("external"); JetModifierKeywordToken ANNOTATION_KEYWORD = JetModifierKeywordToken.softKeywordModifier("annotation"); + JetModifierKeywordToken CROSSINLINE_KEYWORD = JetModifierKeywordToken.softKeywordModifier("crossinline"); TokenSet KEYWORDS = TokenSet.create(PACKAGE_KEYWORD, AS_KEYWORD, TYPE_ALIAS_KEYWORD, CLASS_KEYWORD, TRAIT_KEYWORD, INTERFACE_KEYWORD, THIS_KEYWORD, SUPER_KEYWORD, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, FOR_KEYWORD, @@ -194,7 +195,7 @@ public interface JetTokens { FIELD_KEYWORD, PROPERTY_KEYWORD, RECEIVER_KEYWORD, PARAM_KEYWORD, SPARAM_KEYWORD, LATE_INIT_KEYWORD, DATA_KEYWORD, INLINE_KEYWORD, NOINLINE_KEYWORD, TAILREC_KEYWORD, EXTERNAL_KEYWORD, - ANNOTATION_KEYWORD + ANNOTATION_KEYWORD, CROSSINLINE_KEYWORD ); /* @@ -207,12 +208,12 @@ public interface JetTokens { ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, INNER_KEYWORD, OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, REIFIED_KEYWORD, COMPANION_KEYWORD, SEALED_KEYWORD, LATE_INIT_KEYWORD, - DATA_KEYWORD, INLINE_KEYWORD, NOINLINE_KEYWORD, TAILREC_KEYWORD, EXTERNAL_KEYWORD, ANNOTATION_KEYWORD + DATA_KEYWORD, INLINE_KEYWORD, NOINLINE_KEYWORD, TAILREC_KEYWORD, EXTERNAL_KEYWORD, ANNOTATION_KEYWORD, CROSSINLINE_KEYWORD }; // Please synchronize this array with org.jetbrains.kotlin.descriptors.annotations.ANNOTATION_MODIFIERS_FQ_NAMES JetModifierKeywordToken[] ANNOTATION_MODIFIERS_KEYWORDS_ARRAY = new JetModifierKeywordToken[] { - DATA_KEYWORD, INLINE_KEYWORD, NOINLINE_KEYWORD, TAILREC_KEYWORD, EXTERNAL_KEYWORD, ANNOTATION_KEYWORD + DATA_KEYWORD, INLINE_KEYWORD, NOINLINE_KEYWORD, TAILREC_KEYWORD, EXTERNAL_KEYWORD, ANNOTATION_KEYWORD, CROSSINLINE_KEYWORD }; TokenSet ANNOTATION_MODIFIERS_KEYWORDS = TokenSet.create(ANNOTATION_MODIFIERS_KEYWORDS_ARRAY); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt index a994ab7dc07..6e34e3196f2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt @@ -63,7 +63,8 @@ public object ModifierCheckerCore { NOINLINE_KEYWORD to EnumSet.of(VALUE_PARAMETER), TAILREC_KEYWORD to EnumSet.of(FUNCTION), EXTERNAL_KEYWORD to EnumSet.of(FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER), - ANNOTATION_KEYWORD to EnumSet.of(ANNOTATION_CLASS) + ANNOTATION_KEYWORD to EnumSet.of(ANNOTATION_CLASS), + CROSSINLINE_KEYWORD to EnumSet.of(VALUE_PARAMETER) ) // NOTE: redundant targets must be possible! diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java index afcd4037800..8df75099b5e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java @@ -66,7 +66,8 @@ public class InlineUtil { } public static boolean hasOnlyLocalReturn(@NotNull ValueParameterDescriptor descriptor) { - return hasInlineOption(descriptor, InlineOption.ONLY_LOCAL_RETURN); + return hasInlineOption(descriptor, InlineOption.ONLY_LOCAL_RETURN) + || descriptor.getAnnotations().findAnnotation(KotlinBuiltIns.FQ_NAMES.crossinline) != null; } private static boolean hasInlineOption(@NotNull ValueParameterDescriptor descriptor, @NotNull InlineOption option) { diff --git a/compiler/testData/builtin-classes.txt b/compiler/testData/builtin-classes.txt index ecc4f1ca5a0..7f7f1bd84fa 100644 --- a/compiler/testData/builtin-classes.txt +++ b/compiler/testData/builtin-classes.txt @@ -1252,6 +1252,10 @@ public object Unit { /*primary*/ private constructor Unit() } +kotlin.annotation.Target(allowedTargets = {AnnotationTarget.VALUE_PARAMETER}) kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) kotlin.annotation.MustBeDocumented() kotlin.annotation.annotation() public final class crossinline : kotlin.Annotation { + /*primary*/ public constructor crossinline() +} + kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASSIFIER}) kotlin.annotation.MustBeDocumented() kotlin.annotation.annotation() public final class data : kotlin.Annotation { /*primary*/ public constructor data() } @@ -1264,7 +1268,7 @@ kotlin.annotation.Target(allowedTargets = {AnnotationTarget.FUNCTION, Annotation /*primary*/ public constructor inline() } -kotlin.annotation.Target(allowedTargets = {AnnotationTarget.VALUE_PARAMETER}) kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) kotlin.annotation.MustBeDocumented() kotlin.annotation.annotation() public final class inlineOptions : kotlin.Annotation { +kotlin.annotation.Target(allowedTargets = {AnnotationTarget.VALUE_PARAMETER}) kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) kotlin.annotation.MustBeDocumented() kotlin.Deprecated(value = "Use 'crossinline' modifier instead of 'inlineOptions(InlineOption.ONLY_LOCAL_RETURN)'") kotlin.annotation.annotation() public final class inlineOptions : kotlin.Annotation { /*primary*/ public constructor inlineOptions(/*0*/ vararg value: kotlin.InlineOption /*kotlin.Array*/) public final val value: kotlin.Array public final fun (): kotlin.Array diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.kt index f0511f047de..a866dd3e33c 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.kt @@ -1,7 +1,7 @@ // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE import kotlin.InlineOption.* -inline fun inlineFunOnlyLocal(@inlineOptions(ONLY_LOCAL_RETURN)p: () -> R) { +inline fun inlineFunOnlyLocal(crossinline p: () -> R) { val s = object { val z = p() @@ -21,4 +21,4 @@ inline fun inlineFun(p: () -> R) { p() } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.txt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.txt index 307f35c52d6..fcd152f08cc 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.txt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.txt @@ -1,4 +1,4 @@ package kotlin.inline() public fun inlineFun(/*0*/ p: () -> R): kotlin.Unit -kotlin.inline() public fun inlineFunOnlyLocal(/*0*/ kotlin.inlineOptions(value = {InlineOption.ONLY_LOCAL_RETURN}) p: () -> R): kotlin.Unit +kotlin.inline() public fun inlineFunOnlyLocal(/*0*/ kotlin.crossinline() p: () -> R): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.kt index c040ccc889b..eb650acfdca 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.kt @@ -1,7 +1,7 @@ // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE import kotlin.InlineOption.* -inline fun inlineFunOnlyLocal(@inlineOptions(ONLY_LOCAL_RETURN)p: () -> R) { +inline fun inlineFunOnlyLocal(crossinline p: () -> R) { val s = object { val z = p(); @@ -46,4 +46,4 @@ inline fun inlineFun(p: () -> R) { inline fun doCall(p: () -> R) { p() -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.txt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.txt index c5d192c2ed2..671585c5472 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.txt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.txt @@ -2,4 +2,4 @@ package kotlin.inline() public fun doCall(/*0*/ p: () -> R): kotlin.Unit kotlin.inline() public fun inlineFun(/*0*/ p: () -> R): kotlin.Unit -kotlin.inline() public fun inlineFunOnlyLocal(/*0*/ kotlin.inlineOptions(value = {InlineOption.ONLY_LOCAL_RETURN}) p: () -> R): kotlin.Unit +kotlin.inline() public fun inlineFunOnlyLocal(/*0*/ kotlin.crossinline() p: () -> R): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/fromOnlyLocal.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/fromOnlyLocal.kt index 76ba42241bd..a365fe0bec5 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/fromOnlyLocal.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/fromOnlyLocal.kt @@ -1,9 +1,9 @@ import kotlin.InlineOption.* -inline fun onlyLocal(@inlineOptions(ONLY_LOCAL_RETURN)p: () -> R) { +inline fun onlyLocal(crossinline p: () -> R) { inlineAll(p) } inline fun inlineAll(p: () -> R) { p() -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/fromOnlyLocal.txt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/fromOnlyLocal.txt index 302a1e9a50b..bb835328451 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/fromOnlyLocal.txt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/fromOnlyLocal.txt @@ -1,4 +1,4 @@ package kotlin.inline() public fun inlineAll(/*0*/ p: () -> R): kotlin.Unit -kotlin.inline() public fun onlyLocal(/*0*/ kotlin.inlineOptions(value = {InlineOption.ONLY_LOCAL_RETURN}) p: () -> R): kotlin.Unit +kotlin.inline() public fun onlyLocal(/*0*/ kotlin.crossinline() p: () -> R): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/inlineLambda.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/inlineLambda.kt index c46e465888d..b64de0e7241 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/inlineLambda.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/inlineLambda.kt @@ -1,6 +1,6 @@ import kotlin.InlineOption.* -inline fun inlineFunWithAnnotation(@inlineOptions(ONLY_LOCAL_RETURN) p: () -> R) { +inline fun inlineFunWithAnnotation(crossinline p: () -> R) { inlineFun { p() } @@ -14,4 +14,4 @@ inline fun inlineFun2(p: () -> R) { inline fun inlineFun(p: () -> R) { p() -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/inlineLambda.txt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/inlineLambda.txt index b318a8282d2..8825bcaed53 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/inlineLambda.txt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/inlineLambda.txt @@ -2,4 +2,4 @@ package kotlin.inline() public fun inlineFun(/*0*/ p: () -> R): kotlin.Unit kotlin.inline() public fun inlineFun2(/*0*/ p: () -> R): kotlin.Unit -kotlin.inline() public fun inlineFunWithAnnotation(/*0*/ kotlin.inlineOptions(value = {InlineOption.ONLY_LOCAL_RETURN}) p: () -> R): kotlin.Unit +kotlin.inline() public fun inlineFunWithAnnotation(/*0*/ kotlin.crossinline() p: () -> R): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.kt index 97fb3c87819..f8bdbcb81bf 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.kt @@ -5,6 +5,6 @@ inline fun testSameCaptured(lambdaWithResultCaptured: () -> Unit) : String { return "OK" } -inline fun doWork(@inlineOptions(ONLY_LOCAL_RETURN) job: ()-> R) : R { +inline fun doWork(crossinline job: ()-> R) : R { return job() -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.txt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.txt index 563ae781d3a..195cacad8a1 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.txt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.txt @@ -1,4 +1,4 @@ package -kotlin.inline() public fun doWork(/*0*/ kotlin.inlineOptions(value = {InlineOption.ONLY_LOCAL_RETURN}) job: () -> R): R +kotlin.inline() public fun doWork(/*0*/ kotlin.crossinline() job: () -> R): R kotlin.inline() public fun testSameCaptured(/*0*/ lambdaWithResultCaptured: () -> kotlin.Unit): kotlin.String diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.kt index c108ed02e30..afcd7df3382 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.kt @@ -1,7 +1,7 @@ // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE import kotlin.InlineOption.* -inline fun inlineFunOnlyLocal(@inlineOptions(ONLY_LOCAL_RETURN)p: () -> R) { +inline fun inlineFunOnlyLocal(crossinline p: () -> R) { fun a() { val z = p() } @@ -13,4 +13,4 @@ inline fun inlineFun(p: () -> R) { p() } a() -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.txt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.txt index 307f35c52d6..fcd152f08cc 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.txt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.txt @@ -1,4 +1,4 @@ package kotlin.inline() public fun inlineFun(/*0*/ p: () -> R): kotlin.Unit -kotlin.inline() public fun inlineFunOnlyLocal(/*0*/ kotlin.inlineOptions(value = {InlineOption.ONLY_LOCAL_RETURN}) p: () -> R): kotlin.Unit +kotlin.inline() public fun inlineFunOnlyLocal(/*0*/ kotlin.crossinline() p: () -> R): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.kt index dafb752e6ae..e78669bc5a2 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.kt @@ -1,7 +1,7 @@ // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE import kotlin.InlineOption.* -inline fun inlineFunOnlyLocal(@inlineOptions(ONLY_LOCAL_RETURN)p: () -> R) { +inline fun inlineFunOnlyLocal(crossinline p: () -> R) { { p() }() @@ -11,4 +11,4 @@ inline fun inlineFun(p: () -> R) { { p() }() -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.txt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.txt index 307f35c52d6..fcd152f08cc 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.txt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.txt @@ -1,4 +1,4 @@ package kotlin.inline() public fun inlineFun(/*0*/ p: () -> R): kotlin.Unit -kotlin.inline() public fun inlineFunOnlyLocal(/*0*/ kotlin.inlineOptions(value = {InlineOption.ONLY_LOCAL_RETURN}) p: () -> R): kotlin.Unit +kotlin.inline() public fun inlineFunOnlyLocal(/*0*/ kotlin.crossinline() p: () -> R): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.kt index b6c64452db5..8e15b5b2925 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.kt @@ -1,7 +1,7 @@ // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE import kotlin.InlineOption.* -inline fun inlineFunOnlyLocal(@inlineOptions(ONLY_LOCAL_RETURN)p: () -> R) { +inline fun inlineFunOnlyLocal(crossinline p: () -> R) { class A { val z = p() @@ -21,4 +21,4 @@ inline fun inlineFun(p: () -> R) { p() } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.txt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.txt index 307f35c52d6..fcd152f08cc 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.txt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.txt @@ -1,4 +1,4 @@ package kotlin.inline() public fun inlineFun(/*0*/ p: () -> R): kotlin.Unit -kotlin.inline() public fun inlineFunOnlyLocal(/*0*/ kotlin.inlineOptions(value = {InlineOption.ONLY_LOCAL_RETURN}) p: () -> R): kotlin.Unit +kotlin.inline() public fun inlineFunOnlyLocal(/*0*/ kotlin.crossinline() p: () -> R): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambda.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambda.kt index 67855cffff7..bc4441d8c76 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambda.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambda.kt @@ -39,6 +39,6 @@ fun fun4ValueArgument(p: () -> R) { } -inline fun inlineFun(@inlineOptions(ONLY_LOCAL_RETURN) p: () -> R) { +inline fun inlineFun(crossinline p: () -> R) { p() -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambda.txt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambda.txt index 2428a9f4215..d4e5525e5ab 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambda.txt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambda.txt @@ -6,4 +6,4 @@ public fun fun3(/*0*/ p: () -> R): kotlin.Unit public fun fun3ValueArgument(/*0*/ p: () -> R): kotlin.Unit public fun fun4(/*0*/ p: () -> R): kotlin.Unit public fun fun4ValueArgument(/*0*/ p: () -> R): kotlin.Unit -kotlin.inline() public fun inlineFun(/*0*/ kotlin.inlineOptions(value = {InlineOption.ONLY_LOCAL_RETURN}) p: () -> R): kotlin.Unit +kotlin.inline() public fun inlineFun(/*0*/ kotlin.crossinline() p: () -> R): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambdaBinaryExpr.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambdaBinaryExpr.kt index eeaa087d347..fde1d83977b 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambdaBinaryExpr.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambdaBinaryExpr.kt @@ -2,7 +2,7 @@ import kotlin.InlineOption.* class Z { - inline fun inlineFun(@inlineOptions(ONLY_LOCAL_RETURN) p: () -> R) { + inline fun inlineFun(crossinline p: () -> R) { p() } } @@ -23,4 +23,4 @@ fun fun4(p: () -> R) { Z() inlineFun lambda@ { return@lambda p(); } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambdaBinaryExpr.txt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambdaBinaryExpr.txt index 80834edfb8d..abcad6ce204 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambdaBinaryExpr.txt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/onlyLocalReturnLambdaBinaryExpr.txt @@ -8,6 +8,6 @@ public final class Z { public constructor Z() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - kotlin.inline() public final fun inlineFun(/*0*/ kotlin.inlineOptions(value = {InlineOption.ONLY_LOCAL_RETURN}) p: () -> R): kotlin.Unit + kotlin.inline() public final fun inlineFun(/*0*/ kotlin.crossinline() p: () -> R): kotlin.Unit public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/toOnlyLocal.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/toOnlyLocal.kt index 80aac4dc372..10cc07ad832 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/toOnlyLocal.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/toOnlyLocal.kt @@ -1,6 +1,6 @@ import kotlin.InlineOption.* -inline fun toOnlyLocal(@inlineOptions(ONLY_LOCAL_RETURN) p: () -> R) { +inline fun toOnlyLocal(crossinline p: () -> R) { p() } diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/toOnlyLocal.txt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/toOnlyLocal.txt index 81889508bdd..d48807a2f34 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/toOnlyLocal.txt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/toOnlyLocal.txt @@ -1,4 +1,4 @@ package kotlin.inline() public fun inlineAll(/*0*/ p: () -> R): kotlin.Unit -kotlin.inline() public fun toOnlyLocal(/*0*/ kotlin.inlineOptions(value = {InlineOption.ONLY_LOCAL_RETURN}) p: () -> R): kotlin.Unit +kotlin.inline() public fun toOnlyLocal(/*0*/ kotlin.crossinline() p: () -> R): kotlin.Unit diff --git a/core/builtins/src/kotlin/Inline.kt b/core/builtins/src/kotlin/Inline.kt index 5a7a9698080..d36f5d14a83 100644 --- a/core/builtins/src/kotlin/Inline.kt +++ b/core/builtins/src/kotlin/Inline.kt @@ -50,8 +50,17 @@ public annotation class inline @Target(AnnotationTarget.VALUE_PARAMETER) @Retention(AnnotationRetention.RUNTIME) @MustBeDocumented +@Deprecated("Use 'crossinline' modifier instead of 'inlineOptions(InlineOption.ONLY_LOCAL_RETURN)'") public annotation class inlineOptions(vararg val value: InlineOption) +/** + * Forbids use of non-local control flow statements within lambdas passed as arguments for this parameter. + */ +@Target(AnnotationTarget.VALUE_PARAMETER) +@Retention(AnnotationRetention.RUNTIME) +@MustBeDocumented +public annotation class crossinline + /** * Specifies the control flow statements which are allowed to be used for non-local control flow transfer in a lambda * passed as a parameter to an inline function. diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java index b588a751f56..91536d1b307 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java @@ -180,6 +180,7 @@ public class KotlinBuiltIns { public final FqName tailRecursiveDeprecated = fqName("tailRecursive"); public final FqName inline = fqName("inline"); public final FqName noinline = fqName("noinline"); + public final FqName crossinline = fqName("crossinline"); public final FqName inlineOptions = fqName("inlineOptions"); public final FqName extension = fqName("Extension"); public final FqName target = annotationName("Target"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/annotationUtil.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/annotationUtil.kt index f73c66babed..e11eda49c12 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/annotationUtil.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/annotationUtil.kt @@ -20,4 +20,4 @@ import org.jetbrains.kotlin.name.FqName // Please synchronize this set with JetTokens.ANNOTATION_MODIFIERS_KEYWORDS_ARRAY public val ANNOTATION_MODIFIERS_FQ_NAMES: Set = - arrayOf("data", "inline", "noinline", "tailrec", "external", "annotation.annotation").map { FqName("kotlin.$it") }.toSet() + arrayOf("data", "inline", "noinline", "tailrec", "external", "annotation.annotation", "crossinline").map { FqName("kotlin.$it") }.toSet() diff --git a/idea/idea-completion/testData/keywords/AfterClassProperty.kt b/idea/idea-completion/testData/keywords/AfterClassProperty.kt index 6589fa488f5..3d674ef612f 100644 --- a/idea/idea-completion/testData/keywords/AfterClassProperty.kt +++ b/idea/idea-completion/testData/keywords/AfterClassProperty.kt @@ -42,4 +42,5 @@ class MouseMovedEventArgs // EXIST: tailrec // EXIST: external // EXIST: annotation +// EXIST: crossinline // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/AfterClasses.kt b/idea/idea-completion/testData/keywords/AfterClasses.kt index f4e25d7aadf..23404ab5401 100644 --- a/idea/idea-completion/testData/keywords/AfterClasses.kt +++ b/idea/idea-completion/testData/keywords/AfterClasses.kt @@ -45,5 +45,6 @@ class B { // EXIST: tailrec // EXIST: external // EXIST: annotation +// EXIST: crossinline /*TODO*/ // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/AfterFuns.kt b/idea/idea-completion/testData/keywords/AfterFuns.kt index 705fecf76e4..b46e976a6bc 100644 --- a/idea/idea-completion/testData/keywords/AfterFuns.kt +++ b/idea/idea-completion/testData/keywords/AfterFuns.kt @@ -45,4 +45,5 @@ class A { // EXIST: tailrec // EXIST: external // EXIST: annotation +// EXIST: crossinline // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/GlobalPropertyAccessors.kt b/idea/idea-completion/testData/keywords/GlobalPropertyAccessors.kt index affef029778..4c7c8926c0e 100644 --- a/idea/idea-completion/testData/keywords/GlobalPropertyAccessors.kt +++ b/idea/idea-completion/testData/keywords/GlobalPropertyAccessors.kt @@ -45,5 +45,6 @@ var a : Int // EXIST: tailrec // EXIST: external // EXIST: annotation +// EXIST: crossinline /*TODO*/ // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InClassBeforeFun.kt b/idea/idea-completion/testData/keywords/InClassBeforeFun.kt index 29f21795145..610dc0ce94d 100644 --- a/idea/idea-completion/testData/keywords/InClassBeforeFun.kt +++ b/idea/idea-completion/testData/keywords/InClassBeforeFun.kt @@ -43,4 +43,5 @@ public class Test { // EXIST: tailrec // EXIST: external // EXIST: annotation +// EXIST: crossinline // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InClassScope.kt b/idea/idea-completion/testData/keywords/InClassScope.kt index 97ac5c8cd30..52b7b4426d3 100644 --- a/idea/idea-completion/testData/keywords/InClassScope.kt +++ b/idea/idea-completion/testData/keywords/InClassScope.kt @@ -37,4 +37,5 @@ class TestClass { // EXIST: tailrec // EXIST: external // EXIST: annotation +// EXIST: crossinline // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InTopScopeAfterPackage.kt b/idea/idea-completion/testData/keywords/InTopScopeAfterPackage.kt index aa4f91728a6..3515f13b8d8 100644 --- a/idea/idea-completion/testData/keywords/InTopScopeAfterPackage.kt +++ b/idea/idea-completion/testData/keywords/InTopScopeAfterPackage.kt @@ -36,5 +36,6 @@ package Test // EXIST: tailrec // EXIST: external // EXIST: annotation +// EXIST: crossinline /*TODO*/ // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/PropertyAccessors.kt b/idea/idea-completion/testData/keywords/PropertyAccessors.kt index 79627e5157c..7b8a80bb6f5 100644 --- a/idea/idea-completion/testData/keywords/PropertyAccessors.kt +++ b/idea/idea-completion/testData/keywords/PropertyAccessors.kt @@ -41,4 +41,5 @@ class Some { // EXIST: tailrec // EXIST: external // EXIST: annotation +// EXIST: crossinline // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/PropertyAccessors2.kt b/idea/idea-completion/testData/keywords/PropertyAccessors2.kt index 0917d6002cb..90569a72a91 100644 --- a/idea/idea-completion/testData/keywords/PropertyAccessors2.kt +++ b/idea/idea-completion/testData/keywords/PropertyAccessors2.kt @@ -41,4 +41,5 @@ class Some { // EXIST: tailrec // EXIST: external // EXIST: annotation +// EXIST: crossinline // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/PropertySetter.kt b/idea/idea-completion/testData/keywords/PropertySetter.kt index f6965ac71dd..e1fe084e67e 100644 --- a/idea/idea-completion/testData/keywords/PropertySetter.kt +++ b/idea/idea-completion/testData/keywords/PropertySetter.kt @@ -43,4 +43,5 @@ class Some { // EXIST: tailrec // EXIST: external // EXIST: annotation +// EXIST: crossinline // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/TopScope.kt b/idea/idea-completion/testData/keywords/TopScope.kt index 0413d506723..8284dff4837 100644 --- a/idea/idea-completion/testData/keywords/TopScope.kt +++ b/idea/idea-completion/testData/keywords/TopScope.kt @@ -35,5 +35,6 @@ // EXIST: tailrec // EXIST: external // EXIST: annotation +// EXIST: crossinline /*TODO*/ // NOTHING_ELSE