KT-7844 Completion for top level classes should propose the file name
#KT-7844 Fixed
This commit is contained in:
+29
-5
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.completion.CompletionResultSet
|
|||||||
import com.intellij.codeInsight.completion.CompletionSorter
|
import com.intellij.codeInsight.completion.CompletionSorter
|
||||||
import com.intellij.codeInsight.completion.CompletionType
|
import com.intellij.codeInsight.completion.CompletionType
|
||||||
import com.intellij.codeInsight.lookup.LookupElement
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||||
import com.intellij.codeInsight.template.TemplateManager
|
import com.intellij.codeInsight.template.TemplateManager
|
||||||
import com.intellij.patterns.PatternCondition
|
import com.intellij.patterns.PatternCondition
|
||||||
import com.intellij.patterns.StandardPatterns
|
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.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
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.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
|
||||||
@@ -63,6 +65,8 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
|||||||
|
|
||||||
PARAMETER_NAME(descriptorKindFilter = null),
|
PARAMETER_NAME(descriptorKindFilter = null),
|
||||||
|
|
||||||
|
TOP_LEVEL_CLASS_NAME(descriptorKindFilter = null),
|
||||||
|
|
||||||
SUPER_QUALIFIER(descriptorKindFilter = DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS)
|
SUPER_QUALIFIER(descriptorKindFilter = DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,11 +98,16 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
|||||||
|
|
||||||
private fun detectCompletionKind(): CompletionKind {
|
private fun detectCompletionKind(): CompletionKind {
|
||||||
if (nameExpression == null) {
|
if (nameExpression == null) {
|
||||||
val parameter = position.getParent() as? KtParameter
|
return when {
|
||||||
return if (parameter != null && position == parameter.getNameIdentifier())
|
(position.parent as? KtParameter)?.nameIdentifier == position ->
|
||||||
CompletionKind.PARAMETER_NAME
|
CompletionKind.PARAMETER_NAME
|
||||||
else
|
|
||||||
CompletionKind.KEYWORDS_ONLY
|
(position.parent as? KtClassOrObject)?.nameIdentifier == position && position.parent.parent is KtFile ->
|
||||||
|
CompletionKind.TOP_LEVEL_CLASS_NAME
|
||||||
|
|
||||||
|
else ->
|
||||||
|
CompletionKind.KEYWORDS_ONLY
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NamedArgumentCompletion.isOnlyNamedArgumentExpected(nameExpression)) {
|
if (NamedArgumentCompletion.isOnlyNamedArgumentExpected(nameExpression)) {
|
||||||
@@ -155,6 +164,11 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
|||||||
return
|
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 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) {
|
if (parameterNameAndTypeCompletion != null) {
|
||||||
val prefixPattern = StandardPatterns.string().with(object : PatternCondition<String>("Prefix ends with uppercase letter") {
|
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) }
|
.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 {
|
override fun createSorter(): CompletionSorter {
|
||||||
var sorter = super.createSorter()
|
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
|
||||||
+30
@@ -691,6 +691,36 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("TypeArgCompletionBug.kt")
|
||||||
public void testTypeArgCompletionBug() throws Exception {
|
public void testTypeArgCompletionBug() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TypeArgCompletionBug.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TypeArgCompletionBug.kt");
|
||||||
|
|||||||
+30
@@ -691,6 +691,36 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("TypeArgCompletionBug.kt")
|
||||||
public void testTypeArgCompletionBug() throws Exception {
|
public void testTypeArgCompletionBug() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TypeArgCompletionBug.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TypeArgCompletionBug.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user