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)
|
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),
|
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,
|
OVERRIDE_KEYWORD to EnumSet.of(CLASS_ONLY, INNER_CLASS, LOCAL_CLASS, OBJECT, OBJECT_LITERAL,
|
||||||
INTERFACE, ENUM_CLASS, ENUM_ENTRY),
|
INTERFACE, ENUM_CLASS, ENUM_ENTRY),
|
||||||
@@ -107,7 +107,7 @@ public object ModifierCheckerCore {
|
|||||||
COMPANION_KEYWORD to EnumSet.of(CLASS_ONLY, ENUM_CLASS, INTERFACE)
|
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
|
// Deprecated in M15
|
||||||
FINAL_KEYWORD to EnumSet.of(INTERFACE),
|
FINAL_KEYWORD to EnumSet.of(INTERFACE),
|
||||||
PROTECTED_KEYWORD to EnumSet.of(OBJECT)
|
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.filters.position.PositionElementFilter
|
||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import com.intellij.psi.tree.TokenSet
|
import com.intellij.psi.tree.TokenSet
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
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.KotlinFunctionInsertHandler
|
||||||
import org.jetbrains.kotlin.idea.completion.handlers.KotlinKeywordInsertHandler
|
import org.jetbrains.kotlin.idea.completion.handlers.KotlinKeywordInsertHandler
|
||||||
@@ -197,10 +198,10 @@ object KeywordCompletion {
|
|||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
if (elementAt.parent !is JetModifierList) return true
|
if (elementAt.parent !is JetModifierList) return true
|
||||||
val declaration = elementAt.parent.parent
|
val container = elementAt.parent.parent
|
||||||
val possibleTargets = when (declaration) {
|
val possibleTargets = when (container) {
|
||||||
is JetParameter -> {
|
is JetParameter -> {
|
||||||
if (declaration.ownerFunction is JetPrimaryConstructor)
|
if (container.ownerFunction is JetPrimaryConstructor)
|
||||||
listOf(VALUE_PARAMETER, MEMBER_PROPERTY)
|
listOf(VALUE_PARAMETER, MEMBER_PROPERTY)
|
||||||
else
|
else
|
||||||
listOf(VALUE_PARAMETER)
|
listOf(VALUE_PARAMETER)
|
||||||
@@ -208,14 +209,43 @@ object KeywordCompletion {
|
|||||||
|
|
||||||
is JetTypeParameter -> listOf(TYPE_PARAMETER)
|
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 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)
|
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
|
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: object
|
||||||
// EXIST: open
|
// EXIST: open
|
||||||
// EXIST: private
|
// EXIST: private
|
||||||
// EXIST: protected
|
|
||||||
// EXIST: public
|
// EXIST: public
|
||||||
// EXIST: interface
|
// EXIST: interface
|
||||||
// EXIST: val
|
// EXIST: val
|
||||||
@@ -35,8 +34,4 @@ class B {
|
|||||||
// EXIST: external
|
// EXIST: external
|
||||||
// EXIST: annotation
|
// EXIST: annotation
|
||||||
// EXIST: const
|
// EXIST: const
|
||||||
/*TODO:*/
|
|
||||||
// EXIST: inner
|
|
||||||
/*TODO:*/
|
|
||||||
// EXIST: companion object
|
|
||||||
// NOTHING_ELSE
|
// NOTHING_ELSE
|
||||||
|
|||||||
@@ -16,18 +16,15 @@ var a : Int
|
|||||||
// EXIST: final
|
// EXIST: final
|
||||||
// EXIST: fun
|
// EXIST: fun
|
||||||
// EXIST: get
|
// EXIST: get
|
||||||
// EXIST: inner
|
|
||||||
// EXIST: internal
|
// EXIST: internal
|
||||||
// EXIST: object
|
// EXIST: object
|
||||||
// EXIST: open
|
// EXIST: open
|
||||||
// EXIST: private
|
// EXIST: private
|
||||||
// EXIST: protected
|
|
||||||
// EXIST: public
|
// EXIST: public
|
||||||
// EXIST: set
|
// EXIST: set
|
||||||
// EXIST: interface
|
// EXIST: interface
|
||||||
// EXIST: val
|
// EXIST: val
|
||||||
// EXIST: var
|
// EXIST: var
|
||||||
// EXIST: companion object
|
|
||||||
// EXIST: operator
|
// EXIST: operator
|
||||||
// EXIST: infix
|
// EXIST: infix
|
||||||
// EXIST: sealed
|
// 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: final
|
||||||
// EXIST: fun
|
// EXIST: fun
|
||||||
// EXIST: import
|
// EXIST: import
|
||||||
// EXIST: inner
|
|
||||||
// EXIST: internal
|
// EXIST: internal
|
||||||
// EXIST: object
|
// EXIST: object
|
||||||
// EXIST: open
|
// EXIST: open
|
||||||
// EXIST: private
|
// EXIST: private
|
||||||
// EXIST: protected
|
|
||||||
// EXIST: public
|
// EXIST: public
|
||||||
// EXIST: interface
|
// EXIST: interface
|
||||||
// EXIST: val
|
// EXIST: val
|
||||||
// EXIST: var
|
// EXIST: var
|
||||||
// EXIST: companion object
|
|
||||||
// EXIST: operator
|
// EXIST: operator
|
||||||
// EXIST: infix
|
// EXIST: infix
|
||||||
// EXIST: sealed
|
// EXIST: sealed
|
||||||
|
|||||||
@@ -4,6 +4,5 @@ p<caret>
|
|||||||
|
|
||||||
// EXIST: package
|
// EXIST: package
|
||||||
// EXIST: private
|
// EXIST: private
|
||||||
// EXIST: protected
|
|
||||||
// EXIST: public
|
// EXIST: public
|
||||||
// NOTHING_ELSE
|
// NOTHING_ELSE
|
||||||
|
|||||||
@@ -6,18 +6,15 @@
|
|||||||
// EXIST: final
|
// EXIST: final
|
||||||
// EXIST: fun
|
// EXIST: fun
|
||||||
// EXIST: import
|
// EXIST: import
|
||||||
// EXIST: inner
|
|
||||||
// EXIST: internal
|
// EXIST: internal
|
||||||
// EXIST: object
|
// EXIST: object
|
||||||
// EXIST: open
|
// EXIST: open
|
||||||
// EXIST: package
|
// EXIST: package
|
||||||
// EXIST: private
|
// EXIST: private
|
||||||
// EXIST: protected
|
|
||||||
// EXIST: public
|
// EXIST: public
|
||||||
// EXIST: interface
|
// EXIST: interface
|
||||||
// EXIST: val
|
// EXIST: val
|
||||||
// EXIST: var
|
// EXIST: var
|
||||||
// EXIST: companion object
|
|
||||||
// EXIST: operator
|
// EXIST: operator
|
||||||
// EXIST: infix
|
// EXIST: infix
|
||||||
// EXIST: sealed
|
// EXIST: sealed
|
||||||
|
|||||||
+30
@@ -119,6 +119,12 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("InArgumentList.kt")
|
||||||
public void testInArgumentList() throws Exception {
|
public void testInArgumentList() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InArgumentList.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InArgumentList.kt");
|
||||||
@@ -173,6 +179,18 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("InFunctionExpressionBody.kt")
|
||||||
public void testInFunctionExpressionBody() throws Exception {
|
public void testInFunctionExpressionBody() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InFunctionExpressionBody.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InFunctionExpressionBody.kt");
|
||||||
@@ -203,6 +221,12 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("InMemberFunParametersList.kt")
|
||||||
public void testInMemberFunParametersList() throws Exception {
|
public void testInMemberFunParametersList() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InMemberFunParametersList.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InMemberFunParametersList.kt");
|
||||||
@@ -221,6 +245,12 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("InParameterDefaultValue.kt")
|
||||||
public void testInParameterDefaultValue() throws Exception {
|
public void testInParameterDefaultValue() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InParameterDefaultValue.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/keywords/InParameterDefaultValue.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user