Adapting code completion to no annotations without "@"

This commit is contained in:
Valentin Kipyatkov
2015-10-10 17:58:41 +03:00
parent ddcab047ce
commit f90ff31507
17 changed files with 21 additions and 72 deletions
@@ -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
}
}
@@ -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,7 +1,7 @@
annotation class Hello
val v = 1
<caret>
@<caret>
fun some() {}
// INVOCATION_COUNT: 0
@@ -1,7 +1,7 @@
annotation class Hello
val v = 1
fun foo(<caret>) { }
fun foo(@<caret>) { }
// INVOCATION_COUNT: 1
// EXIST: Hello
@@ -1,6 +1,6 @@
annotation class SHello
fun foo(S<caret>) { }
fun foo(@S<caret>) { }
// INVOCATION_COUNT: 1
// EXIST: SHello
@@ -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,7 +1,7 @@
annotation class Hello
val v = 1
fun foo(@Volatile <caret>) { }
fun foo(@Volatile @<caret>) { }
// INVOCATION_COUNT: 1
// EXIST: Hello
@@ -1,7 +1,7 @@
annotation class Hello
val v = 1
fun foo(<caret>
fun foo(@<caret>
// INVOCATION_COUNT: 1
// EXIST: Hello
@@ -1,4 +1,4 @@
fun foo(kotlin.<caret>) { }
fun foo(@kotlin.<caret>) { }
// INVOCATION_COUNT: 1
// EXIST: Suppress
@@ -1,7 +1,7 @@
annotation class Hello
val v = 1
<caret>
@<caret>
// INVOCATION_COUNT: 0
// EXIST: Hello
@@ -1,7 +1,7 @@
annotation class Hello
val v = 1
<caret>
@<caret>
class C
// INVOCATION_COUNT: 0
@@ -1,6 +1,6 @@
import java.lang.annotation.*
Retention(<caret>
@Retention(<caret>
// INVOCATION_COUNT: 0
// EXIST_JAVA_ONLY: RetentionPolicy
@@ -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,5 +1,5 @@
class MyClassA
Deprecated class MyClassB
@Deprecated class MyClassB
class MyClassC
fun foo(myCla<caret>)