Adapting code completion to no annotations without "@"
This commit is contained in:
+6
-40
@@ -30,8 +30,6 @@ import com.intellij.psi.util.PsiTreeUtil
|
|||||||
import com.intellij.util.ProcessingContext
|
import com.intellij.util.ProcessingContext
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.completion.smart.ExpectedInfoMatch
|
import org.jetbrains.kotlin.idea.completion.smart.ExpectedInfoMatch
|
||||||
import org.jetbrains.kotlin.idea.completion.smart.SMART_COMPLETION_ITEM_PRIORITY_KEY
|
import org.jetbrains.kotlin.idea.completion.smart.SMART_COMPLETION_ITEM_PRIORITY_KEY
|
||||||
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletion
|
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletion
|
||||||
@@ -42,7 +40,10 @@ import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
@@ -68,16 +69,6 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
|||||||
classKindFilter = { it != ClassKind.ENUM_ENTRY }
|
classKindFilter = { it != ClassKind.ENUM_ENTRY }
|
||||||
),
|
),
|
||||||
|
|
||||||
ANNOTATION_TYPES(
|
|
||||||
descriptorKindFilter = ANNOTATION_TYPES_FILTER,
|
|
||||||
classKindFilter = { it == ClassKind.ANNOTATION_CLASS }
|
|
||||||
),
|
|
||||||
|
|
||||||
ANNOTATION_TYPES_OR_PARAMETER_NAME(
|
|
||||||
descriptorKindFilter = ANNOTATION_TYPES_FILTER,
|
|
||||||
classKindFilter = { it == ClassKind.ANNOTATION_CLASS }
|
|
||||||
),
|
|
||||||
|
|
||||||
KEYWORDS_ONLY(descriptorKindFilter = null, classKindFilter = null),
|
KEYWORDS_ONLY(descriptorKindFilter = null, classKindFilter = null),
|
||||||
|
|
||||||
NAMED_ARGUMENTS_ONLY(descriptorKindFilter = null, classKindFilter = null),
|
NAMED_ARGUMENTS_ONLY(descriptorKindFilter = null, classKindFilter = null),
|
||||||
@@ -126,18 +117,6 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
|||||||
CompletionKind.KEYWORDS_ONLY
|
CompletionKind.KEYWORDS_ONLY
|
||||||
}
|
}
|
||||||
|
|
||||||
val annotationEntry = position.getStrictParentOfType<JetAnnotationEntry>()
|
|
||||||
if (annotationEntry != null) {
|
|
||||||
val valueArgList = position.getStrictParentOfType<JetValueArgumentList>()
|
|
||||||
if (valueArgList == null || !annotationEntry.isAncestor(valueArgList)) {
|
|
||||||
val parent = annotationEntry.getParent()
|
|
||||||
if (parent is JetDeclarationModifierList && parent.getParent() is JetParameter) {
|
|
||||||
return CompletionKind.ANNOTATION_TYPES_OR_PARAMETER_NAME
|
|
||||||
}
|
|
||||||
return CompletionKind.ANNOTATION_TYPES
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that completion in the type annotation context and if there's a qualified
|
// Check that completion in the type annotation context and if there's a qualified
|
||||||
// expression we are at first of it
|
// expression we are at first of it
|
||||||
val typeReference = position.getStrictParentOfType<JetTypeReference>()
|
val typeReference = position.getStrictParentOfType<JetTypeReference>()
|
||||||
@@ -156,7 +135,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun shouldCompleteParameterNameAndType(): Boolean {
|
private fun shouldCompleteParameterNameAndType(): Boolean {
|
||||||
if (completionKind != CompletionKind.PARAMETER_NAME && completionKind != CompletionKind.ANNOTATION_TYPES_OR_PARAMETER_NAME) return false
|
if (completionKind != CompletionKind.PARAMETER_NAME) return false
|
||||||
|
|
||||||
val parameter = position.getNonStrictParentOfType<JetParameter>()!!
|
val parameter = position.getNonStrictParentOfType<JetParameter>()!!
|
||||||
val list = parameter.parent as? JetParameterList ?: return false
|
val list = parameter.parent as? JetParameterList ?: return false
|
||||||
@@ -170,7 +149,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public fun shouldDisableAutoPopup(): Boolean {
|
public fun shouldDisableAutoPopup(): Boolean {
|
||||||
if (completionKind == CompletionKind.PARAMETER_NAME || completionKind == CompletionKind.ANNOTATION_TYPES_OR_PARAMETER_NAME) {
|
if (completionKind == CompletionKind.PARAMETER_NAME) {
|
||||||
if (!shouldCompleteParameterNameAndType() || TemplateManager.getInstance(project).getActiveTemplate(parameters.editor) != null) {
|
if (!shouldCompleteParameterNameAndType() || TemplateManager.getInstance(project).getActiveTemplate(parameters.editor) != null) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -395,17 +374,4 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
|||||||
|
|
||||||
return sorter
|
return sorter
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
|
||||||
object NonAnnotationClassifierExclude : DescriptorKindExclude() {
|
|
||||||
override fun excludes(descriptor: DeclarationDescriptor): Boolean {
|
|
||||||
if (descriptor !is ClassifierDescriptor) return false
|
|
||||||
return descriptor !is ClassDescriptor || descriptor.getKind() != ClassKind.ANNOTATION_CLASS
|
|
||||||
}
|
|
||||||
|
|
||||||
override val fullyExcludedDescriptorKinds: Int get() = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
val ANNOTATION_TYPES_FILTER = DescriptorKindFilter(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS_MASK or DescriptorKindFilter.PACKAGES_MASK) exclude NonAnnotationClassifierExclude
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
-17
@@ -84,7 +84,6 @@ public class KotlinCompletionContributor : CompletionContributor() {
|
|||||||
else -> specialLambdaSignatureDummyIdentifier(tokenBefore)
|
else -> specialLambdaSignatureDummyIdentifier(tokenBefore)
|
||||||
?: specialExtensionReceiverDummyIdentifier(tokenBefore)
|
?: specialExtensionReceiverDummyIdentifier(tokenBefore)
|
||||||
?: specialInTypeArgsDummyIdentifier(tokenBefore)
|
?: specialInTypeArgsDummyIdentifier(tokenBefore)
|
||||||
?: specialInParameterListDummyIdentifier(tokenBefore)
|
|
||||||
?: specialInArgumentListDummyIdentifier(tokenBefore)
|
?: specialInArgumentListDummyIdentifier(tokenBefore)
|
||||||
?: DEFAULT_DUMMY_IDENTIFIER
|
?: DEFAULT_DUMMY_IDENTIFIER
|
||||||
}
|
}
|
||||||
@@ -389,22 +388,6 @@ public class KotlinCompletionContributor : CompletionContributor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun specialInParameterListDummyIdentifier(tokenBefore: PsiElement?): String? {
|
|
||||||
if (tokenBefore == null) return null
|
|
||||||
var parent = tokenBefore.getParent()
|
|
||||||
while (parent != null) {
|
|
||||||
if (parent is JetParameterList) {
|
|
||||||
val balance = countParenthesisBalance(tokenBefore, parent)
|
|
||||||
val count = if (balance > 1) balance - 1 else 0
|
|
||||||
return CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED + ")".repeat(count) + " a: B"
|
|
||||||
}
|
|
||||||
if (parent is JetTypeElement) return null
|
|
||||||
if (parent is JetAnnotationEntry) return null
|
|
||||||
parent = parent.getParent()
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun specialInArgumentListDummyIdentifier(tokenBefore: PsiElement?): String? {
|
private fun specialInArgumentListDummyIdentifier(tokenBefore: PsiElement?): String? {
|
||||||
// If we insert $ in the argument list of a delegation specifier, this will break parsing
|
// If we insert $ in the argument list of a delegation specifier, this will break parsing
|
||||||
// and the following block will not be attached as a body to the constructor. Therefore
|
// and the following block will not be attached as a body to the constructor. Therefore
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<caret> annotation class Annotated
|
@<caret> annotation class Annotated
|
||||||
|
|
||||||
// EXIST: Target
|
// EXIST: Target
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
@Dep<caret>
|
@Deprecate<caret>
|
||||||
fun foo() { }
|
fun foo() { }
|
||||||
|
|
||||||
// INVOCATION_COUNT: 2
|
// INVOCATION_COUNT: 2
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
annotation class Hello
|
annotation class Hello
|
||||||
val v = 1
|
val v = 1
|
||||||
|
|
||||||
<caret>
|
@<caret>
|
||||||
fun some() {}
|
fun some() {}
|
||||||
|
|
||||||
// INVOCATION_COUNT: 0
|
// INVOCATION_COUNT: 0
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
annotation class Hello
|
annotation class Hello
|
||||||
val v = 1
|
val v = 1
|
||||||
|
|
||||||
fun foo(<caret>) { }
|
fun foo(@<caret>) { }
|
||||||
|
|
||||||
// INVOCATION_COUNT: 1
|
// INVOCATION_COUNT: 1
|
||||||
// EXIST: Hello
|
// EXIST: Hello
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
annotation class SHello
|
annotation class SHello
|
||||||
|
|
||||||
fun foo(S<caret>) { }
|
fun foo(@S<caret>) { }
|
||||||
|
|
||||||
// INVOCATION_COUNT: 1
|
// INVOCATION_COUNT: 1
|
||||||
// EXIST: SHello
|
// EXIST: SHello
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
annotation class Hello
|
annotation class Hello
|
||||||
val v = 1
|
val v = 1
|
||||||
|
|
||||||
fun foo(p: String, <caret>) { }
|
fun foo(p: String, @<caret>) { }
|
||||||
|
|
||||||
// INVOCATION_COUNT: 1
|
// INVOCATION_COUNT: 1
|
||||||
// EXIST: Hello
|
// EXIST: Hello
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
annotation class Hello
|
annotation class Hello
|
||||||
val v = 1
|
val v = 1
|
||||||
|
|
||||||
fun foo(@Volatile <caret>) { }
|
fun foo(@Volatile @<caret>) { }
|
||||||
|
|
||||||
// INVOCATION_COUNT: 1
|
// INVOCATION_COUNT: 1
|
||||||
// EXIST: Hello
|
// EXIST: Hello
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
annotation class Hello
|
annotation class Hello
|
||||||
val v = 1
|
val v = 1
|
||||||
|
|
||||||
fun foo(<caret>
|
fun foo(@<caret>
|
||||||
|
|
||||||
// INVOCATION_COUNT: 1
|
// INVOCATION_COUNT: 1
|
||||||
// EXIST: Hello
|
// EXIST: Hello
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
fun foo(kotlin.<caret>) { }
|
fun foo(@kotlin.<caret>) { }
|
||||||
|
|
||||||
// INVOCATION_COUNT: 1
|
// INVOCATION_COUNT: 1
|
||||||
// EXIST: Suppress
|
// EXIST: Suppress
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
annotation class Hello
|
annotation class Hello
|
||||||
val v = 1
|
val v = 1
|
||||||
|
|
||||||
<caret>
|
@<caret>
|
||||||
|
|
||||||
// INVOCATION_COUNT: 0
|
// INVOCATION_COUNT: 0
|
||||||
// EXIST: Hello
|
// EXIST: Hello
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
annotation class Hello
|
annotation class Hello
|
||||||
val v = 1
|
val v = 1
|
||||||
|
|
||||||
<caret>
|
@<caret>
|
||||||
class C
|
class C
|
||||||
|
|
||||||
// INVOCATION_COUNT: 0
|
// INVOCATION_COUNT: 0
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import java.lang.annotation.*
|
import java.lang.annotation.*
|
||||||
|
|
||||||
Retention(<caret>
|
@Retention(<caret>
|
||||||
|
|
||||||
// INVOCATION_COUNT: 0
|
// INVOCATION_COUNT: 0
|
||||||
// EXIST_JAVA_ONLY: RetentionPolicy
|
// EXIST_JAVA_ONLY: RetentionPolicy
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import java.lang.annotation.*
|
import java.lang.annotation.*
|
||||||
|
|
||||||
Retention(RetentionPolicy.<caret>
|
@Retention(RetentionPolicy.<caret>
|
||||||
|
|
||||||
// INVOCATION_COUNT: 0
|
// INVOCATION_COUNT: 0
|
||||||
// EXIST_JAVA_ONLY: SOURCE
|
// EXIST_JAVA_ONLY: SOURCE
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
fun foo1() {}
|
fun foo1() {}
|
||||||
Deprecated("Use foo3 instead") fun foo2() {}
|
@Deprecated("Use foo3 instead") fun foo2() {}
|
||||||
fun foo3() {}
|
fun foo3() {}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
class MyClassA
|
class MyClassA
|
||||||
Deprecated class MyClassB
|
@Deprecated class MyClassB
|
||||||
class MyClassC
|
class MyClassC
|
||||||
|
|
||||||
fun foo(myCla<caret>)
|
fun foo(myCla<caret>)
|
||||||
|
|||||||
Reference in New Issue
Block a user