KT-6608 Code completion does not work after $ in string literals
KT-5070 Add braces when complete function in string templates #KT-6608 Fixed #KT-5070 Fixed
This commit is contained in:
@@ -17,36 +17,38 @@
|
|||||||
package org.jetbrains.kotlin.idea.completion
|
package org.jetbrains.kotlin.idea.completion
|
||||||
|
|
||||||
import com.intellij.codeInsight.completion.*
|
import com.intellij.codeInsight.completion.*
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.patterns.CharPattern
|
||||||
|
import com.intellij.patterns.PatternCondition
|
||||||
|
import com.intellij.patterns.StandardPatterns
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import com.intellij.util.ProcessingContext
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.idea.caches.KotlinIndicesHelper
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.*
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper
|
import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper
|
||||||
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletion
|
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletion
|
||||||
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference
|
|
||||||
import org.jetbrains.kotlin.idea.caches.KotlinIndicesHelper
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptorKindExclude
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils
|
|
||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
|
||||||
import org.jetbrains.kotlin.idea.refactoring.comparePossiblyOverridingDescriptors
|
import org.jetbrains.kotlin.idea.refactoring.comparePossiblyOverridingDescriptors
|
||||||
import kotlin.properties.Delegates
|
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
|
||||||
import org.jetbrains.kotlin.idea.util.makeNotNullable
|
|
||||||
import org.jetbrains.kotlin.idea.util.CallType
|
import org.jetbrains.kotlin.idea.util.CallType
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
|
import org.jetbrains.kotlin.idea.util.makeNotNullable
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptorKindExclude
|
||||||
import com.intellij.patterns.StandardPatterns
|
import org.jetbrains.kotlin.psi.*
|
||||||
import com.intellij.util.ProcessingContext
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import com.intellij.patterns.PatternCondition
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
class CompletionSessionConfiguration(
|
class CompletionSessionConfiguration(
|
||||||
val completeNonImportedDeclarations: Boolean,
|
val completeNonImportedDeclarations: Boolean,
|
||||||
@@ -88,18 +90,21 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
|||||||
protected val bindingContext: BindingContext? = expression?.let { resolutionFacade.analyze(it, BodyResolveMode.PARTIAL_FOR_COMPLETION) }
|
protected val bindingContext: BindingContext? = expression?.let { resolutionFacade.analyze(it, BodyResolveMode.PARTIAL_FOR_COMPLETION) }
|
||||||
protected val inDescriptor: DeclarationDescriptor? = expression?.let { bindingContext!!.get(BindingContext.RESOLUTION_SCOPE, it)?.getContainingDeclaration() }
|
protected val inDescriptor: DeclarationDescriptor? = expression?.let { bindingContext!!.get(BindingContext.RESOLUTION_SCOPE, it)?.getContainingDeclaration() }
|
||||||
|
|
||||||
|
private fun singleCharPattern(char: Char): CharPattern {
|
||||||
|
return StandardPatterns.character().with(
|
||||||
|
object : PatternCondition<Char>(char.toString()) {
|
||||||
|
override fun accepts(c: Char, context: ProcessingContext) = c == char
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private val kotlinIdentifierStartPattern = StandardPatterns.and(StandardPatterns.character().javaIdentifierStart(), StandardPatterns.not(singleCharPattern('$')))
|
||||||
|
private val kotlinIdentifierPartPattern = StandardPatterns.and(StandardPatterns.character().javaIdentifierPart(), StandardPatterns.not(singleCharPattern('$')))
|
||||||
|
|
||||||
protected val prefix: String = CompletionUtil.findIdentifierPrefix(
|
protected val prefix: String = CompletionUtil.findIdentifierPrefix(
|
||||||
parameters.getPosition().getContainingFile(),
|
parameters.getPosition().getContainingFile(),
|
||||||
parameters.getOffset(),
|
parameters.getOffset(),
|
||||||
StandardPatterns.or(StandardPatterns.character().javaIdentifierPart(),
|
StandardPatterns.or(kotlinIdentifierPartPattern, singleCharPattern('@')),
|
||||||
StandardPatterns.character().with(
|
kotlinIdentifierStartPattern)
|
||||||
object : PatternCondition<Char>("@") {
|
|
||||||
override fun accepts(c: Char?, context: ProcessingContext?): Boolean {
|
|
||||||
return c == '@'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
),
|
|
||||||
StandardPatterns.character().javaIdentifierStart())
|
|
||||||
|
|
||||||
protected val resultSet: CompletionResultSet = resultSet
|
protected val resultSet: CompletionResultSet = resultSet
|
||||||
.withPrefixMatcher(prefix)
|
.withPrefixMatcher(prefix)
|
||||||
@@ -129,7 +134,8 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
|||||||
LookupElementFactory(receiverTypes)
|
LookupElementFactory(receiverTypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected val collector: LookupElementsCollector = LookupElementsCollector(prefixMatcher, parameters, resolutionFacade, lookupElementFactory)
|
protected val collector: LookupElementsCollector = LookupElementsCollector(
|
||||||
|
prefixMatcher, parameters, resolutionFacade, lookupElementFactory, expression?.getParent() is JetSimpleNameStringTemplateEntry)
|
||||||
|
|
||||||
protected val project: Project = position.getProject()
|
protected val project: Project = position.getProject()
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,20 @@ fun LookupElement.withReceiverCast(): LookupElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun LookupElement.withBracesSurrounding(): LookupElement {
|
||||||
|
return object: LookupElementDecorator<LookupElement>(this) {
|
||||||
|
override fun handleInsert(context: InsertionContext) {
|
||||||
|
context.getDocument().insertString(context.getStartOffset(), "{")
|
||||||
|
|
||||||
|
val tailOffset = context.getTailOffset()
|
||||||
|
context.getDocument().insertString(tailOffset, "}")
|
||||||
|
context.setTailOffset(tailOffset)
|
||||||
|
|
||||||
|
super.handleInsert(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY = Key<Unit>("KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY")
|
val KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY = Key<Unit>("KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY")
|
||||||
|
|
||||||
fun LookupElement.keepOldArgumentListOnTab(): LookupElement {
|
fun LookupElement.keepOldArgumentListOnTab(): LookupElement {
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ class LookupElementsCollector(
|
|||||||
private val prefixMatcher: PrefixMatcher,
|
private val prefixMatcher: PrefixMatcher,
|
||||||
private val completionParameters: CompletionParameters,
|
private val completionParameters: CompletionParameters,
|
||||||
private val resolutionFacade: ResolutionFacade,
|
private val resolutionFacade: ResolutionFacade,
|
||||||
private val lookupElementFactory: LookupElementFactory
|
private val lookupElementFactory: LookupElementFactory,
|
||||||
|
private val surroundCallsWithBraces: Boolean
|
||||||
) {
|
) {
|
||||||
private val elements = ArrayList<LookupElement>()
|
private val elements = ArrayList<LookupElement>()
|
||||||
|
|
||||||
@@ -62,9 +63,15 @@ class LookupElementsCollector(
|
|||||||
public fun addDescriptorElements(descriptor: DeclarationDescriptor, suppressAutoInsertion: Boolean, withReceiverCast: Boolean) {
|
public fun addDescriptorElements(descriptor: DeclarationDescriptor, suppressAutoInsertion: Boolean, withReceiverCast: Boolean) {
|
||||||
run {
|
run {
|
||||||
var lookupElement = lookupElementFactory.createLookupElement(resolutionFacade, descriptor, true)
|
var lookupElement = lookupElementFactory.createLookupElement(resolutionFacade, descriptor, true)
|
||||||
|
|
||||||
if (withReceiverCast) {
|
if (withReceiverCast) {
|
||||||
lookupElement = lookupElement.withReceiverCast()
|
lookupElement = lookupElement.withReceiverCast()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (surroundCallsWithBraces && descriptor is FunctionDescriptor) {
|
||||||
|
lookupElement = lookupElement.withBracesSurrounding()
|
||||||
|
}
|
||||||
|
|
||||||
if (suppressAutoInsertion) {
|
if (suppressAutoInsertion) {
|
||||||
addElementWithAutoInsertionSuppressed(lookupElement)
|
addElementWithAutoInsertionSuppressed(lookupElement)
|
||||||
}
|
}
|
||||||
@@ -81,8 +88,9 @@ class LookupElementsCollector(
|
|||||||
if (KotlinBuiltIns.isFunctionOrExtensionFunctionType(parameterType)) {
|
if (KotlinBuiltIns.isFunctionOrExtensionFunctionType(parameterType)) {
|
||||||
val parameterCount = KotlinBuiltIns.getParameterTypeProjectionsFromFunctionType(parameterType).size()
|
val parameterCount = KotlinBuiltIns.getParameterTypeProjectionsFromFunctionType(parameterType).size()
|
||||||
if (parameterCount > 1) {
|
if (parameterCount > 1) {
|
||||||
val lookupElement = lookupElementFactory.createLookupElement(resolutionFacade, descriptor, true)
|
var lookupElement = lookupElementFactory.createLookupElement(resolutionFacade, descriptor, true)
|
||||||
addElement(object : LookupElementDecorator<LookupElement>(lookupElement) {
|
|
||||||
|
lookupElement = object : LookupElementDecorator<LookupElement>(lookupElement) {
|
||||||
override fun renderElement(presentation: LookupElementPresentation) {
|
override fun renderElement(presentation: LookupElementPresentation) {
|
||||||
super.renderElement(presentation)
|
super.renderElement(presentation)
|
||||||
|
|
||||||
@@ -95,7 +103,13 @@ class LookupElementsCollector(
|
|||||||
override fun handleInsert(context: InsertionContext) {
|
override fun handleInsert(context: InsertionContext) {
|
||||||
KotlinFunctionInsertHandler(CaretPosition.IN_BRACKETS, GenerateLambdaInfo(parameterType, true)).handleInsert(context, this)
|
KotlinFunctionInsertHandler(CaretPosition.IN_BRACKETS, GenerateLambdaInfo(parameterType, true)).handleInsert(context, this)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
if (surroundCallsWithBraces) {
|
||||||
|
lookupElement = lookupElement.withBracesSurrounding()
|
||||||
|
}
|
||||||
|
|
||||||
|
addElement(lookupElement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(param: String) {
|
||||||
|
val s = "$<caret>"
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: foo
|
||||||
|
// EXIST: param
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(param: String) {
|
||||||
|
val s = "${<caret>}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: foo
|
||||||
|
// EXIST: param
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo(): String {
|
||||||
|
val s = "$<caret>"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: foo
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo(): String {
|
||||||
|
val s = "${foo()<caret>}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: foo
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo(p: String): String {
|
||||||
|
val s = "$<caret>"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: foo
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo(p: String): String {
|
||||||
|
val s = "${foo(<caret>)}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: foo
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo(): String {
|
||||||
|
val s = "${<caret>}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: foo
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo(): String {
|
||||||
|
val s = "${foo()<caret>}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: foo
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo(param: Any): String {
|
||||||
|
val s = "${<caret>}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: param
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo(param: Any): String {
|
||||||
|
val s = "${param<caret>}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: param
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun bar() {}
|
||||||
|
|
||||||
|
fun test(){
|
||||||
|
"$b<caret>"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: bar
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun bar() {}
|
||||||
|
|
||||||
|
fun test(){
|
||||||
|
"${bar()<caret>}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: bar
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(): String {
|
||||||
|
val s = "$<caret>xxx"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: foo
|
||||||
|
// CHAR: \t
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun foo(): String {
|
||||||
|
val s = "${foo()<caret>}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: foo
|
||||||
|
// CHAR: \t
|
||||||
@@ -883,6 +883,18 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("StringTemplate1.kt")
|
||||||
|
public void testStringTemplate1() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/StringTemplate1.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("StringTemplate2.kt")
|
||||||
|
public void testStringTemplate2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/StringTemplate2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("SubpackageInFun.kt")
|
@TestMetadata("SubpackageInFun.kt")
|
||||||
public void testSubpackageInFun() throws Exception {
|
public void testSubpackageInFun() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/SubpackageInFun.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/SubpackageInFun.kt");
|
||||||
|
|||||||
@@ -883,6 +883,18 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("StringTemplate1.kt")
|
||||||
|
public void testStringTemplate1() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/StringTemplate1.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("StringTemplate2.kt")
|
||||||
|
public void testStringTemplate2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/StringTemplate2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("SubpackageInFun.kt")
|
@TestMetadata("SubpackageInFun.kt")
|
||||||
public void testSubpackageInFun() throws Exception {
|
public void testSubpackageInFun() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/SubpackageInFun.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/SubpackageInFun.kt");
|
||||||
|
|||||||
+9
-20
@@ -17,11 +17,12 @@
|
|||||||
package org.jetbrains.kotlin.completion.handlers
|
package org.jetbrains.kotlin.completion.handlers
|
||||||
|
|
||||||
import com.intellij.codeInsight.completion.CompletionType
|
import com.intellij.codeInsight.completion.CompletionType
|
||||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import org.jetbrains.kotlin.idea.JetLightProjectDescriptor
|
||||||
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
public abstract class AbstractCompletionHandlerTest : CompletionHandlerTestBase() {
|
public abstract class AbstractCompletionHandlerTest(private val defaultCompletionType: CompletionType) : CompletionHandlerTestBase() {
|
||||||
private val INVOCATION_COUNT_PREFIX = "INVOCATION_COUNT:"
|
private val INVOCATION_COUNT_PREFIX = "INVOCATION_COUNT:"
|
||||||
private val LOOKUP_STRING_PREFIX = "ELEMENT:"
|
private val LOOKUP_STRING_PREFIX = "ELEMENT:"
|
||||||
private val ELEMENT_TEXT_PREFIX = "ELEMENT_TEXT:"
|
private val ELEMENT_TEXT_PREFIX = "ELEMENT_TEXT:"
|
||||||
@@ -53,32 +54,20 @@ public abstract class AbstractCompletionHandlerTest : CompletionHandlerTestBase(
|
|||||||
else -> error("Unknown completion type: $completionTypeString")
|
else -> error("Unknown completion type: $completionTypeString")
|
||||||
}
|
}
|
||||||
|
|
||||||
doTestWithTextLoaded(completionType, invocationCount, lookupString, itemText, tailText, completionChar)
|
doTestWithTextLoaded(completionType, invocationCount, lookupString, itemText, tailText, completionChar, testPath + ".after")
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun setUpFixture(testPath: String) {
|
protected open fun setUpFixture(testPath: String) {
|
||||||
fixture.configureByFile(testPath)
|
fixture.configureByFile(testPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract val defaultCompletionType: CompletionType
|
override fun getProjectDescriptor() = JetLightProjectDescriptor.INSTANCE
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class AbstractBasicCompletionHandlerTest() : AbstractCompletionHandlerTest() {
|
public abstract class AbstractBasicCompletionHandlerTest() : AbstractCompletionHandlerTest(CompletionType.BASIC)
|
||||||
override val defaultCompletionType: CompletionType = CompletionType.BASIC
|
|
||||||
override val testDataRelativePath: String = "/completion/handlers/basic"
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class AbstractSmartCompletionHandlerTest() : AbstractCompletionHandlerTest() {
|
public abstract class AbstractSmartCompletionHandlerTest() : AbstractCompletionHandlerTest(CompletionType.SMART)
|
||||||
override val defaultCompletionType: CompletionType = CompletionType.SMART
|
|
||||||
override val testDataRelativePath: String = "/completion/handlers/smart"
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class AbstractCompletionCharFilterTest() : AbstractCompletionHandlerTest() {
|
public abstract class AbstractCompletionCharFilterTest() : AbstractCompletionHandlerTest(CompletionType.BASIC)
|
||||||
override val defaultCompletionType: CompletionType = CompletionType.BASIC
|
|
||||||
override val testDataRelativePath: String = "/completion/handlers/charFilter"
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class AbstractKeywordCompletionHandlerTest() : AbstractCompletionHandlerTest() {
|
public abstract class AbstractKeywordCompletionHandlerTest() : AbstractCompletionHandlerTest(CompletionType.BASIC)
|
||||||
override val defaultCompletionType: CompletionType = CompletionType.BASIC
|
|
||||||
override val testDataRelativePath: String = "/completion/handlers/keywords"
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -17,12 +17,18 @@
|
|||||||
package org.jetbrains.kotlin.completion.handlers
|
package org.jetbrains.kotlin.completion.handlers
|
||||||
|
|
||||||
import com.intellij.codeInsight.completion.CompletionType
|
import com.intellij.codeInsight.completion.CompletionType
|
||||||
import org.jetbrains.kotlin.idea.formatter.JetCodeStyleSettings
|
|
||||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
||||||
|
import org.jetbrains.kotlin.idea.PluginTestCaseBase
|
||||||
|
import org.jetbrains.kotlin.idea.formatter.JetCodeStyleSettings
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
deprecated("All tests from here to be moved to the generated test")
|
deprecated("All tests from here to be moved to the generated test")
|
||||||
public class BasicCompletionHandlerTest : CompletionHandlerTestBase(){
|
public class BasicCompletionHandlerTest : CompletionHandlerTestBase(){
|
||||||
override val testDataRelativePath: String = "/completion/handlers"
|
private fun checkResult(){
|
||||||
|
fixture.checkResultByFile(getTestName(false) + ".kt.after")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTestDataPath() = File(PluginTestCaseBase.getTestDataPathBase(), "/completion/handlers").getPath() + File.separator
|
||||||
|
|
||||||
private fun doTest() {
|
private fun doTest() {
|
||||||
doTest(2, "*", null, null, '\n')
|
doTest(2, "*", null, null, '\n')
|
||||||
@@ -34,7 +40,7 @@ public class BasicCompletionHandlerTest : CompletionHandlerTestBase(){
|
|||||||
|
|
||||||
private fun doTest(time: Int, lookupString: String?, itemText: String?, tailText: String?, completionChar: Char) {
|
private fun doTest(time: Int, lookupString: String?, itemText: String?, tailText: String?, completionChar: Char) {
|
||||||
fixture.configureByFile(fileName())
|
fixture.configureByFile(fileName())
|
||||||
doTestWithTextLoaded(CompletionType.BASIC, time, lookupString, itemText, tailText, completionChar)
|
doTestWithTextLoaded(CompletionType.BASIC, time, lookupString, itemText, tailText, completionChar, fileName() + ".after")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testClassCompletionImport() = doTest(2, "SortedSet", null, '\n')
|
fun testClassCompletionImport() = doTest(2, "SortedSet", null, '\n')
|
||||||
|
|||||||
+48
@@ -30,6 +30,9 @@ import java.util.regex.Pattern;
|
|||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@TestMetadata("idea/testData/completion/handlers/basic")
|
@TestMetadata("idea/testData/completion/handlers/basic")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@InnerTestClasses({
|
||||||
|
BasicCompletionHandlerTestGenerated.StringTemplate.class,
|
||||||
|
})
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletionHandlerTest {
|
public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletionHandlerTest {
|
||||||
public void testAllFilesPresentInBasic() throws Exception {
|
public void testAllFilesPresentInBasic() throws Exception {
|
||||||
@@ -77,4 +80,49 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion
|
|||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/basic/SuperTypeArg.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/basic/SuperTypeArg.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/completion/handlers/basic/stringTemplate")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class StringTemplate extends AbstractBasicCompletionHandlerTest {
|
||||||
|
@TestMetadata("1.kt")
|
||||||
|
public void test1() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/basic/stringTemplate/1.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("2.kt")
|
||||||
|
public void test2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/basic/stringTemplate/2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("3.kt")
|
||||||
|
public void test3() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/basic/stringTemplate/3.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("4.kt")
|
||||||
|
public void test4() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/basic/stringTemplate/4.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInStringTemplate() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/completion/handlers/basic/stringTemplate"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("NotEmptyPrefix.kt")
|
||||||
|
public void testNotEmptyPrefix() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/basic/stringTemplate/NotEmptyPrefix.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("Replace.kt")
|
||||||
|
public void testReplace() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/basic/stringTemplate/Replace.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,23 +16,20 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.completion.handlers
|
package org.jetbrains.kotlin.completion.handlers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase
|
|
||||||
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 java.io.File
|
|
||||||
import org.jetbrains.kotlin.idea.PluginTestCaseBase
|
|
||||||
import com.intellij.codeInsight.lookup.impl.LookupImpl
|
|
||||||
import com.intellij.codeInsight.lookup.LookupEvent
|
|
||||||
import com.intellij.openapi.command.WriteCommandAction
|
|
||||||
import com.intellij.codeInsight.lookup.LookupManager
|
|
||||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
||||||
import org.junit.Assert
|
import com.intellij.codeInsight.lookup.LookupEvent
|
||||||
|
import com.intellij.codeInsight.lookup.LookupManager
|
||||||
|
import com.intellij.codeInsight.lookup.impl.LookupImpl
|
||||||
import com.intellij.openapi.application.Result
|
import com.intellij.openapi.application.Result
|
||||||
|
import com.intellij.openapi.command.WriteCommandAction
|
||||||
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
|
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
|
||||||
|
import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase
|
||||||
|
import org.jetbrains.kotlin.test.JetTestUtils
|
||||||
|
import org.junit.Assert
|
||||||
|
|
||||||
public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTestCase() {
|
public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTestCase() {
|
||||||
protected abstract val testDataRelativePath: String
|
|
||||||
|
|
||||||
protected val fixture: JavaCodeInsightTestFixture
|
protected val fixture: JavaCodeInsightTestFixture
|
||||||
get() = myFixture
|
get() = myFixture
|
||||||
|
|
||||||
@@ -42,7 +39,8 @@ public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTe
|
|||||||
lookupString: String?,
|
lookupString: String?,
|
||||||
itemText: String?,
|
itemText: String?,
|
||||||
tailText: String?,
|
tailText: String?,
|
||||||
completionChar: Char
|
completionChar: Char,
|
||||||
|
afterFilePath: String
|
||||||
) {
|
) {
|
||||||
fixture.complete(completionType, time)
|
fixture.complete(completionType, time)
|
||||||
|
|
||||||
@@ -53,11 +51,7 @@ public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkResult()
|
fixture.checkResultByFile(afterFilePath)
|
||||||
}
|
|
||||||
|
|
||||||
protected fun checkResult(){
|
|
||||||
fixture.checkResultByFile(afterFileName())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getExistentLookupElement(lookupString: String?, itemText: String?, tailText: String?): LookupElement? {
|
private fun getExistentLookupElement(lookupString: String?, itemText: String?, tailText: String?): LookupElement? {
|
||||||
@@ -111,13 +105,7 @@ public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTe
|
|||||||
return foundElement
|
return foundElement
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun afterFileName(): String = getTestName(false) + ".kt.after"
|
override fun getTestDataPath() = JetTestUtils.getHomeDirectory()
|
||||||
|
|
||||||
protected override fun getTestDataPath() : String = File(PluginTestCaseBase.getTestDataPathBase(), testDataRelativePath).getPath() + File.separator
|
|
||||||
|
|
||||||
protected fun selectItem(item: LookupElement?) {
|
|
||||||
selectItem(item, 0.toChar())
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun selectItem(item: LookupElement?, completionChar: Char) {
|
protected fun selectItem(item: LookupElement?, completionChar: Char) {
|
||||||
val lookup = (fixture.getLookup() as LookupImpl)
|
val lookup = (fixture.getLookup() as LookupImpl)
|
||||||
|
|||||||
+1
-4
@@ -78,13 +78,10 @@ public abstract class AbstractCodeFragmentCompletionTest : AbstractJvmBasicCompl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class AbstractCodeFragmentCompletionHandlerTest : AbstractCompletionHandlerTest() {
|
public abstract class AbstractCodeFragmentCompletionHandlerTest : AbstractCompletionHandlerTest(CompletionType.BASIC) {
|
||||||
override fun setUpFixture(testPath: String) {
|
override fun setUpFixture(testPath: String) {
|
||||||
myFixture.configureByCodeFragment(testPath)
|
myFixture.configureByCodeFragment(testPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val testDataRelativePath: String = "/completion/handlers/runtimeCast/"
|
|
||||||
override val defaultCompletionType: CompletionType = CompletionType.BASIC
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JavaCodeInsightTestFixture.configureByCodeFragment(filePath: String) {
|
private fun JavaCodeInsightTestFixture.configureByCodeFragment(filePath: String) {
|
||||||
|
|||||||
Reference in New Issue
Block a user