Competion in debugger for runtime receiver type should not show members grayed
This commit is contained in:
+11
-9
@@ -94,7 +94,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
private val smartCompletion = expression?.let {
|
||||
SmartCompletion(
|
||||
it, resolutionFacade, bindingContext, moduleDescriptor, isVisibleFilter, prefixMatcher,
|
||||
GlobalSearchScope.EMPTY_SCOPE, toFromOriginalFileMapper, lookupElementFactory, callTypeAndReceiver,
|
||||
GlobalSearchScope.EMPTY_SCOPE, toFromOriginalFileMapper, callTypeAndReceiver,
|
||||
isJvmModule, forBasicCompletion = true
|
||||
)
|
||||
}
|
||||
@@ -197,7 +197,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
|
||||
if (completionKind != CompletionKind.NAMED_ARGUMENTS_ONLY) {
|
||||
if (smartCompletion != null) {
|
||||
val (additionalItems, @Suppress("UNUSED_VARIABLE") inheritanceSearcher) = smartCompletion.additionalItems()
|
||||
val (additionalItems, @Suppress("UNUSED_VARIABLE") inheritanceSearcher) = smartCompletion.additionalItems(lookupElementFactory)
|
||||
|
||||
// all additional items should have SMART_COMPLETION_ITEM_PRIORITY_KEY to be recognized by SmartCompletionInBasicWeigher
|
||||
for (item in additionalItems) {
|
||||
@@ -211,8 +211,8 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
|
||||
referenceVariants?.let {
|
||||
val (imported, notImported) = it
|
||||
collector.addDescriptorElements(imported)
|
||||
collector.addDescriptorElements(notImported, notImported = true)
|
||||
collector.addDescriptorElements(imported, lookupElementFactory)
|
||||
collector.addDescriptorElements(notImported, lookupElementFactory, notImported = true)
|
||||
}
|
||||
|
||||
completeKeywords()
|
||||
@@ -243,10 +243,12 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
flushToResultSet()
|
||||
|
||||
if (position.getContainingFile() is KtCodeFragment) {
|
||||
val variants = getRuntimeReceiverTypeReferenceVariants()
|
||||
if (variants != null) {
|
||||
collector.addDescriptorElements(variants.imported, withReceiverCast = true)
|
||||
collector.addDescriptorElements(variants.notImportedExtensions, withReceiverCast = true, notImported = true)
|
||||
val variantsAndFactory = getRuntimeReceiverTypeReferenceVariants()
|
||||
if (variantsAndFactory != null) {
|
||||
val variants = variantsAndFactory.first
|
||||
val lookupElementFactory = variantsAndFactory.second
|
||||
collector.addDescriptorElements(variants.imported, lookupElementFactory, withReceiverCast = true)
|
||||
collector.addDescriptorElements(variants.notImportedExtensions, lookupElementFactory, withReceiverCast = true, notImported = true)
|
||||
flushToResultSet()
|
||||
}
|
||||
}
|
||||
@@ -380,7 +382,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
|
||||
private fun completeNonImported() {
|
||||
if (shouldCompleteTopLevelCallablesFromIndex()) {
|
||||
collector.addDescriptorElements(getTopLevelCallables(), notImported = true)
|
||||
collector.addDescriptorElements(getTopLevelCallables(), lookupElementFactory, notImported = true)
|
||||
}
|
||||
|
||||
val classKindFilter: ((ClassKind) -> Boolean)?
|
||||
|
||||
@@ -143,7 +143,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
|
||||
|
||||
// LookupElementsCollector instantiation is deferred because virtual call to createSorter uses data from derived classes
|
||||
protected val collector: LookupElementsCollector by lazy(LazyThreadSafetyMode.NONE) {
|
||||
LookupElementsCollector(prefixMatcher, parameters, resultSet, lookupElementFactory, createSorter())
|
||||
LookupElementsCollector(prefixMatcher, parameters, resultSet, createSorter())
|
||||
}
|
||||
|
||||
protected val originalSearchScope: GlobalSearchScope = getResolveScope(parameters.getOriginalFile() as KtFile)
|
||||
@@ -329,7 +329,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
|
||||
return this
|
||||
}
|
||||
|
||||
protected fun getRuntimeReceiverTypeReferenceVariants(): ReferenceVariants? {
|
||||
protected fun getRuntimeReceiverTypeReferenceVariants(): Pair<ReferenceVariants, LookupElementFactory>? {
|
||||
val explicitReceiver = callTypeAndReceiver.receiver as? KtExpression ?: return null
|
||||
val type = bindingContext.getType(explicitReceiver) ?: return null
|
||||
if (!TypeUtils.canHaveSubtypes(KotlinTypeChecker.DEFAULT, type)) return null
|
||||
@@ -340,7 +340,9 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
|
||||
val (variants, notImportedExtensions) = collectReferenceVariants(descriptorKindFilter!!, ExpressionReceiver(explicitReceiver, runtimeType))
|
||||
val filteredVariants = filterVariantsForRuntimeReceiverType(variants, referenceVariants!!.imported)
|
||||
val filteredNotImportedExtensions = filterVariantsForRuntimeReceiverType(notImportedExtensions, referenceVariants!!.notImportedExtensions)
|
||||
return ReferenceVariants(filteredVariants, filteredNotImportedExtensions)
|
||||
|
||||
val referenceVariants = ReferenceVariants(filteredVariants, filteredNotImportedExtensions)
|
||||
return Pair(referenceVariants, lookupElementFactory.copy(receiverTypes = listOf(runtimeType)))
|
||||
}
|
||||
|
||||
private fun <TDescriptor : DeclarationDescriptor> filterVariantsForRuntimeReceiverType(
|
||||
@@ -383,7 +385,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
|
||||
protected fun addClassesFromIndex(kindFilter: (ClassKind) -> Boolean) {
|
||||
AllClassesCompletion(parameters, indicesHelper, prefixMatcher, resolutionFacade, kindFilter)
|
||||
.collect(
|
||||
{ descriptor -> collector.addDescriptorElements(descriptor, notImported = true) },
|
||||
{ descriptor -> collector.addDescriptorElements(descriptor, lookupElementFactory, notImported = true) },
|
||||
{ javaClass -> collector.addElement(lookupElementFactory.createLookupElementForJavaClass(javaClass), notImported = true) }
|
||||
)
|
||||
}
|
||||
|
||||
+2
-1
@@ -42,13 +42,14 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
|
||||
data /* we need copy() */
|
||||
class LookupElementFactory(
|
||||
private val resolutionFacade: ResolutionFacade,
|
||||
private val receiverTypes: Collection<KotlinType>?,
|
||||
private val callType: CallType<*>?,
|
||||
private val isInStringTemplateAfterDollar: Boolean,
|
||||
public val insertHandlerProvider: InsertHandlerProvider,
|
||||
contextVariablesProvider: () -> Collection<VariableDescriptor>
|
||||
private val contextVariablesProvider: () -> Collection<VariableDescriptor>
|
||||
) {
|
||||
private val basicFactory = BasicLookupElementFactory(resolutionFacade.project, insertHandlerProvider)
|
||||
|
||||
|
||||
+13
-10
@@ -31,7 +31,6 @@ class LookupElementsCollector(
|
||||
private val prefixMatcher: PrefixMatcher,
|
||||
private val completionParameters: CompletionParameters,
|
||||
resultSet: CompletionResultSet,
|
||||
private val lookupElementFactory: LookupElementFactory,
|
||||
private val sorter: CompletionSorter
|
||||
) {
|
||||
|
||||
@@ -59,24 +58,28 @@ class LookupElementsCollector(
|
||||
}
|
||||
|
||||
public fun addDescriptorElements(descriptors: Iterable<DeclarationDescriptor>,
|
||||
lookupElementFactory: LookupElementFactory,
|
||||
notImported: Boolean = false,
|
||||
withReceiverCast: Boolean = false
|
||||
) {
|
||||
for (descriptor in descriptors) {
|
||||
addDescriptorElements(descriptor, notImported, withReceiverCast)
|
||||
addDescriptorElements(descriptor, lookupElementFactory, notImported, withReceiverCast)
|
||||
}
|
||||
}
|
||||
|
||||
public fun addDescriptorElements(descriptor: DeclarationDescriptor, notImported: Boolean = false, withReceiverCast: Boolean = false) {
|
||||
run {
|
||||
var lookupElements = lookupElementFactory.createStandardLookupElementsForDescriptor(descriptor, useReceiverTypes = true)
|
||||
public fun addDescriptorElements(
|
||||
descriptor: DeclarationDescriptor,
|
||||
lookupElementFactory: LookupElementFactory,
|
||||
notImported: Boolean = false,
|
||||
withReceiverCast: Boolean = false
|
||||
) {
|
||||
var lookupElements = lookupElementFactory.createStandardLookupElementsForDescriptor(descriptor, useReceiverTypes = true)
|
||||
|
||||
if (withReceiverCast) {
|
||||
lookupElements = lookupElements.map { it.withReceiverCast() }
|
||||
}
|
||||
|
||||
addElements(lookupElements, notImported)
|
||||
if (withReceiverCast) {
|
||||
lookupElements = lookupElements.map { it.withReceiverCast() }
|
||||
}
|
||||
|
||||
addElements(lookupElements, notImported)
|
||||
}
|
||||
|
||||
public fun addElement(element: LookupElement, notImported: Boolean = false) {
|
||||
|
||||
+12
-11
@@ -56,7 +56,6 @@ class SmartCompletion(
|
||||
private val prefixMatcher: PrefixMatcher,
|
||||
private val inheritorSearchScope: GlobalSearchScope,
|
||||
private val toFromOriginalFileMapper: ToFromOriginalFileMapper,
|
||||
private val lookupElementFactory: LookupElementFactory,
|
||||
private val callTypeAndReceiver: CallTypeAndReceiver<*, *>,
|
||||
private val isJvmModule: Boolean,
|
||||
private val forBasicCompletion: Boolean = false
|
||||
@@ -83,11 +82,13 @@ class SmartCompletion(
|
||||
SmartCastCalculator(bindingContext, resolutionFacade.moduleDescriptor, expression, resolutionFacade)
|
||||
}
|
||||
|
||||
public val descriptorFilter: ((DeclarationDescriptor) -> Collection<LookupElement>)?
|
||||
= { descriptor: DeclarationDescriptor -> filterDescriptor(descriptor).map { postProcess(it) } }.check { expectedInfos.isNotEmpty() }
|
||||
public val descriptorFilter: ((DeclarationDescriptor, LookupElementFactory) -> Collection<LookupElement>)? =
|
||||
{ descriptor: DeclarationDescriptor, lookupElementFactory: LookupElementFactory ->
|
||||
filterDescriptor(descriptor, lookupElementFactory).map { postProcess(it) }
|
||||
}.check { expectedInfos.isNotEmpty() }
|
||||
|
||||
public fun additionalItems(): Pair<Collection<LookupElement>, InheritanceItemsSearcher?> {
|
||||
val (items, inheritanceSearcher) = additionalItemsNoPostProcess()
|
||||
public fun additionalItems(lookupElementFactory: LookupElementFactory): Pair<Collection<LookupElement>, InheritanceItemsSearcher?> {
|
||||
val (items, inheritanceSearcher) = additionalItemsNoPostProcess(lookupElementFactory)
|
||||
val postProcessedItems = items.map { postProcess(it) }
|
||||
//TODO: could not use "let" because of KT-8754
|
||||
val postProcessedSearcher = if (inheritanceSearcher != null)
|
||||
@@ -152,7 +153,7 @@ class SmartCompletion(
|
||||
return@lazy emptySet()
|
||||
}
|
||||
|
||||
private fun filterDescriptor(descriptor: DeclarationDescriptor): Collection<LookupElement> {
|
||||
private fun filterDescriptor(descriptor: DeclarationDescriptor, lookupElementFactory: LookupElementFactory): Collection<LookupElement> {
|
||||
val callType = callTypeAndReceiver.callType
|
||||
if (descriptor in descriptorsToSkip) return emptyList()
|
||||
|
||||
@@ -165,14 +166,14 @@ class SmartCompletion(
|
||||
}
|
||||
|
||||
if (callTypeAndReceiver is CallTypeAndReceiver.DEFAULT) {
|
||||
result.addCallableReferenceLookupElements(descriptor)
|
||||
result.addCallableReferenceLookupElements(descriptor, lookupElementFactory)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun additionalItemsNoPostProcess(): Pair<Collection<LookupElement>, InheritanceItemsSearcher?> {
|
||||
val asTypePositionItems = buildForAsTypePosition()
|
||||
private fun additionalItemsNoPostProcess(lookupElementFactory: LookupElementFactory): Pair<Collection<LookupElement>, InheritanceItemsSearcher?> {
|
||||
val asTypePositionItems = buildForAsTypePosition(lookupElementFactory)
|
||||
if (asTypePositionItems != null) {
|
||||
assert(expectedInfos.isEmpty())
|
||||
return Pair(asTypePositionItems, null)
|
||||
@@ -320,7 +321,7 @@ class SmartCompletion(
|
||||
return null
|
||||
}
|
||||
|
||||
private fun MutableCollection<LookupElement>.addCallableReferenceLookupElements(descriptor: DeclarationDescriptor) {
|
||||
private fun MutableCollection<LookupElement>.addCallableReferenceLookupElements(descriptor: DeclarationDescriptor, lookupElementFactory: LookupElementFactory) {
|
||||
if (callableTypeExpectedInfo.isEmpty()) return
|
||||
|
||||
fun toLookupElement(descriptor: CallableDescriptor): LookupElement? {
|
||||
@@ -367,7 +368,7 @@ class SmartCompletion(
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildForAsTypePosition(): Collection<LookupElement>? {
|
||||
private fun buildForAsTypePosition(lookupElementFactory: LookupElementFactory): Collection<LookupElement>? {
|
||||
val binaryExpression = ((expression.getParent() as? KtUserType)
|
||||
?.getParent() as? KtTypeReference)
|
||||
?.getParent() as? KtBinaryExpressionWithTypeRHS
|
||||
|
||||
+11
-9
@@ -50,7 +50,7 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
||||
private val smartCompletion by lazy(LazyThreadSafetyMode.NONE) {
|
||||
expression?.let {
|
||||
SmartCompletion(it, resolutionFacade, bindingContext, moduleDescriptor, isVisibleFilter,
|
||||
prefixMatcher, originalSearchScope, toFromOriginalFileMapper, lookupElementFactory,
|
||||
prefixMatcher, originalSearchScope, toFromOriginalFileMapper,
|
||||
callTypeAndReceiver, isJvmModule)
|
||||
}
|
||||
}
|
||||
@@ -67,28 +67,30 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
||||
if (expression != null) {
|
||||
addFunctionLiteralArgumentCompletions()
|
||||
|
||||
val (additionalItems, inheritanceSearcher) = smartCompletion!!.additionalItems()
|
||||
val (additionalItems, inheritanceSearcher) = smartCompletion!!.additionalItems(lookupElementFactory)
|
||||
collector.addElements(additionalItems)
|
||||
|
||||
if (nameExpression != null) {
|
||||
val filter = smartCompletion!!.descriptorFilter
|
||||
if (filter != null) {
|
||||
val (imported, notImported) = referenceVariants!!
|
||||
imported.forEach { collector.addElements(filter(it)) }
|
||||
notImported.forEach { collector.addElements(filter(it), notImported = true) }
|
||||
imported.forEach { collector.addElements(filter(it, lookupElementFactory)) }
|
||||
notImported.forEach { collector.addElements(filter(it, lookupElementFactory), notImported = true) }
|
||||
|
||||
flushToResultSet()
|
||||
|
||||
if (shouldCompleteTopLevelCallablesFromIndex()) {
|
||||
getTopLevelCallables().forEach { collector.addElements(filter(it), notImported = true) }
|
||||
getTopLevelCallables().forEach { collector.addElements(filter(it, lookupElementFactory), notImported = true) }
|
||||
flushToResultSet()
|
||||
}
|
||||
|
||||
if (position.getContainingFile() is KtCodeFragment) {
|
||||
val variants = getRuntimeReceiverTypeReferenceVariants()
|
||||
if (variants != null) {
|
||||
variants.imported.forEach { collector.addElements(filter(it).map { it.withReceiverCast() }) }
|
||||
variants.notImportedExtensions.forEach { collector.addElements(filter(it).map { it.withReceiverCast() }, notImported = true) }
|
||||
val variantsAndFactory = getRuntimeReceiverTypeReferenceVariants()
|
||||
if (variantsAndFactory != null) {
|
||||
val variants = variantsAndFactory.first
|
||||
val lookupElementFactory = variantsAndFactory.second
|
||||
variants.imported.forEach { collector.addElements(filter(it, lookupElementFactory).map { it.withReceiverCast() }) }
|
||||
variants.notImportedExtensions.forEach { collector.addElements(filter(it, lookupElementFactory).map { it.withReceiverCast() }, notImported = true) }
|
||||
flushToResultSet()
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@ fun foo(o: Any) {
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 1
|
||||
// EXIST: read, write
|
||||
// EXIST: { itemText: "read", attributes: "bold" }
|
||||
// EXIST: { itemText: "write", attributes: "bold" }
|
||||
|
||||
// RUNTIME_TYPE: java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
+11
-6
@@ -12,7 +12,11 @@ open class Base {
|
||||
fun funInBoth() { }
|
||||
}
|
||||
|
||||
class Derived: Base() {
|
||||
open class Intermediate : Base() {
|
||||
fun funInIntermediate(){}
|
||||
}
|
||||
|
||||
class Derived : Intermediate() {
|
||||
fun funInDerived() { }
|
||||
|
||||
override fun funWithOverride() { }
|
||||
@@ -21,12 +25,13 @@ class Derived: Base() {
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 1
|
||||
// EXIST: funInBase
|
||||
// EXIST: funWithOverride
|
||||
// EXIST: funWithoutOverride
|
||||
// EXIST: funInDerived
|
||||
// EXIST: { itemText: "funInBase", tailText: "()", attributes: "bold" }
|
||||
// EXIST: { itemText: "funWithOverride", tailText: "()", attributes: "bold" }
|
||||
// EXIST: { itemText: "funWithoutOverride", tailText: "()", attributes: "bold" }
|
||||
// EXIST: { itemText: "funInDerived", tailText: "()", attributes: "bold" }
|
||||
// EXIST: { itemText: "funInBoth", tailText: "()", attributes: "bold" }
|
||||
// EXIST: { itemText: "funInBoth", tailText: "(p: Int)", attributes: "grayed" }
|
||||
// EXIST: { itemText: "funInBoth", tailText: "(p: Int)", attributes: "bold" }
|
||||
// EXIST: { itemText: "funInIntermediate", tailText: "()", attributes: "" }
|
||||
// NOTHING_ELSE
|
||||
|
||||
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
fun main(args: Array<String>) {
|
||||
val b: Base = Derived()
|
||||
<caret>val a = 1
|
||||
}
|
||||
|
||||
open class Base {
|
||||
fun funInBase(): Int = 0
|
||||
|
||||
open fun funWithOverride(): Int = 0
|
||||
open fun funWithoutOverride(): Int = 0
|
||||
|
||||
fun funInBoth(): Int = 0
|
||||
}
|
||||
|
||||
open class Intermediate : Base() {
|
||||
fun funInIntermediate() = 0
|
||||
}
|
||||
|
||||
class Derived : Intermediate() {
|
||||
fun funInDerived(): Int = 0
|
||||
|
||||
override fun funWithOverride(): Int = 0
|
||||
|
||||
fun funInBoth(p: Int): Int = 0
|
||||
|
||||
fun funWrongType(): String = ""
|
||||
}
|
||||
|
||||
// COMPLETION_TYPE: SMART
|
||||
// INVOCATION_COUNT: 1
|
||||
// EXIST: { itemText: "funInBase", tailText: "()", attributes: "bold" }
|
||||
// EXIST: { itemText: "funWithOverride", tailText: "()", attributes: "bold" }
|
||||
// EXIST: { itemText: "funWithoutOverride", tailText: "()", attributes: "bold" }
|
||||
// EXIST: { itemText: "funInDerived", tailText: "()", attributes: "bold" }
|
||||
// EXIST: { itemText: "funInBoth", tailText: "()", attributes: "bold" }
|
||||
// EXIST: { itemText: "funInBoth", tailText: "(p: Int)", attributes: "bold" }
|
||||
// EXIST: { itemText: "funInIntermediate", tailText: "()", attributes: "" }
|
||||
// NOTHING_ELSE
|
||||
|
||||
|
||||
// RUNTIME_TYPE: Derived
|
||||
+1
@@ -0,0 +1 @@
|
||||
"".substring(b.fun<caret>)
|
||||
+1
-2
@@ -24,6 +24,5 @@ public abstract class AbstractCompiledKotlinInJavaCompletionTest : JetFixtureCom
|
||||
override fun getPlatform() = JvmPlatform
|
||||
|
||||
override fun getProjectDescriptor() = JdkAndMockLibraryProjectDescriptor(COMPLETION_TEST_DATA_BASE_PATH + "/injava/mockLib", false)
|
||||
|
||||
override fun complete(invocationCount: Int) = myFixture.complete(CompletionType.BASIC, invocationCount)
|
||||
override fun defaultCompletionType() = CompletionType.BASIC
|
||||
}
|
||||
|
||||
+4
-2
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.CompletionType;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.js.KotlinJavaScriptLibraryManager;
|
||||
import org.jetbrains.kotlin.idea.test.KotlinStdJSProjectDescriptor;
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform;
|
||||
@@ -44,8 +45,9 @@ public abstract class AbstractJSBasicCompletionTest extends JetFixtureCompletion
|
||||
KotlinJavaScriptLibraryManager.getInstance(getProject()).syncUpdateProjectLibrary();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected LookupElement[] complete(int invocationCount) {
|
||||
return myFixture.complete(CompletionType.BASIC, invocationCount);
|
||||
protected CompletionType defaultCompletionType() {
|
||||
return CompletionType.BASIC;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.idea.completion.test;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionType;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.test.JetWithJdkAndRuntimeLightProjectDescriptor;
|
||||
@@ -37,8 +36,9 @@ public abstract class AbstractJvmBasicCompletionTest extends JetFixtureCompletio
|
||||
return JvmPlatform.INSTANCE$;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected LookupElement[] complete(int invocationCount) {
|
||||
return myFixture.complete(CompletionType.BASIC, invocationCount);
|
||||
protected CompletionType defaultCompletionType() {
|
||||
return CompletionType.BASIC;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.idea.completion.test;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionType;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.test.JetWithJdkAndRuntimeLightProjectDescriptor;
|
||||
@@ -37,8 +36,9 @@ public abstract class AbstractJvmSmartCompletionTest extends JetFixtureCompletio
|
||||
return JvmPlatform.INSTANCE$;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected LookupElement[] complete(int invocationCount) {
|
||||
return myFixture.complete(CompletionType.SMART, invocationCount);
|
||||
protected CompletionType defaultCompletionType() {
|
||||
return CompletionType.SMART;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -33,6 +33,5 @@ public abstract class AbstractJvmWithLibBasicCompletionTest : JetFixtureCompleti
|
||||
}
|
||||
|
||||
override fun getPlatform() = JvmPlatform
|
||||
|
||||
override fun complete(invocationCount: Int) = myFixture.complete(CompletionType.BASIC, invocationCount)
|
||||
override fun defaultCompletionType() = CompletionType.BASIC
|
||||
}
|
||||
|
||||
+5
-3
@@ -25,9 +25,11 @@ import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
public abstract class AbstractKeywordCompletionTest : JetFixtureCompletionBaseTestCase() {
|
||||
override fun getPlatform() = JvmPlatform
|
||||
|
||||
override fun complete(invocationCount: Int): Array<LookupElement>? {
|
||||
val items = myFixture.complete(CompletionType.BASIC) ?: return null
|
||||
return items.filter { it.getObject() is KeywordLookupObject }.toTypedArray()
|
||||
override fun defaultCompletionType() = CompletionType.BASIC
|
||||
|
||||
override fun complete(completionType: CompletionType, invocationCount: Int): Array<LookupElement>? {
|
||||
val items = myFixture.complete(completionType) ?: return null
|
||||
return items.filter { it.`object` is KeywordLookupObject }.toTypedArray()
|
||||
}
|
||||
|
||||
override fun getProjectDescriptor() = JetLightProjectDescriptor.INSTANCE
|
||||
|
||||
+1
-2
@@ -43,6 +43,5 @@ public abstract class AbstractKotlinSourceInJavaCompletionTest : JetFixtureCompl
|
||||
}
|
||||
|
||||
override fun getProjectDescriptor() = LightCodeInsightFixtureTestCase.JAVA_LATEST
|
||||
|
||||
override fun complete(invocationCount: Int) = myFixture.complete(CompletionType.BASIC, invocationCount)
|
||||
override fun defaultCompletionType() = CompletionType.BASIC
|
||||
}
|
||||
|
||||
+4
-2
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.completion.test
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import org.jetbrains.kotlin.idea.test.AstAccessControl
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
|
||||
@@ -24,10 +25,11 @@ public abstract class AbstractMultiFileJvmBasicCompletionTest : KotlinCompletion
|
||||
configureByFile(getTestName(false) + ".kt", "")
|
||||
val shouldFail = testPath.contains("NoSpecifiedType")
|
||||
AstAccessControl.testWithControlledAccessToAst(shouldFail, getFile().getVirtualFile(), getProject(), getTestRootDisposable(), {
|
||||
testCompletion(getFile().getText(), JvmPlatform, { invocationCount ->
|
||||
testCompletion(getFile().getText(), JvmPlatform, { completionType, invocationCount ->
|
||||
setType(completionType)
|
||||
complete(invocationCount)
|
||||
myItems
|
||||
}, 0)
|
||||
}, CompletionType.BASIC, 0)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -29,10 +29,11 @@ public abstract class AbstractMultiFileSmartCompletionTest : KotlinCompletionTes
|
||||
protected fun doTest(testPath: String) {
|
||||
configureByFile(getTestName(false) + ".kt", "")
|
||||
AstAccessControl.testWithControlledAccessToAst(false, getFile().getVirtualFile(), getProject(), getTestRootDisposable(), {
|
||||
testCompletion(getFile().getText(), JvmPlatform, { invocationCount ->
|
||||
testCompletion(getFile().getText(), JvmPlatform, { completionType, invocationCount ->
|
||||
setType(completionType)
|
||||
complete(invocationCount)
|
||||
myItems
|
||||
}, 1)
|
||||
}, CompletionType.SMART, 1)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.idea.completion.test
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.test.JetTestUtils
|
||||
@@ -26,10 +27,11 @@ val RELATIVE_COMPLETION_TEST_DATA_BASE_PATH = "idea/idea-completion/testData"
|
||||
|
||||
val COMPLETION_TEST_DATA_BASE_PATH = JetTestUtils.getHomeDirectory() + "/" + RELATIVE_COMPLETION_TEST_DATA_BASE_PATH
|
||||
|
||||
fun testCompletion(fileText: String, platform: TargetPlatform?, complete: (Int) -> Array<LookupElement>?, defaultInvocationCount: Int = 0) {
|
||||
fun testCompletion(fileText: String, platform: TargetPlatform?, complete: (CompletionType, Int) -> Array<LookupElement>?, defaultCompletionType: CompletionType = CompletionType.BASIC, defaultInvocationCount: Int = 0) {
|
||||
testWithAutoCompleteSetting(fileText) {
|
||||
val completionType = ExpectedCompletionUtils.getCompletionType(fileText) ?: defaultCompletionType
|
||||
val invocationCount = ExpectedCompletionUtils.getInvocationCount(fileText) ?: defaultInvocationCount
|
||||
val items = complete(invocationCount) ?: emptyArray()
|
||||
val items = complete(completionType, invocationCount) ?: emptyArray()
|
||||
|
||||
ExpectedCompletionUtils.assertDirectivesValid(fileText)
|
||||
|
||||
|
||||
+14
@@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableList
|
||||
import com.google.gson.JsonNull
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
||||
import com.intellij.codeInsight.lookup.impl.LookupCellRenderer
|
||||
@@ -113,6 +114,8 @@ public object ExpectedCompletionUtils {
|
||||
|
||||
public val RUNTIME_TYPE: String = "RUNTIME_TYPE:"
|
||||
|
||||
private val COMPLETION_TYPE_PREFIX = "COMPLETION_TYPE:"
|
||||
|
||||
public val KNOWN_PREFIXES: List<String> = ImmutableList.of(
|
||||
EXIST_LINE_PREFIX,
|
||||
ABSENT_LINE_PREFIX,
|
||||
@@ -128,6 +131,7 @@ public object ExpectedCompletionUtils {
|
||||
AUTOCOMPLETE_SETTING_PREFIX,
|
||||
NOTHING_ELSE_PREFIX,
|
||||
RUNTIME_TYPE,
|
||||
COMPLETION_TYPE_PREFIX,
|
||||
AstAccessControl.ALLOW_AST_ACCESS_DIRECTIVE)
|
||||
|
||||
public fun itemsShouldExist(fileText: String, platform: TargetPlatform?): Array<CompletionProposal> {
|
||||
@@ -186,6 +190,16 @@ public object ExpectedCompletionUtils {
|
||||
return InTextDirectivesUtils.getPrefixedInt(fileText, INVOCATION_COUNT_PREFIX)
|
||||
}
|
||||
|
||||
public fun getCompletionType(fileText: String): CompletionType? {
|
||||
val completionTypeString = InTextDirectivesUtils.findStringWithPrefixes(fileText, COMPLETION_TYPE_PREFIX)
|
||||
return when (completionTypeString) {
|
||||
"BASIC" -> CompletionType.BASIC
|
||||
"SMART" -> CompletionType.SMART
|
||||
null -> null
|
||||
else -> error("Unknown completion type: $completionTypeString")
|
||||
}
|
||||
}
|
||||
|
||||
public fun getAutocompleteSetting(fileText: String): Boolean? {
|
||||
return InTextDirectivesUtils.getPrefixedBoolean(fileText, AUTOCOMPLETE_SETTING_PREFIX)
|
||||
}
|
||||
|
||||
+5
-2
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.completion.test
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.LibraryModificationTracker
|
||||
@@ -26,15 +27,17 @@ import java.io.File
|
||||
public abstract class JetFixtureCompletionBaseTestCase : JetLightCodeInsightFixtureTestCase() {
|
||||
public abstract fun getPlatform(): TargetPlatform
|
||||
|
||||
protected abstract fun complete(invocationCount: Int): Array<LookupElement>?
|
||||
protected open fun complete(completionType: CompletionType, invocationCount: Int): Array<LookupElement>?
|
||||
= myFixture.complete(completionType, invocationCount)
|
||||
|
||||
protected abstract fun defaultCompletionType(): CompletionType
|
||||
protected open fun defaultInvocationCount(): Int = 0
|
||||
|
||||
public open fun doTest(testPath: String) {
|
||||
setUpFixture(testPath)
|
||||
|
||||
val fileText = FileUtil.loadFile(File(testPath), true)
|
||||
testCompletion(fileText, getPlatform(), { complete(it) }, defaultInvocationCount())
|
||||
testCompletion(fileText, getPlatform(), { completionType, count -> complete(completionType, count) }, defaultCompletionType(), defaultInvocationCount())
|
||||
}
|
||||
|
||||
protected open fun setUpFixture(testPath: String) {
|
||||
|
||||
+2
-8
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.completion.test.handlers
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
||||
import org.jetbrains.kotlin.idea.completion.test.ExpectedCompletionUtils
|
||||
import org.jetbrains.kotlin.idea.core.formatter.JetCodeStyleSettings
|
||||
import org.jetbrains.kotlin.idea.test.JetWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
@@ -31,7 +32,6 @@ public abstract class AbstractCompletionHandlerTest(private val defaultCompletio
|
||||
private val ELEMENT_TEXT_PREFIX = "ELEMENT_TEXT:"
|
||||
private val TAIL_TEXT_PREFIX = "TAIL_TEXT:"
|
||||
private val COMPLETION_CHAR_PREFIX = "CHAR:"
|
||||
private val COMPLETION_TYPE_PREFIX = "COMPLETION_TYPE:"
|
||||
private val CODE_STYLE_SETTING_PREFIX = "CODE_STYLE_SETTING:"
|
||||
|
||||
protected open fun doTest(testPath: String) {
|
||||
@@ -54,13 +54,7 @@ public abstract class AbstractCompletionHandlerTest(private val defaultCompletio
|
||||
else -> completionCharString.singleOrNull() ?: error("Incorrect completion char: \"$completionCharString\"")
|
||||
}
|
||||
|
||||
val completionTypeString = InTextDirectivesUtils.findStringWithPrefixes(fileText, COMPLETION_TYPE_PREFIX)
|
||||
val completionType = when (completionTypeString) {
|
||||
"BASIC" -> CompletionType.BASIC
|
||||
"SMART" -> CompletionType.SMART
|
||||
null -> defaultCompletionType
|
||||
else -> error("Unknown completion type: $completionTypeString")
|
||||
}
|
||||
val completionType = ExpectedCompletionUtils.getCompletionType(fileText) ?: defaultCompletionType
|
||||
|
||||
val codeStyleSettings = JetCodeStyleSettings.getInstance(getProject())
|
||||
for (line in InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, CODE_STYLE_SETTING_PREFIX)) {
|
||||
|
||||
-1
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.jetbrains.kotlin.test.JetTestUtils
|
||||
import java.io.File
|
||||
import kotlin.test.fail
|
||||
|
||||
public abstract class AbstractCodeFragmentHighlightingTest : AbstractJetPsiCheckerTest() {
|
||||
override fun doTest(filePath: String) {
|
||||
|
||||
+1
-4
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger.evaluate
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.ModifiableRootModel
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
@@ -68,9 +67,7 @@ public class CodeFragmentCompletionInLibraryTest : AbstractJvmBasicCompletionTes
|
||||
private fun testCompletionInLibraryCodeFragment(fragmentText: String, vararg completionDirectives: String) {
|
||||
setupFixtureByCodeFragment(fragmentText)
|
||||
val directives = completionDirectives.map { "//$it" }.joinToString(separator = "\n")
|
||||
testCompletion(directives, JvmPlatform, {
|
||||
myFixture.complete(CompletionType.BASIC)
|
||||
})
|
||||
testCompletion(directives, JvmPlatform, { completionType, count -> myFixture.complete(completionType, count) })
|
||||
}
|
||||
|
||||
private fun setupFixtureByCodeFragment(fragmentText: String) {
|
||||
|
||||
+6
@@ -126,5 +126,11 @@ public class CodeFragmentCompletionTestGenerated extends AbstractCodeFragmentCom
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/codeFragments/runtimeType/runtimeCast.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("smartCompletion.kt")
|
||||
public void testSmartCompletion() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/codeFragments/runtimeType/smartCompletion.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-3
@@ -48,9 +48,7 @@ public abstract class AbstractAndroidCompletionTest : KotlinAndroidTestCase() {
|
||||
val virtualFile = myFixture.copyFileToProject(path + getTestName(true) + ".kt", "src/" + getTestName(true) + ".kt");
|
||||
myFixture.configureFromExistingVirtualFile(virtualFile)
|
||||
val fileText = FileUtil.loadFile(File(path + getTestName(true) + ".kt"), true)
|
||||
testCompletion(fileText, JvmPlatform, {
|
||||
count -> myFixture.complete(completionType())
|
||||
})
|
||||
testCompletion(fileText, JvmPlatform, { completionType, count -> myFixture.complete(completionType, count) })
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user