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 org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
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.SMART_COMPLETION_ITEM_PRIORITY_KEY
|
||||
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.Name
|
||||
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.scopes.DescriptorKindExclude
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
@@ -68,16 +69,6 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
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),
|
||||
|
||||
NAMED_ARGUMENTS_ONLY(descriptorKindFilter = null, classKindFilter = null),
|
||||
@@ -126,18 +117,6 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
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
|
||||
// expression we are at first of it
|
||||
val typeReference = position.getStrictParentOfType<JetTypeReference>()
|
||||
@@ -156,7 +135,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
}
|
||||
|
||||
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 list = parameter.parent as? JetParameterList ?: return false
|
||||
@@ -170,7 +149,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
}
|
||||
|
||||
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) {
|
||||
return true
|
||||
}
|
||||
@@ -395,17 +374,4 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
|
||||
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)
|
||||
?: specialExtensionReceiverDummyIdentifier(tokenBefore)
|
||||
?: specialInTypeArgsDummyIdentifier(tokenBefore)
|
||||
?: specialInParameterListDummyIdentifier(tokenBefore)
|
||||
?: specialInArgumentListDummyIdentifier(tokenBefore)
|
||||
?: 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? {
|
||||
// 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
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<caret> annotation class Annotated
|
||||
@<caret> annotation class Annotated
|
||||
|
||||
// EXIST: Target
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@Dep<caret>
|
||||
@Deprecate<caret>
|
||||
fun foo() { }
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
annotation class Hello
|
||||
val v = 1
|
||||
|
||||
<caret>
|
||||
@<caret>
|
||||
fun some() {}
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
annotation class Hello
|
||||
val v = 1
|
||||
|
||||
fun foo(<caret>) { }
|
||||
fun foo(@<caret>) { }
|
||||
|
||||
// INVOCATION_COUNT: 1
|
||||
// EXIST: Hello
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
annotation class SHello
|
||||
|
||||
fun foo(S<caret>) { }
|
||||
fun foo(@S<caret>) { }
|
||||
|
||||
// INVOCATION_COUNT: 1
|
||||
// EXIST: SHello
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
annotation class Hello
|
||||
val v = 1
|
||||
|
||||
fun foo(p: String, <caret>) { }
|
||||
fun foo(p: String, @<caret>) { }
|
||||
|
||||
// INVOCATION_COUNT: 1
|
||||
// EXIST: Hello
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
annotation class Hello
|
||||
val v = 1
|
||||
|
||||
fun foo(@Volatile <caret>) { }
|
||||
fun foo(@Volatile @<caret>) { }
|
||||
|
||||
// INVOCATION_COUNT: 1
|
||||
// EXIST: Hello
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
annotation class Hello
|
||||
val v = 1
|
||||
|
||||
fun foo(<caret>
|
||||
fun foo(@<caret>
|
||||
|
||||
// INVOCATION_COUNT: 1
|
||||
// EXIST: Hello
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
fun foo(kotlin.<caret>) { }
|
||||
fun foo(@kotlin.<caret>) { }
|
||||
|
||||
// INVOCATION_COUNT: 1
|
||||
// EXIST: Suppress
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
annotation class Hello
|
||||
val v = 1
|
||||
|
||||
<caret>
|
||||
@<caret>
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
// EXIST: Hello
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
annotation class Hello
|
||||
val v = 1
|
||||
|
||||
<caret>
|
||||
@<caret>
|
||||
class C
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import java.lang.annotation.*
|
||||
|
||||
Retention(<caret>
|
||||
@Retention(<caret>
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
// EXIST_JAVA_ONLY: RetentionPolicy
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import java.lang.annotation.*
|
||||
|
||||
Retention(RetentionPolicy.<caret>
|
||||
@Retention(RetentionPolicy.<caret>
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
// EXIST_JAVA_ONLY: SOURCE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fun foo1() {}
|
||||
Deprecated("Use foo3 instead") fun foo2() {}
|
||||
@Deprecated("Use foo3 instead") fun foo2() {}
|
||||
fun foo3() {}
|
||||
|
||||
fun test() {
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
class MyClassA
|
||||
Deprecated class MyClassB
|
||||
@Deprecated class MyClassB
|
||||
class MyClassC
|
||||
|
||||
fun foo(myCla<caret>)
|
||||
|
||||
Reference in New Issue
Block a user