KT-7844 Completion for top level classes should propose the file name

#KT-7844 Fixed
This commit is contained in:
Valentin Kipyatkov
2015-10-20 22:07:18 +03:00
parent eb8fb80325
commit b26a590614
8 changed files with 109 additions and 5 deletions
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.completion.CompletionResultSet
import com.intellij.codeInsight.completion.CompletionSorter
import com.intellij.codeInsight.completion.CompletionType
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.codeInsight.template.TemplateManager
import com.intellij.patterns.PatternCondition
import com.intellij.patterns.StandardPatterns
@@ -43,6 +44,7 @@ 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.renderer.render
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
@@ -63,6 +65,8 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
PARAMETER_NAME(descriptorKindFilter = null),
TOP_LEVEL_CLASS_NAME(descriptorKindFilter = null),
SUPER_QUALIFIER(descriptorKindFilter = DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS)
}
@@ -94,11 +98,16 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
private fun detectCompletionKind(): CompletionKind {
if (nameExpression == null) {
val parameter = position.getParent() as? KtParameter
return if (parameter != null && position == parameter.getNameIdentifier())
CompletionKind.PARAMETER_NAME
else
CompletionKind.KEYWORDS_ONLY
return when {
(position.parent as? KtParameter)?.nameIdentifier == position ->
CompletionKind.PARAMETER_NAME
(position.parent as? KtClassOrObject)?.nameIdentifier == position && position.parent.parent is KtFile ->
CompletionKind.TOP_LEVEL_CLASS_NAME
else ->
CompletionKind.KEYWORDS_ONLY
}
}
if (NamedArgumentCompletion.isOnlyNamedArgumentExpected(nameExpression)) {
@@ -155,6 +164,11 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
return
}
if (completionKind == CompletionKind.TOP_LEVEL_CLASS_NAME) {
completeTopLevelClassName()
return
}
// if we are typing parameter name, restart completion each time we type an upper case letter because new suggestions will appear (previous words can be used as user prefix)
if (parameterNameAndTypeCompletion != null) {
val prefixPattern = StandardPatterns.string().with(object : PatternCondition<String>("Prefix ends with uppercase letter") {
@@ -344,6 +358,16 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
.forEach { collector.addElement(it) }
}
private fun completeTopLevelClassName() {
val name = parameters.originalFile.virtualFile.nameWithoutExtension
if (!(Name.isValidIdentifier(name) && Name.identifier(name).render() == name && name[0].isUpperCase())) return
if ((parameters.originalFile as KtFile).declarations.any { it is KtClassOrObject && it.name == name }) return
val lookupElement = LookupElementBuilder.create(name)
lookupElement.putUserData(KotlinCompletionCharFilter.SUPPRESS_ITEM_SELECTION_BY_CHARS_ON_TYPING, Unit)
collector.addElement(lookupElement)
}
override fun createSorter(): CompletionSorter {
var sorter = super.createSorter()
@@ -0,0 +1,3 @@
class <caret>
// NUMBER: 0
@@ -0,0 +1,3 @@
class <caret>
// EXIST: { lookupString: "TopLevelClassName1", itemText: "TopLevelClassName1" }
@@ -0,0 +1,5 @@
class A {
class <caret>
}
// NUMBER: 0
@@ -0,0 +1,6 @@
class <caret>
class TopLevelClassName5 {
}
// NUMBER: 0
@@ -0,0 +1,3 @@
class <caret>
// NUMBER: 0
@@ -691,6 +691,36 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
doTest(fileName);
}
@TestMetadata("TopLevelClassName1.kt")
public void testTopLevelClassName1() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TopLevelClassName1.kt");
doTest(fileName);
}
@TestMetadata("topLevelClassName2.kt")
public void testTopLevelClassName2() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/topLevelClassName2.kt");
doTest(fileName);
}
@TestMetadata("TopLevelClassName4.kt")
public void testTopLevelClassName4() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TopLevelClassName4.kt");
doTest(fileName);
}
@TestMetadata("TopLevelClassName5.kt")
public void testTopLevelClassName5() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TopLevelClassName5.kt");
doTest(fileName);
}
@TestMetadata("TopLevelClassName-3.kt")
public void testTopLevelClassName_3() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TopLevelClassName-3.kt");
doTest(fileName);
}
@TestMetadata("TypeArgCompletionBug.kt")
public void testTypeArgCompletionBug() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TypeArgCompletionBug.kt");
@@ -691,6 +691,36 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
doTest(fileName);
}
@TestMetadata("TopLevelClassName1.kt")
public void testTopLevelClassName1() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TopLevelClassName1.kt");
doTest(fileName);
}
@TestMetadata("topLevelClassName2.kt")
public void testTopLevelClassName2() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/topLevelClassName2.kt");
doTest(fileName);
}
@TestMetadata("TopLevelClassName4.kt")
public void testTopLevelClassName4() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TopLevelClassName4.kt");
doTest(fileName);
}
@TestMetadata("TopLevelClassName5.kt")
public void testTopLevelClassName5() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TopLevelClassName5.kt");
doTest(fileName);
}
@TestMetadata("TopLevelClassName-3.kt")
public void testTopLevelClassName_3() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TopLevelClassName-3.kt");
doTest(fileName);
}
@TestMetadata("TypeArgCompletionBug.kt")
public void testTypeArgCompletionBug() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TypeArgCompletionBug.kt");