From 434be3be21d5e765c81552985523854ff91a5cfd Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Sat, 10 Oct 2015 18:47:48 +0300 Subject: [PATCH] Adapted keyword completion to changed parser + more precise completion for modifier keywords --- .../kotlin/resolve/ModifiersChecker.kt | 17 ++++++---- .../idea/completion/KeywordCompletion.kt | 34 +++++++++++++------ .../testData/keywords/AfterClassProperty.kt | 9 ----- .../testData/keywords/AfterClasses.kt | 19 +++-------- .../testData/keywords/AfterFuns.kt | 9 ----- .../testData/keywords/FileKeyword.kt | 1 - .../keywords/GlobalPropertyAccessors.kt | 13 ------- .../testData/keywords/InClassBeforeFun.kt | 9 ----- .../testData/keywords/InClassScope.kt | 10 ------ .../keywords/InClassTypeParameters.kt | 1 + .../keywords/InMemberFunParametersList.kt | 7 ++-- .../InNotFinishedGenericWithFunAfter.kt | 1 + .../keywords/InTopFunParametersList.kt | 5 +-- .../keywords/InTopScopeAfterPackage.kt | 13 ------- .../testData/keywords/PropertyAccessors.kt | 10 ------ .../testData/keywords/PropertyAccessors2.kt | 10 ------ .../testData/keywords/PropertySetter.kt | 10 ------ .../testData/keywords/TopScope.kt | 13 ------- 18 files changed, 48 insertions(+), 143 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt index 77c3c96a32b..b56926bcb48 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt @@ -19,15 +19,20 @@ package org.jetbrains.kotlin.resolve import com.intellij.lang.ASTNode import com.intellij.psi.PsiElement import com.intellij.psi.tree.TokenSet -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget +import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.* import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.lexer.JetModifierKeywordToken -import java.util.* -import org.jetbrains.kotlin.lexer.JetTokens.* -import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.* import org.jetbrains.kotlin.lexer.JetTokens -import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.lexer.JetTokens.* +import org.jetbrains.kotlin.psi.JetClassOrObject +import org.jetbrains.kotlin.psi.JetDeclarationWithBody +import org.jetbrains.kotlin.psi.JetModifierList +import org.jetbrains.kotlin.psi.JetModifierListOwner +import java.util.* public object ModifierCheckerCore { private enum class Compatibility { @@ -51,7 +56,7 @@ public object ModifierCheckerCore { MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, MEMBER_PROPERTY, TOP_LEVEL_PROPERTY, CONSTRUCTOR) - private val possibleTargetMap = mapOf>( + val possibleTargetMap = mapOf>( ENUM_KEYWORD to EnumSet.of(ENUM_CLASS), ABSTRACT_KEYWORD to EnumSet.of(CLASS_ONLY, LOCAL_CLASS, INNER_CLASS, INTERFACE, MEMBER_PROPERTY, MEMBER_FUNCTION), OPEN_KEYWORD to EnumSet.of(CLASS_ONLY, LOCAL_CLASS, INNER_CLASS, INTERFACE, MEMBER_PROPERTY, MEMBER_FUNCTION), diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KeywordCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KeywordCompletion.kt index b65c46dca9a..a3ff6c1f69f 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KeywordCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KeywordCompletion.kt @@ -28,15 +28,18 @@ import com.intellij.psi.filters.position.LeftNeighbour import com.intellij.psi.filters.position.PositionElementFilter import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.TokenSet +import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.* import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler import org.jetbrains.kotlin.idea.completion.handlers.KotlinKeywordInsertHandler import org.jetbrains.kotlin.lexer.JetKeywordToken +import org.jetbrains.kotlin.lexer.JetModifierKeywordToken import org.jetbrains.kotlin.lexer.JetTokens.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.nextLeaf import org.jetbrains.kotlin.psi.psiUtil.prevLeaf import org.jetbrains.kotlin.psi.psiUtil.siblings +import org.jetbrains.kotlin.resolve.ModifierCheckerCore open class KeywordLookupObject @@ -47,10 +50,8 @@ object KeywordCompletion { .filter { it !in NON_ACTUAL_KEYWORDS } .map { it as JetKeywordToken } - private val KEYWORD_TO_DUMMY_POSTFIX = mapOf( - OUT_KEYWORD to " X", - FILE_KEYWORD to ":" - ) + private val DEFAULT_DUMMY_POSTFIX = " X" + private val KEYWORD_TO_DUMMY_POSTFIX = mapOf(FILE_KEYWORD to ":") private val KEYWORDS_TO_IGNORE_PREFIX = TokenSet.create(OVERRIDE_KEYWORD /* it's needed to complete overrides that should be work by member name too */) @@ -176,19 +177,32 @@ object KeywordCompletion { private fun buildFilterByText(prefixText: String, project: Project): (JetKeywordToken) -> Boolean { val psiFactory = JetPsiFactory(project) - return { keywordTokenType -> - val postfix = KEYWORD_TO_DUMMY_POSTFIX[keywordTokenType] ?: "" + return fun (keywordTokenType): Boolean { + val postfix = KEYWORD_TO_DUMMY_POSTFIX[keywordTokenType] ?: DEFAULT_DUMMY_POSTFIX val file = psiFactory.createFile(prefixText + keywordTokenType.getValue() + postfix) val elementAt = file.findElementAt(prefixText.length())!! when { - !elementAt.getNode()!!.getElementType().matchesKeyword(keywordTokenType) -> false + !elementAt.getNode()!!.getElementType().matchesKeyword(keywordTokenType) -> return false - elementAt.getNonStrictParentOfType() != null -> false + elementAt.getNonStrictParentOfType() != null -> return false - elementAt.prevLeaf { it !is PsiWhiteSpace && it !is PsiComment } is PsiErrorElement -> false + elementAt.prevLeaf { it !is PsiWhiteSpace && it !is PsiComment } is PsiErrorElement -> return false - else -> true + keywordTokenType !is JetModifierKeywordToken -> return true + + else -> { + if (elementAt.parent !is JetModifierList) return true + val possibleTargets = when (elementAt.parent.parent) { + is JetParameter -> listOf(VALUE_PARAMETER) + is JetTypeParameter -> listOf(TYPE_PARAMETER) + is JetClassBody -> listOf(CLASS_ONLY, INTERFACE, OBJECT, ENUM_CLASS, ANNOTATION_CLASS, INNER_CLASS, MEMBER_FUNCTION, MEMBER_PROPERTY, FUNCTION, PROPERTY) + is JetFile -> listOf(CLASS_ONLY, INTERFACE, OBJECT, ENUM_CLASS, ANNOTATION_CLASS, TOP_LEVEL_FUNCTION, TOP_LEVEL_PROPERTY, FUNCTION, PROPERTY) + else -> return true + } + val modifierTargets = ModifierCheckerCore.possibleTargetMap[keywordTokenType] ?: return true + return possibleTargets.any { it in modifierTargets } + } } } } diff --git a/idea/idea-completion/testData/keywords/AfterClassProperty.kt b/idea/idea-completion/testData/keywords/AfterClassProperty.kt index e0e0f98fc12..719e750e9b5 100644 --- a/idea/idea-completion/testData/keywords/AfterClassProperty.kt +++ b/idea/idea-completion/testData/keywords/AfterClassProperty.kt @@ -11,16 +11,10 @@ class MouseMovedEventArgs // EXIST: final // EXIST: fun // EXIST: get -// EXIST: in -/*why?*/ // EXIST: inner // EXIST: internal // EXIST: object // EXIST: open -// EXIST: out -/*why?*/ -// EXIST: reified -/*why?*/ // EXIST: override // EXIST: private // EXIST: protected @@ -29,7 +23,6 @@ class MouseMovedEventArgs // EXIST: interface // EXIST: val // EXIST: var -// EXIST: vararg // EXIST: constructor // EXIST: init /*why?*/ @@ -40,10 +33,8 @@ class MouseMovedEventArgs // EXIST: lateinit // EXIST: data // EXIST: inline -// EXIST: noinline // EXIST: tailrec // EXIST: external // EXIST: annotation -// EXIST: crossinline // EXIST: const // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/AfterClasses.kt b/idea/idea-completion/testData/keywords/AfterClasses.kt index 9e87000711f..cf2676a8ecf 100644 --- a/idea/idea-completion/testData/keywords/AfterClasses.kt +++ b/idea/idea-completion/testData/keywords/AfterClasses.kt @@ -17,37 +17,26 @@ class B { // EXIST: enum // EXIST: final // EXIST: fun -// EXIST: in -/*why?*/ -// EXIST: inner // EXIST: internal // EXIST: object // EXIST: open -// EXIST: out -/*why?*/ -// EXIST: reified -/*why?*/ -// EXIST: override // EXIST: private // EXIST: protected // EXIST: public // EXIST: interface // EXIST: val // EXIST: var -// EXIST: vararg -/*why?*/ -// EXIST: companion object // EXIST: operator // EXIST: infix // EXIST: sealed -// EXIST: lateinit // EXIST: data // EXIST: inline -// EXIST: noinline // EXIST: tailrec // EXIST: external // EXIST: annotation -// EXIST: crossinline // EXIST: const -/*TODO*/ +/*TODO:*/ +// EXIST: inner +/*TODO:*/ +// EXIST: companion object // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/AfterFuns.kt b/idea/idea-completion/testData/keywords/AfterFuns.kt index 5b96cf7e086..759a1659bcb 100644 --- a/idea/idea-completion/testData/keywords/AfterFuns.kt +++ b/idea/idea-completion/testData/keywords/AfterFuns.kt @@ -15,16 +15,10 @@ class A { // EXIST: enum // EXIST: final // EXIST: fun -// EXIST: in -/*why?*/ // EXIST: inner // EXIST: internal // EXIST: object // EXIST: open -// EXIST: out -/*why?*/ -// EXIST: reified -/*why?*/ // EXIST: override // EXIST: private // EXIST: protected @@ -32,7 +26,6 @@ class A { // EXIST: interface // EXIST: val // EXIST: var -// EXIST: vararg // EXIST: constructor // EXIST: init /*why?*/ @@ -43,10 +36,8 @@ class A { // EXIST: lateinit // EXIST: data // EXIST: inline -// EXIST: noinline // EXIST: tailrec // EXIST: external // EXIST: annotation -// EXIST: crossinline // EXIST: const // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/FileKeyword.kt b/idea/idea-completion/testData/keywords/FileKeyword.kt index 261f1541d6c..b646a5ae182 100644 --- a/idea/idea-completion/testData/keywords/FileKeyword.kt +++ b/idea/idea-completion/testData/keywords/FileKeyword.kt @@ -2,7 +2,6 @@ // EXIST: {"lookupString":"class","itemText":"class","attributes":"bold"} // EXIST: {"lookupString":"fun","itemText":"fun","attributes":"bold"} -// EXIST: {"lookupString":"in","itemText":"in","attributes":"bold"} // EXIST: {"lookupString":"interface","itemText":"interface","attributes":"bold"} // EXIST: {"lookupString":"object","itemText":"object","attributes":"bold"} // EXIST: {"lookupString":"package","itemText":"package","attributes":"bold"} diff --git a/idea/idea-completion/testData/keywords/GlobalPropertyAccessors.kt b/idea/idea-completion/testData/keywords/GlobalPropertyAccessors.kt index 50385f051fe..3acfad3f2e0 100644 --- a/idea/idea-completion/testData/keywords/GlobalPropertyAccessors.kt +++ b/idea/idea-completion/testData/keywords/GlobalPropertyAccessors.kt @@ -16,17 +16,10 @@ var a : Int // EXIST: final // EXIST: fun // EXIST: get -// EXIST: in -/*why?*/ // EXIST: inner // EXIST: internal // EXIST: object // EXIST: open -// EXIST: out -/*why?*/ -// EXIST: reified -/*why?*/ -// EXIST: override // EXIST: private // EXIST: protected // EXIST: public @@ -34,20 +27,14 @@ var a : Int // EXIST: interface // EXIST: val // EXIST: var -// EXIST: vararg -/*why?*/ // EXIST: companion object // EXIST: operator // EXIST: infix // EXIST: sealed -// EXIST: lateinit // EXIST: data // EXIST: inline -// EXIST: noinline // EXIST: tailrec // EXIST: external // EXIST: annotation -// EXIST: crossinline // EXIST: const -/*TODO*/ // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InClassBeforeFun.kt b/idea/idea-completion/testData/keywords/InClassBeforeFun.kt index 372303cdb2e..507cd675f26 100644 --- a/idea/idea-completion/testData/keywords/InClassBeforeFun.kt +++ b/idea/idea-completion/testData/keywords/InClassBeforeFun.kt @@ -13,16 +13,10 @@ public class Test { // EXIST: enum // EXIST: final // EXIST: fun -// EXIST: in -/*why?*/ // EXIST: inner // EXIST: internal // EXIST: object // EXIST: open -// EXIST: out -/*why?*/ -// EXIST: reified -/*why?*/ // EXIST: override // EXIST: private // EXIST: protected @@ -30,7 +24,6 @@ public class Test { // EXIST: interface // EXIST: val // EXIST: var -// EXIST: vararg // EXIST: constructor // EXIST: init /*why?*/ @@ -41,10 +34,8 @@ public class Test { // EXIST: lateinit // EXIST: data // EXIST: inline -// EXIST: noinline // EXIST: tailrec // EXIST: external // EXIST: annotation -// EXIST: crossinline // EXIST: const // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InClassScope.kt b/idea/idea-completion/testData/keywords/InClassScope.kt index a129836b77b..17236537d28 100644 --- a/idea/idea-completion/testData/keywords/InClassScope.kt +++ b/idea/idea-completion/testData/keywords/InClassScope.kt @@ -7,16 +7,10 @@ class TestClass { // EXIST: enum // EXIST: final // EXIST: fun -// EXIST: in -/*why?*/ // EXIST: inner // EXIST: internal // EXIST: object // EXIST: open -// EXIST: out -/*why?*/ -// EXIST: reified -/*why?*/ // EXIST: override // EXIST: private // EXIST: protected @@ -24,8 +18,6 @@ class TestClass { // EXIST: interface // EXIST: val // EXIST: var -// EXIST: vararg -/*why?*/ // EXIST: constructor // EXIST: init // EXIST: companion object @@ -35,10 +27,8 @@ class TestClass { // EXIST: lateinit // EXIST: data // EXIST: inline -// EXIST: noinline // EXIST: tailrec // EXIST: external // EXIST: annotation -// EXIST: crossinline // EXIST: const // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InClassTypeParameters.kt b/idea/idea-completion/testData/keywords/InClassTypeParameters.kt index 11eb3ff8ead..dfb7796a6ab 100644 --- a/idea/idea-completion/testData/keywords/InClassTypeParameters.kt +++ b/idea/idea-completion/testData/keywords/InClassTypeParameters.kt @@ -2,4 +2,5 @@ class T<> // EXIST: in // EXIST: out +// EXIST: reified // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InMemberFunParametersList.kt b/idea/idea-completion/testData/keywords/InMemberFunParametersList.kt index d84081b0125..55b75405dc2 100644 --- a/idea/idea-completion/testData/keywords/InMemberFunParametersList.kt +++ b/idea/idea-completion/testData/keywords/InMemberFunParametersList.kt @@ -5,9 +5,10 @@ class TestSample() { } } -/* TODO: they all are not correct */ +// EXIST: vararg +// EXIST: noinline +// EXIST: crossinline +/* TODO: val&var are not correct */ // EXIST: val // EXIST: var -// EXIST: in -// EXIST: out // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InNotFinishedGenericWithFunAfter.kt b/idea/idea-completion/testData/keywords/InNotFinishedGenericWithFunAfter.kt index 98936ed887f..5efbc1a9545 100644 --- a/idea/idea-completion/testData/keywords/InNotFinishedGenericWithFunAfter.kt +++ b/idea/idea-completion/testData/keywords/InNotFinishedGenericWithFunAfter.kt @@ -4,4 +4,5 @@ fun testing() {} // EXIST: in // EXIST: out +// EXIST: reified // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InTopFunParametersList.kt b/idea/idea-completion/testData/keywords/InTopFunParametersList.kt index e6193f06576..edff43a024a 100644 --- a/idea/idea-completion/testData/keywords/InTopFunParametersList.kt +++ b/idea/idea-completion/testData/keywords/InTopFunParametersList.kt @@ -2,9 +2,10 @@ fun test() { } +// EXIST: vararg +// EXIST: noinline +// EXIST: crossinline /* TODO: they all are not correct */ // EXIST: val // EXIST: var -// EXIST: in -// EXIST: out // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InTopScopeAfterPackage.kt b/idea/idea-completion/testData/keywords/InTopScopeAfterPackage.kt index 06bc70f9f15..d27f2088ffb 100644 --- a/idea/idea-completion/testData/keywords/InTopScopeAfterPackage.kt +++ b/idea/idea-completion/testData/keywords/InTopScopeAfterPackage.kt @@ -8,37 +8,24 @@ package Test // EXIST: final // EXIST: fun // EXIST: import -// EXIST: in -/*why?*/ // EXIST: inner // EXIST: internal // EXIST: object // EXIST: open -// EXIST: out -/*why?*/ -// EXIST: reified -/*why?*/ -// EXIST: override // EXIST: private // EXIST: protected // EXIST: public // EXIST: interface // EXIST: val // EXIST: var -// EXIST: vararg -/*why?*/ // EXIST: companion object // EXIST: operator // EXIST: infix // EXIST: sealed -// EXIST: lateinit // EXIST: data // EXIST: inline -// EXIST: noinline // EXIST: tailrec // EXIST: external // EXIST: annotation -// EXIST: crossinline // EXIST: const -/*TODO*/ // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/PropertyAccessors.kt b/idea/idea-completion/testData/keywords/PropertyAccessors.kt index 39dbf1db6d9..782d0bdd408 100644 --- a/idea/idea-completion/testData/keywords/PropertyAccessors.kt +++ b/idea/idea-completion/testData/keywords/PropertyAccessors.kt @@ -10,16 +10,10 @@ class Some { // EXIST: final // EXIST: fun // EXIST: get -// EXIST: in -/*why?*/ // EXIST: inner // EXIST: internal // EXIST: object // EXIST: open -// EXIST: out -/*why?*/ -// EXIST: reified -/*why?*/ // EXIST: override // EXIST: private // EXIST: protected @@ -28,8 +22,6 @@ class Some { // EXIST: interface // EXIST: val // EXIST: var -// EXIST: vararg -/*why?*/ // EXIST: constructor // EXIST: init // EXIST: companion object @@ -39,10 +31,8 @@ class Some { // EXIST: lateinit // EXIST: data // EXIST: inline -// EXIST: noinline // EXIST: tailrec // EXIST: external // EXIST: annotation -// EXIST: crossinline // EXIST: const // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/PropertyAccessors2.kt b/idea/idea-completion/testData/keywords/PropertyAccessors2.kt index 16cdaa6efcc..e23de2f6902 100644 --- a/idea/idea-completion/testData/keywords/PropertyAccessors2.kt +++ b/idea/idea-completion/testData/keywords/PropertyAccessors2.kt @@ -10,16 +10,10 @@ class Some { // EXIST: final // EXIST: fun // EXIST: get -// EXIST: in -/*why?*/ // EXIST: inner // EXIST: internal // EXIST: object // EXIST: open -// EXIST: out -/*why?*/ -// EXIST: reified -/*why?*/ // EXIST: override // EXIST: private // EXIST: protected @@ -28,8 +22,6 @@ class Some { // EXIST: interface // EXIST: val // EXIST: var -// EXIST: vararg -/*why?*/ // EXIST: constructor // EXIST: init // EXIST: companion object @@ -39,10 +31,8 @@ class Some { // EXIST: lateinit // EXIST: data // EXIST: inline -// EXIST: noinline // EXIST: tailrec // EXIST: external // EXIST: annotation -// EXIST: crossinline // EXIST: const // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/PropertySetter.kt b/idea/idea-completion/testData/keywords/PropertySetter.kt index 2e94be6afb7..56426e2211d 100644 --- a/idea/idea-completion/testData/keywords/PropertySetter.kt +++ b/idea/idea-completion/testData/keywords/PropertySetter.kt @@ -12,16 +12,10 @@ class Some { // EXIST: fun // EXIST: get /*TODO*/ -// EXIST: in -/*why?*/ // EXIST: inner // EXIST: internal // EXIST: object // EXIST: open -// EXIST: out -/*why?*/ -// EXIST: reified -/*why?*/ // EXIST: override // EXIST: private // EXIST: protected @@ -30,8 +24,6 @@ class Some { // EXIST: interface // EXIST: val // EXIST: var -// EXIST: vararg -/*why?*/ // EXIST: constructor // EXIST: init // EXIST: companion object @@ -41,10 +33,8 @@ class Some { // EXIST: lateinit // EXIST: data // EXIST: inline -// EXIST: noinline // EXIST: tailrec // EXIST: external // EXIST: annotation -// EXIST: crossinline // EXIST: const // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/TopScope.kt b/idea/idea-completion/testData/keywords/TopScope.kt index a7fd580b01c..53526a46246 100644 --- a/idea/idea-completion/testData/keywords/TopScope.kt +++ b/idea/idea-completion/testData/keywords/TopScope.kt @@ -6,17 +6,10 @@ // EXIST: final // EXIST: fun // EXIST: import -// EXIST: in -/*why?*/ // EXIST: inner // EXIST: internal // EXIST: object // EXIST: open -// EXIST: out -/*why?*/ -// EXIST: reified -/*why?*/ -// EXIST: override // EXIST: package // EXIST: private // EXIST: protected @@ -24,20 +17,14 @@ // EXIST: interface // EXIST: val // EXIST: var -// EXIST: vararg -/*why?*/ // EXIST: companion object // EXIST: operator // EXIST: infix // EXIST: sealed -// EXIST: lateinit // EXIST: data // EXIST: inline -// EXIST: noinline // EXIST: tailrec // EXIST: external // EXIST: annotation -// EXIST: crossinline // EXIST: const -/*TODO*/ // NOTHING_ELSE