Even more precise keyword completion for modifiers
This commit is contained in:
@@ -95,7 +95,7 @@ public object ModifierCheckerCore {
|
||||
FINAL_KEYWORD to EnumSet.of(ENUM_CLASS, OBJECT)
|
||||
)
|
||||
|
||||
private val possibleParentTargetMap = mapOf<JetModifierKeywordToken, Set<KotlinTarget>>(
|
||||
val possibleParentTargetMap = mapOf<JetModifierKeywordToken, Set<KotlinTarget>>(
|
||||
INNER_KEYWORD to EnumSet.of(CLASS_ONLY, INNER_CLASS, LOCAL_CLASS, ENUM_CLASS, ENUM_ENTRY),
|
||||
OVERRIDE_KEYWORD to EnumSet.of(CLASS_ONLY, INNER_CLASS, LOCAL_CLASS, OBJECT, OBJECT_LITERAL,
|
||||
INTERFACE, ENUM_CLASS, ENUM_ENTRY),
|
||||
@@ -107,7 +107,7 @@ public object ModifierCheckerCore {
|
||||
COMPANION_KEYWORD to EnumSet.of(CLASS_ONLY, ENUM_CLASS, INTERFACE)
|
||||
)
|
||||
|
||||
private val deprecatedParentTargetMap = mapOf<JetModifierKeywordToken, Set<KotlinTarget>>(
|
||||
val deprecatedParentTargetMap = mapOf<JetModifierKeywordToken, Set<KotlinTarget>>(
|
||||
// Deprecated in M15
|
||||
FINAL_KEYWORD to EnumSet.of(INTERFACE),
|
||||
PROTECTED_KEYWORD to EnumSet.of(OBJECT)
|
||||
|
||||
@@ -28,6 +28,7 @@ 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.descriptors.annotations.KotlinTarget.*
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.KotlinKeywordInsertHandler
|
||||
@@ -197,10 +198,10 @@ object KeywordCompletion {
|
||||
|
||||
else -> {
|
||||
if (elementAt.parent !is JetModifierList) return true
|
||||
val declaration = elementAt.parent.parent
|
||||
val possibleTargets = when (declaration) {
|
||||
val container = elementAt.parent.parent
|
||||
val possibleTargets = when (container) {
|
||||
is JetParameter -> {
|
||||
if (declaration.ownerFunction is JetPrimaryConstructor)
|
||||
if (container.ownerFunction is JetPrimaryConstructor)
|
||||
listOf(VALUE_PARAMETER, MEMBER_PROPERTY)
|
||||
else
|
||||
listOf(VALUE_PARAMETER)
|
||||
@@ -208,14 +209,43 @@ object KeywordCompletion {
|
||||
|
||||
is JetTypeParameter -> listOf(TYPE_PARAMETER)
|
||||
|
||||
is JetEnumEntry -> listOf(ENUM_ENTRY)
|
||||
|
||||
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 -> null
|
||||
}
|
||||
val modifierTargets = ModifierCheckerCore.possibleTargetMap[keywordTokenType]
|
||||
if (modifierTargets != null && possibleTargets != null && possibleTargets.none { it in modifierTargets }) return false
|
||||
|
||||
val ownerDeclaration = container?.getParentOfType<JetDeclaration>(strict = true)
|
||||
val parentTarget = when (ownerDeclaration) {
|
||||
null -> KotlinTarget.FILE
|
||||
|
||||
is JetClass -> {
|
||||
when {
|
||||
ownerDeclaration.isInterface() -> KotlinTarget.INTERFACE
|
||||
ownerDeclaration.isEnum() -> KotlinTarget.ENUM_CLASS
|
||||
ownerDeclaration.isAnnotation() -> KotlinTarget.ANNOTATION_CLASS
|
||||
ownerDeclaration.isInner() -> KotlinTarget.INNER_CLASS
|
||||
else -> KotlinTarget.CLASS_ONLY
|
||||
}
|
||||
}
|
||||
|
||||
is JetObjectDeclaration -> if (ownerDeclaration.isObjectLiteral()) KotlinTarget.OBJECT_LITERAL else KotlinTarget.OBJECT
|
||||
|
||||
else -> return true
|
||||
}
|
||||
val modifierTargets = ModifierCheckerCore.possibleTargetMap[keywordTokenType] ?: return true
|
||||
return possibleTargets.any { it in modifierTargets }
|
||||
|
||||
val modifierParents = ModifierCheckerCore.possibleParentTargetMap[keywordTokenType]
|
||||
if (modifierParents != null && parentTarget !in modifierParents) return false
|
||||
|
||||
val deprecatedParents = ModifierCheckerCore.deprecatedParentTargetMap[keywordTokenType]
|
||||
if (deprecatedParents != null && parentTarget in deprecatedParents) return false
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ class B {
|
||||
// EXIST: object
|
||||
// EXIST: open
|
||||
// EXIST: private
|
||||
// EXIST: protected
|
||||
// EXIST: public
|
||||
// EXIST: interface
|
||||
// EXIST: val
|
||||
@@ -35,8 +34,4 @@ class B {
|
||||
// EXIST: external
|
||||
// EXIST: annotation
|
||||
// EXIST: const
|
||||
/*TODO:*/
|
||||
// EXIST: inner
|
||||
/*TODO:*/
|
||||
// EXIST: companion object
|
||||
// NOTHING_ELSE
|
||||
|
||||
@@ -16,18 +16,15 @@ var a : Int
|
||||
// EXIST: final
|
||||
// EXIST: fun
|
||||
// EXIST: get
|
||||
// EXIST: inner
|
||||
// EXIST: internal
|
||||
// EXIST: object
|
||||
// EXIST: open
|
||||
// EXIST: private
|
||||
// EXIST: protected
|
||||
// EXIST: public
|
||||
// EXIST: set
|
||||
// EXIST: interface
|
||||
// EXIST: val
|
||||
// EXIST: var
|
||||
// EXIST: companion object
|
||||
// EXIST: operator
|
||||
// EXIST: infix
|
||||
// EXIST: sealed
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
annotation class Test {
|
||||
<caret>
|
||||
}
|
||||
|
||||
// EXIST: abstract
|
||||
// EXIST: class
|
||||
// EXIST: enum
|
||||
// EXIST: final
|
||||
// EXIST: fun
|
||||
// EXIST: object
|
||||
// EXIST: open
|
||||
// EXIST: public
|
||||
// EXIST: interface
|
||||
// EXIST: val
|
||||
// EXIST: var
|
||||
// EXIST: constructor
|
||||
// EXIST: init
|
||||
// EXIST: operator
|
||||
// EXIST: infix
|
||||
// EXIST: sealed
|
||||
// EXIST: lateinit
|
||||
// EXIST: data
|
||||
// EXIST: inline
|
||||
// EXIST: tailrec
|
||||
// EXIST: external
|
||||
// EXIST: annotation
|
||||
// EXIST: const
|
||||
// NOTHING_ELSE
|
||||
@@ -0,0 +1,5 @@
|
||||
enum class Test {
|
||||
<caret>
|
||||
}
|
||||
|
||||
// NUMBER: 0
|
||||
@@ -0,0 +1,39 @@
|
||||
enum class Test {
|
||||
;
|
||||
|
||||
<caret>
|
||||
}
|
||||
|
||||
// EXIST: abstract
|
||||
// EXIST: enum
|
||||
// EXIST: final
|
||||
// EXIST: inner
|
||||
// EXIST: internal
|
||||
// EXIST: open
|
||||
// EXIST: override
|
||||
// EXIST: private
|
||||
// EXIST: protected
|
||||
// EXIST: public
|
||||
// EXIST: companion object
|
||||
// EXIST: operator
|
||||
// EXIST: infix
|
||||
// EXIST: sealed
|
||||
// EXIST: lateinit
|
||||
// EXIST: data
|
||||
// EXIST: inline
|
||||
// EXIST: tailrec
|
||||
// EXIST: external
|
||||
// EXIST: annotation
|
||||
// EXIST: const
|
||||
// EXIST: fun
|
||||
|
||||
/* TODO: items below are not valid here */
|
||||
// EXIST: class
|
||||
// EXIST: constructor
|
||||
// EXIST: init
|
||||
// EXIST: interface
|
||||
// EXIST: object
|
||||
// EXIST: val
|
||||
// EXIST: var
|
||||
|
||||
// NOTHING_ELSE
|
||||
@@ -0,0 +1,30 @@
|
||||
interface Test {
|
||||
<caret>
|
||||
}
|
||||
|
||||
// EXIST: abstract
|
||||
// EXIST: class
|
||||
// EXIST: enum
|
||||
// EXIST: fun
|
||||
// EXIST: object
|
||||
// EXIST: open
|
||||
// EXIST: override
|
||||
// EXIST: private
|
||||
// EXIST: public
|
||||
// EXIST: interface
|
||||
// EXIST: val
|
||||
// EXIST: var
|
||||
// EXIST: constructor
|
||||
// EXIST: init
|
||||
// EXIST: companion object
|
||||
// EXIST: operator
|
||||
// EXIST: infix
|
||||
// EXIST: sealed
|
||||
// EXIST: lateinit
|
||||
// EXIST: data
|
||||
// EXIST: inline
|
||||
// EXIST: tailrec
|
||||
// EXIST: external
|
||||
// EXIST: annotation
|
||||
// EXIST: const
|
||||
// NOTHING_ELSE
|
||||
@@ -0,0 +1,31 @@
|
||||
object Test {
|
||||
<caret>
|
||||
}
|
||||
|
||||
// EXIST: abstract
|
||||
// EXIST: class
|
||||
// EXIST: enum
|
||||
// EXIST: final
|
||||
// EXIST: fun
|
||||
// EXIST: internal
|
||||
// EXIST: object
|
||||
// EXIST: open
|
||||
// EXIST: override
|
||||
// EXIST: private
|
||||
// EXIST: public
|
||||
// EXIST: interface
|
||||
// EXIST: val
|
||||
// EXIST: var
|
||||
// EXIST: constructor
|
||||
// EXIST: init
|
||||
// EXIST: operator
|
||||
// EXIST: infix
|
||||
// EXIST: sealed
|
||||
// EXIST: lateinit
|
||||
// EXIST: data
|
||||
// EXIST: inline
|
||||
// EXIST: tailrec
|
||||
// EXIST: external
|
||||
// EXIST: annotation
|
||||
// EXIST: const
|
||||
// NOTHING_ELSE
|
||||
@@ -8,17 +8,14 @@ package Test
|
||||
// EXIST: final
|
||||
// EXIST: fun
|
||||
// EXIST: import
|
||||
// EXIST: inner
|
||||
// EXIST: internal
|
||||
// EXIST: object
|
||||
// EXIST: open
|
||||
// EXIST: private
|
||||
// EXIST: protected
|
||||
// EXIST: public
|
||||
// EXIST: interface
|
||||
// EXIST: val
|
||||
// EXIST: var
|
||||
// EXIST: companion object
|
||||
// EXIST: operator
|
||||
// EXIST: infix
|
||||
// EXIST: sealed
|
||||
|
||||
@@ -4,6 +4,5 @@ p<caret>
|
||||
|
||||
// EXIST: package
|
||||
// EXIST: private
|
||||
// EXIST: protected
|
||||
// EXIST: public
|
||||
// NOTHING_ELSE
|
||||
|
||||
@@ -6,18 +6,15 @@
|
||||
// EXIST: final
|
||||
// EXIST: fun
|
||||
// EXIST: import
|
||||
// EXIST: inner
|
||||
// EXIST: internal
|
||||
// EXIST: object
|
||||
// EXIST: open
|
||||
// EXIST: package
|
||||
// EXIST: private
|
||||
// EXIST: protected
|
||||
// EXIST: public
|
||||
// EXIST: interface
|
||||
// EXIST: val
|
||||
// EXIST: var
|
||||
// EXIST: companion object
|
||||
// EXIST: operator
|
||||
// EXIST: infix
|
||||
// EXIST: sealed
|
||||
|
||||
+30
@@ -119,6 +119,12 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InAnnotationClassScope.kt")
|
||||
public void testInAnnotationClassScope() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InAnnotationClassScope.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InArgumentList.kt")
|
||||
public void testInArgumentList() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InArgumentList.kt");
|
||||
@@ -173,6 +179,18 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InEnumScope1.kt")
|
||||
public void testInEnumScope1() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InEnumScope1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InEnumScope2.kt")
|
||||
public void testInEnumScope2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InEnumScope2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InFunctionExpressionBody.kt")
|
||||
public void testInFunctionExpressionBody() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InFunctionExpressionBody.kt");
|
||||
@@ -203,6 +221,12 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InInterfaceScope.kt")
|
||||
public void testInInterfaceScope() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InInterfaceScope.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InMemberFunParametersList.kt")
|
||||
public void testInMemberFunParametersList() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InMemberFunParametersList.kt");
|
||||
@@ -221,6 +245,12 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InObjectScope.kt")
|
||||
public void testInObjectScope() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InObjectScope.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InParameterDefaultValue.kt")
|
||||
public void testInParameterDefaultValue() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InParameterDefaultValue.kt");
|
||||
|
||||
Reference in New Issue
Block a user