Basic completion shows items from smart completion after "as" + do not insert any tail in basic completion
This commit is contained in:
+20
-15
@@ -30,8 +30,9 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.completion.smart.SMART_COMPLETION_ITEM_PRIORITY_KEY
|
||||||
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletion
|
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletion
|
||||||
import org.jetbrains.kotlin.idea.completion.smart.toExpressionWithType
|
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletionItemPriority
|
||||||
import org.jetbrains.kotlin.idea.project.ProjectStructureUtil
|
import org.jetbrains.kotlin.idea.project.ProjectStructureUtil
|
||||||
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -95,13 +96,9 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
|||||||
else
|
else
|
||||||
null
|
null
|
||||||
|
|
||||||
private val expectedInfos = if (expression != null)
|
|
||||||
ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor).calculate(expression.toExpressionWithType())
|
|
||||||
else
|
|
||||||
null
|
|
||||||
|
|
||||||
private val smartCompletion = expression?.let {
|
private val smartCompletion = expression?.let {
|
||||||
SmartCompletion(it, resolutionFacade, moduleDescriptor, bindingContext, isVisibleFilter, inDescriptor, prefixMatcher, GlobalSearchScope.EMPTY_SCOPE, toFromOriginalFileMapper, lookupElementFactory)
|
SmartCompletion(it, resolutionFacade, moduleDescriptor, bindingContext, isVisibleFilter, inDescriptor, prefixMatcher,
|
||||||
|
GlobalSearchScope.EMPTY_SCOPE, toFromOriginalFileMapper, lookupElementFactory, forBasicCompletion = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calcCompletionKind(): CompletionKind {
|
private fun calcCompletionKind(): CompletionKind {
|
||||||
@@ -198,6 +195,20 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (completionKind != CompletionKind.NAMED_ARGUMENTS_ONLY) {
|
if (completionKind != CompletionKind.NAMED_ARGUMENTS_ONLY) {
|
||||||
|
if (smartCompletion != null) {
|
||||||
|
@suppress("UNUSED_VARIABLE") // we don't use InheritanceSearcher
|
||||||
|
val (additionalItems, inheritanceSearcher) = smartCompletion.additionalItems()
|
||||||
|
|
||||||
|
// all additional items should have SMART_COMPLETION_ITEM_PRIORITY_KEY to be recognized by SmartCompletionInBasicWeigher
|
||||||
|
for (item in additionalItems) {
|
||||||
|
if (item.getUserData(SMART_COMPLETION_ITEM_PRIORITY_KEY) == null) {
|
||||||
|
item.putUserData(SMART_COMPLETION_ITEM_PRIORITY_KEY, SmartCompletionItemPriority.DEFAULT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collector.addElements(additionalItems)
|
||||||
|
}
|
||||||
|
|
||||||
collector.addDescriptorElements(referenceVariants, suppressAutoInsertion = false)
|
collector.addDescriptorElements(referenceVariants, suppressAutoInsertion = false)
|
||||||
|
|
||||||
val keywordsPrefix = prefix.substringBefore('@') // if there is '@' in the prefix - use shorter prefix to not loose 'this' etc
|
val keywordsPrefix = prefix.substringBefore('@') // if there is '@' in the prefix - use shorter prefix to not loose 'this' etc
|
||||||
@@ -251,12 +262,6 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (completionKind != CompletionKind.KEYWORDS_ONLY) {
|
if (completionKind != CompletionKind.KEYWORDS_ONLY) {
|
||||||
if (smartCompletion != null && expectedInfos != null && expectedInfos.isNotEmpty()) {
|
|
||||||
@suppress("UNUSED_VARIABLE") // we don't use InheritanceSearcher
|
|
||||||
val (additionalItems, inheritanceSearcher) = smartCompletion.additionalItems(expectedInfos, forOrdinaryCompletion = true)
|
|
||||||
collector.addElements(additionalItems)
|
|
||||||
}
|
|
||||||
|
|
||||||
flushToResultSet()
|
flushToResultSet()
|
||||||
|
|
||||||
if (!configuration.completeNonImportedDeclarations && isNoQualifierContext()) {
|
if (!configuration.completeNonImportedDeclarations && isNoQualifierContext()) {
|
||||||
@@ -300,8 +305,8 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
|||||||
sorter = sorter.weighBefore(DeprecatedWeigher.toString(), ParameterNameAndTypeCompletion.Weigher)
|
sorter = sorter.weighBefore(DeprecatedWeigher.toString(), ParameterNameAndTypeCompletion.Weigher)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smartCompletion != null && expectedInfos != null && expectedInfos.isNotEmpty()) {
|
if (smartCompletion != null) {
|
||||||
sorter = sorter.weighBefore(KindWeigher.toString(), ExpectedInfoMatchWeigher(expectedInfos, smartCompletion), SmartCompletionPriorityWeigher)
|
sorter = sorter.weighBefore(KindWeigher.toString(), SmartCompletionInBasicWeigher(smartCompletion), SmartCompletionPriorityWeigher)
|
||||||
}
|
}
|
||||||
|
|
||||||
return sorter
|
return sorter
|
||||||
|
|||||||
@@ -315,17 +315,23 @@ fun LookupElementFactory.createLookupElementForType(type: JetType): LookupElemen
|
|||||||
|
|
||||||
val itemText = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type)
|
val itemText = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type)
|
||||||
|
|
||||||
return object : BaseTypeLookupElement(type, baseLookupElement) {
|
val typeLookupElement = object : BaseTypeLookupElement(type, baseLookupElement) {
|
||||||
override fun renderElement(presentation: LookupElementPresentation) {
|
override fun renderElement(presentation: LookupElementPresentation) {
|
||||||
super.renderElement(presentation)
|
super.renderElement(presentation)
|
||||||
presentation.setItemText(itemText)
|
presentation.setItemText(itemText)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if type is simply classifier without anything else, use classifier's lookup element to avoid duplicates (works after "as" in basic completion)
|
||||||
|
return if (typeLookupElement.fullText == IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(classifier))
|
||||||
|
baseLookupElement
|
||||||
|
else
|
||||||
|
typeLookupElement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private open class BaseTypeLookupElement(type: JetType, baseLookupElement: LookupElement) : LookupElementDecorator<LookupElement>(baseLookupElement) {
|
private open class BaseTypeLookupElement(type: JetType, baseLookupElement: LookupElement) : LookupElementDecorator<LookupElement>(baseLookupElement) {
|
||||||
private val fullText = IdeDescriptorRenderers.SOURCE_CODE.renderType(type)
|
val fullText = IdeDescriptorRenderers.SOURCE_CODE.renderType(type)
|
||||||
|
|
||||||
override fun equals(other: Any?) = other is BaseTypeLookupElement && fullText == other.fullText
|
override fun equals(other: Any?) = other is BaseTypeLookupElement && fullText == other.fullText
|
||||||
override fun hashCode() = fullText.hashCode()
|
override fun hashCode() = fullText.hashCode()
|
||||||
|
|||||||
@@ -86,16 +86,36 @@ class ByExpectedTypeFilter(val fuzzyType: FuzzyType) : ByTypeFilter {
|
|||||||
override fun hashCode() = fuzzyType.hashCode()
|
override fun hashCode() = fuzzyType.hashCode()
|
||||||
}
|
}
|
||||||
|
|
||||||
open data class ExpectedInfo(val filter: ByTypeFilter, val expectedName: String?, val tail: Tail?, val itemOptions: ItemOptions = ItemOptions.DEFAULT) {
|
data class ExpectedInfo(
|
||||||
constructor(fuzzyType: FuzzyType, expectedName: String?, tail: Tail?, itemOptions: ItemOptions = ItemOptions.DEFAULT)
|
val filter: ByTypeFilter,
|
||||||
: this(ByExpectedTypeFilter(fuzzyType), expectedName, tail, itemOptions)
|
val expectedName: String?,
|
||||||
|
val tail: Tail?,
|
||||||
|
val itemOptions: ItemOptions = ItemOptions.DEFAULT,
|
||||||
|
val additionalData: ExpectedInfo.AdditionalData? = null
|
||||||
|
) {
|
||||||
|
// just a marker interface
|
||||||
|
interface AdditionalData {}
|
||||||
|
|
||||||
constructor(type: JetType, expectedName: String?, tail: Tail?, itemOptions: ItemOptions = ItemOptions.DEFAULT)
|
constructor(fuzzyType: FuzzyType, expectedName: String?, tail: Tail?, itemOptions: ItemOptions = ItemOptions.DEFAULT, additionalData: ExpectedInfo.AdditionalData? = null)
|
||||||
: this(FuzzyType(type, emptyList()), expectedName, tail, itemOptions)
|
: this(ByExpectedTypeFilter(fuzzyType), expectedName, tail, itemOptions, additionalData)
|
||||||
|
|
||||||
|
constructor(type: JetType, expectedName: String?, tail: Tail?, itemOptions: ItemOptions = ItemOptions.DEFAULT, additionalData: ExpectedInfo.AdditionalData? = null)
|
||||||
|
: this(FuzzyType(type, emptyList()), expectedName, tail, itemOptions, additionalData)
|
||||||
|
|
||||||
fun matchingSubstitutor(descriptorType: FuzzyType): TypeSubstitutor? = filter.matchingSubstitutor(descriptorType)
|
fun matchingSubstitutor(descriptorType: FuzzyType): TypeSubstitutor? = filter.matchingSubstitutor(descriptorType)
|
||||||
|
|
||||||
fun matchingSubstitutor(descriptorType: JetType): TypeSubstitutor? = matchingSubstitutor(FuzzyType(descriptorType, emptyList()))
|
fun matchingSubstitutor(descriptorType: JetType): TypeSubstitutor? = matchingSubstitutor(FuzzyType(descriptorType, emptyList()))
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun createForArgument(type: JetType, name: String?, tail: Tail?, function: FunctionDescriptor, position: ArgumentPosition, itemOptions: ItemOptions = ItemOptions.DEFAULT): ExpectedInfo {
|
||||||
|
return ExpectedInfo(FuzzyType(type, function.typeParameters), name, tail, itemOptions, ArgumentAdditionalData(function, position))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createForReturnValue(type: JetType?, callable: CallableDescriptor): ExpectedInfo {
|
||||||
|
val filter = if (type != null) ByExpectedTypeFilter(FuzzyType(type, emptyList())) else ByTypeFilter.All
|
||||||
|
return ExpectedInfo(filter, callable.name.asString(), null, additionalData = ReturnValueAdditionalData(callable))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val ExpectedInfo.fuzzyType: FuzzyType?
|
val ExpectedInfo.fuzzyType: FuzzyType?
|
||||||
@@ -106,26 +126,17 @@ data class ArgumentPosition(val argumentIndex: Int, val argumentName: Name?, val
|
|||||||
constructor(argumentIndex: Int, argumentName: Name?) : this(argumentIndex, argumentName, false)
|
constructor(argumentIndex: Int, argumentName: Name?) : this(argumentIndex, argumentName, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArgumentExpectedInfo(type: JetType, name: String?, tail: Tail?, val function: FunctionDescriptor, val position: ArgumentPosition, itemOptions: ItemOptions = ItemOptions.DEFAULT)
|
class ArgumentAdditionalData(val function: FunctionDescriptor, val position: ArgumentPosition) : ExpectedInfo.AdditionalData {
|
||||||
: ExpectedInfo(FuzzyType(type, function.typeParameters), name, tail, itemOptions) {
|
|
||||||
|
|
||||||
override fun equals(other: Any?)
|
override fun equals(other: Any?)
|
||||||
= other is ArgumentExpectedInfo && super.equals(other) && function == other.function && position == other.position
|
= other is ArgumentAdditionalData && function == other.function && position == other.position
|
||||||
|
|
||||||
override fun hashCode()
|
override fun hashCode()
|
||||||
= function.hashCode()
|
= function.hashCode()
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReturnValueExpectedInfo(
|
class ReturnValueAdditionalData(val callable: CallableDescriptor) : ExpectedInfo.AdditionalData {
|
||||||
type: JetType?,
|
|
||||||
val callable: CallableDescriptor
|
|
||||||
) : ExpectedInfo(
|
|
||||||
if (type != null) ByExpectedTypeFilter(FuzzyType(type, emptyList())) else ByTypeFilter.All,
|
|
||||||
callable.name.asString(),
|
|
||||||
null
|
|
||||||
) {
|
|
||||||
override fun equals(other: Any?)
|
override fun equals(other: Any?)
|
||||||
= other is ReturnValueExpectedInfo && super.equals(other) && callable == other.callable
|
= other is ReturnValueAdditionalData && callable == other.callable
|
||||||
|
|
||||||
override fun hashCode()
|
override fun hashCode()
|
||||||
= callable.hashCode()
|
= callable.hashCode()
|
||||||
@@ -180,7 +191,14 @@ class ExpectedInfos(
|
|||||||
public fun calculateForArgument(call: Call, argument: ValueArgument): Collection<ExpectedInfo>? {
|
public fun calculateForArgument(call: Call, argument: ValueArgument): Collection<ExpectedInfo>? {
|
||||||
val results = calculateForArgument(call, TypeUtils.NO_EXPECTED_TYPE, argument) ?: return null
|
val results = calculateForArgument(call, TypeUtils.NO_EXPECTED_TYPE, argument) ?: return null
|
||||||
|
|
||||||
if (useOuterCallsExpectedTypeCount > 0 && results.any { it.fuzzyType != null && it.fuzzyType!!.freeParameters.isNotEmpty() && it.function.fuzzyReturnType()?.freeParameters?.isNotEmpty() ?: false }) {
|
fun makesSenseToUseOuterCallExpectedType(info: ExpectedInfo): Boolean {
|
||||||
|
val data = info.additionalData as ArgumentAdditionalData
|
||||||
|
return info.fuzzyType != null
|
||||||
|
&& info.fuzzyType!!.freeParameters.isNotEmpty()
|
||||||
|
&& data.function.fuzzyReturnType()?.freeParameters?.isNotEmpty() ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useOuterCallsExpectedTypeCount > 0 && results.any(::makesSenseToUseOuterCallExpectedType)) {
|
||||||
val callExpression = (call.callElement as? JetExpression)?.getQualifiedExpressionForSelectorOrThis() ?: return results
|
val callExpression = (call.callElement as? JetExpression)?.getQualifiedExpressionForSelectorOrThis() ?: return results
|
||||||
val expectedFuzzyTypes = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useHeuristicSignatures, useOuterCallsExpectedTypeCount - 1)
|
val expectedFuzzyTypes = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useHeuristicSignatures, useOuterCallsExpectedTypeCount - 1)
|
||||||
.calculate(callExpression)
|
.calculate(callExpression)
|
||||||
@@ -198,7 +216,7 @@ class ExpectedInfos(
|
|||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calculateForArgument(call: Call, callExpectedType: JetType, argument: ValueArgument): Collection<ArgumentExpectedInfo>? {
|
private fun calculateForArgument(call: Call, callExpectedType: JetType, argument: ValueArgument): Collection<ExpectedInfo>? {
|
||||||
val argumentIndex = call.getValueArguments().indexOf(argument)
|
val argumentIndex = call.getValueArguments().indexOf(argument)
|
||||||
assert(argumentIndex >= 0) {
|
assert(argumentIndex >= 0) {
|
||||||
"Could not find argument '$argument' among arguments of call: $call"
|
"Could not find argument '$argument' among arguments of call: $call"
|
||||||
@@ -229,7 +247,7 @@ class ExpectedInfos(
|
|||||||
val callResolver = createContainerForMacros(project, moduleDescriptor).callResolver
|
val callResolver = createContainerForMacros(project, moduleDescriptor).callResolver
|
||||||
val results: OverloadResolutionResults<FunctionDescriptor> = callResolver.resolveFunctionCall(callResolutionContext)
|
val results: OverloadResolutionResults<FunctionDescriptor> = callResolver.resolveFunctionCall(callResolutionContext)
|
||||||
|
|
||||||
val expectedInfos = LinkedHashSet<ArgumentExpectedInfo>()
|
val expectedInfos = LinkedHashSet<ExpectedInfo>()
|
||||||
for (candidate: ResolvedCall<FunctionDescriptor> in results.getAllCandidates()!!) {
|
for (candidate: ResolvedCall<FunctionDescriptor> in results.getAllCandidates()!!) {
|
||||||
val status = candidate.getStatus()
|
val status = candidate.getStatus()
|
||||||
if (status == ResolutionStatus.RECEIVER_TYPE_ERROR || status == ResolutionStatus.RECEIVER_PRESENCE_ERROR) continue
|
if (status == ResolutionStatus.RECEIVER_TYPE_ERROR || status == ResolutionStatus.RECEIVER_PRESENCE_ERROR) continue
|
||||||
@@ -289,11 +307,11 @@ class ExpectedInfos(
|
|||||||
tail
|
tail
|
||||||
|
|
||||||
if (!alreadyHasStar) {
|
if (!alreadyHasStar) {
|
||||||
expectedInfos.add(ArgumentExpectedInfo(varargElementType, expectedName?.unpluralize(), varargTail, descriptor, argumentPosition))
|
expectedInfos.add(ExpectedInfo.createForArgument(varargElementType, expectedName?.unpluralize(), varargTail, descriptor, argumentPosition))
|
||||||
}
|
}
|
||||||
|
|
||||||
val starOptions = if (!alreadyHasStar) ItemOptions.STAR_PREFIX else ItemOptions.DEFAULT
|
val starOptions = if (!alreadyHasStar) ItemOptions.STAR_PREFIX else ItemOptions.DEFAULT
|
||||||
expectedInfos.add(ArgumentExpectedInfo(parameter.getType(), expectedName, varargTail, descriptor, argumentPosition, starOptions))
|
expectedInfos.add(ExpectedInfo.createForArgument(parameter.getType(), expectedName, varargTail, descriptor, argumentPosition, starOptions))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (alreadyHasStar) continue
|
if (alreadyHasStar) continue
|
||||||
@@ -305,11 +323,11 @@ class ExpectedInfos(
|
|||||||
|
|
||||||
if (isFunctionLiteralArgument) {
|
if (isFunctionLiteralArgument) {
|
||||||
if (KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(parameterType)) {
|
if (KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(parameterType)) {
|
||||||
expectedInfos.add(ArgumentExpectedInfo(parameterType, expectedName, null, descriptor, argumentPosition))
|
expectedInfos.add(ExpectedInfo.createForArgument(parameterType, expectedName, null, descriptor, argumentPosition))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
expectedInfos.add(ArgumentExpectedInfo(parameterType, expectedName, tail, descriptor, argumentPosition))
|
expectedInfos.add(ExpectedInfo.createForArgument(parameterType, expectedName, tail, descriptor, argumentPosition))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,18 +475,18 @@ class ExpectedInfos(
|
|||||||
return functionReturnValueExpectedInfo(descriptor, expectType = true).singletonOrEmptyList()
|
return functionReturnValueExpectedInfo(descriptor, expectType = true).singletonOrEmptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun functionReturnValueExpectedInfo(descriptor: FunctionDescriptor, expectType: Boolean): ReturnValueExpectedInfo? {
|
private fun functionReturnValueExpectedInfo(descriptor: FunctionDescriptor, expectType: Boolean): ExpectedInfo? {
|
||||||
return when (descriptor) {
|
return when (descriptor) {
|
||||||
is SimpleFunctionDescriptor -> {
|
is SimpleFunctionDescriptor -> {
|
||||||
val expectedType = if (expectType) descriptor.returnType else null
|
val expectedType = if (expectType) descriptor.returnType else null
|
||||||
ReturnValueExpectedInfo(expectedType, descriptor)
|
ExpectedInfo.createForReturnValue(expectedType, descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
is PropertyGetterDescriptor -> {
|
is PropertyGetterDescriptor -> {
|
||||||
if (descriptor !is PropertyGetterDescriptor) return null
|
if (descriptor !is PropertyGetterDescriptor) return null
|
||||||
val property = descriptor.getCorrespondingProperty()
|
val property = descriptor.getCorrespondingProperty()
|
||||||
val expectedType = if (expectType) property.type else null
|
val expectedType = if (expectType) property.type else null
|
||||||
ReturnValueExpectedInfo(expectedType, property)
|
ExpectedInfo.createForReturnValue(expectedType, property)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
|
|||||||
@@ -186,13 +186,9 @@ class DeclarationRemotenessWeigher(private val file: JetFile) : LookupElementWei
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExpectedInfoMatchWeigher(
|
class SmartCompletionInBasicWeigher(private val smartCompletion: SmartCompletion) : LookupElementWeigher("kotlin.smartInBasic") {
|
||||||
private val expectedInfos: Collection<ExpectedInfo>,
|
|
||||||
private val smartCompletion: SmartCompletion
|
|
||||||
) : LookupElementWeigher("kotlin.expectedInfoMatch") {
|
|
||||||
|
|
||||||
private val smartCastCalculator = smartCompletion.smartCastCalculator
|
|
||||||
private val descriptorsToSkip = smartCompletion.descriptorsToSkip
|
private val descriptorsToSkip = smartCompletion.descriptorsToSkip
|
||||||
|
private val expectedInfos = smartCompletion.expectedInfos
|
||||||
|
|
||||||
private fun fullMatchWeight(nameSimilarity: Int): Long {
|
private fun fullMatchWeight(nameSimilarity: Int): Long {
|
||||||
return -((3L shl 32) + nameSimilarity)
|
return -((3L shl 32) + nameSimilarity)
|
||||||
@@ -218,10 +214,16 @@ class ExpectedInfoMatchWeigher(
|
|||||||
|
|
||||||
// TODO: keywords with type
|
// TODO: keywords with type
|
||||||
val o = element.`object`
|
val o = element.`object`
|
||||||
|
|
||||||
|
if ((o as? DeclarationLookupObject)?.descriptor in descriptorsToSkip) return DESCRIPTOR_TO_SKIP_WEIGHT
|
||||||
|
|
||||||
|
if (expectedInfos == null || expectedInfos.isEmpty()) return NO_MATCH_WEIGHT
|
||||||
|
|
||||||
|
val smartCastCalculator = smartCompletion.smartCastCalculator
|
||||||
|
|
||||||
val (fuzzyTypes, name) = when (o) {
|
val (fuzzyTypes, name) = when (o) {
|
||||||
is DeclarationLookupObject -> {
|
is DeclarationLookupObject -> {
|
||||||
val descriptor = o.descriptor ?: return NO_MATCH_WEIGHT
|
val descriptor = o.descriptor ?: return NO_MATCH_WEIGHT
|
||||||
if (descriptor in descriptorsToSkip) return DESCRIPTOR_TO_SKIP_WEIGHT
|
|
||||||
descriptor.fuzzyTypesForSmartCompletion(smartCastCalculator) to descriptor.name
|
descriptor.fuzzyTypesForSmartCompletion(smartCastCalculator) to descriptor.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -43,8 +43,8 @@ class MultipleArgumentsItemProvider(val bindingContext: BindingContext,
|
|||||||
|
|
||||||
val added = HashSet<String>()
|
val added = HashSet<String>()
|
||||||
for (expectedInfo in expectedInfos) {
|
for (expectedInfo in expectedInfos) {
|
||||||
if (expectedInfo is ArgumentExpectedInfo && expectedInfo.position == ArgumentPosition(0)) {
|
if (expectedInfo.additionalData is ArgumentAdditionalData && expectedInfo.additionalData.position == ArgumentPosition(0)) {
|
||||||
val parameters = expectedInfo.function.getValueParameters()
|
val parameters = expectedInfo.additionalData.function.valueParameters
|
||||||
if (parameters.size() > 1) {
|
if (parameters.size() > 1) {
|
||||||
val variables = ArrayList<VariableDescriptor>()
|
val variables = ArrayList<VariableDescriptor>()
|
||||||
for ((i, parameter) in parameters.withIndex()) {
|
for ((i, parameter) in parameters.withIndex()) {
|
||||||
|
|||||||
+37
-26
@@ -48,18 +48,22 @@ interface InheritanceItemsSearcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SmartCompletion(
|
class SmartCompletion(
|
||||||
val expression: JetExpression,
|
private val expression: JetExpression,
|
||||||
val resolutionFacade: ResolutionFacade,
|
private val resolutionFacade: ResolutionFacade,
|
||||||
val moduleDescriptor: ModuleDescriptor,
|
private val moduleDescriptor: ModuleDescriptor,
|
||||||
val bindingContext: BindingContext,
|
private val bindingContext: BindingContext,
|
||||||
val visibilityFilter: (DeclarationDescriptor) -> Boolean,
|
private val visibilityFilter: (DeclarationDescriptor) -> Boolean,
|
||||||
val inDescriptor: DeclarationDescriptor,
|
private val inDescriptor: DeclarationDescriptor,
|
||||||
val prefixMatcher: PrefixMatcher,
|
private val prefixMatcher: PrefixMatcher,
|
||||||
val inheritorSearchScope: GlobalSearchScope,
|
private val inheritorSearchScope: GlobalSearchScope,
|
||||||
val toFromOriginalFileMapper: ToFromOriginalFileMapper,
|
private val toFromOriginalFileMapper: ToFromOriginalFileMapper,
|
||||||
val lookupElementFactory: LookupElementFactory
|
private val lookupElementFactory: LookupElementFactory,
|
||||||
|
private val forBasicCompletion: Boolean = false
|
||||||
) {
|
) {
|
||||||
private val receiver = if (expression is JetSimpleNameExpression) expression.getReceiverExpression() else null
|
private val receiver = if (expression is JetSimpleNameExpression) expression.getReceiverExpression() else null
|
||||||
|
private val expressionWithType = receiver?.parent as? JetExpression ?: expression
|
||||||
|
|
||||||
|
public val expectedInfos: Collection<ExpectedInfo>? = calcExpectedInfos(expressionWithType)
|
||||||
|
|
||||||
public val smartCastCalculator: SmartCastCalculator = SmartCastCalculator(bindingContext, moduleDescriptor, expression)
|
public val smartCastCalculator: SmartCastCalculator = SmartCastCalculator(bindingContext, moduleDescriptor, expression)
|
||||||
|
|
||||||
@@ -107,11 +111,11 @@ class SmartCompletion(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun executeInternal(): Result? {
|
private fun executeInternal(): Result? {
|
||||||
val asTypePositionResult = buildForAsTypePosition()
|
val (additionalItems, inheritanceSearcher) = additionalItems()
|
||||||
if (asTypePositionResult != null) return asTypePositionResult
|
|
||||||
|
|
||||||
val expectedInfos = calcExpectedInfos(expression.toExpressionWithType())
|
if (expectedInfos == null || expectedInfos.isEmpty()) {
|
||||||
if (expectedInfos == null || expectedInfos.isEmpty()) return null
|
return Result(null, additionalItems, inheritanceSearcher)
|
||||||
|
}
|
||||||
|
|
||||||
fun filterDeclaration(descriptor: DeclarationDescriptor): Collection<LookupElement> {
|
fun filterDeclaration(descriptor: DeclarationDescriptor): Collection<LookupElement> {
|
||||||
if (descriptor in descriptorsToSkip) return emptyList()
|
if (descriptor in descriptorsToSkip) return emptyList()
|
||||||
@@ -137,26 +141,28 @@ class SmartCompletion(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
val (additionalItems, inheritanceSearcher) = additionalItems(expectedInfos)
|
|
||||||
|
|
||||||
return Result(::filterDeclaration, additionalItems, inheritanceSearcher)
|
return Result(::filterDeclaration, additionalItems, inheritanceSearcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun additionalItems(
|
public fun additionalItems(): Pair<Collection<LookupElement>, InheritanceItemsSearcher?> {
|
||||||
expectedInfos: Collection<ExpectedInfo>,
|
val asTypePositionItems = buildForAsTypePosition()
|
||||||
forOrdinaryCompletion: Boolean = false
|
if (asTypePositionItems != null) {
|
||||||
): Pair<Collection<LookupElement>, InheritanceItemsSearcher?> {
|
assert(expectedInfos == null)
|
||||||
|
return Pair(asTypePositionItems, null)
|
||||||
|
}
|
||||||
|
|
||||||
val items = ArrayList<LookupElement>()
|
val items = ArrayList<LookupElement>()
|
||||||
val inheritanceSearchers = ArrayList<InheritanceItemsSearcher>()
|
val inheritanceSearchers = ArrayList<InheritanceItemsSearcher>()
|
||||||
if (receiver == null) {
|
|
||||||
TypeInstantiationItems(resolutionFacade, moduleDescriptor, bindingContext, visibilityFilter, toFromOriginalFileMapper, inheritorSearchScope, lookupElementFactory, forOrdinaryCompletion)
|
if (expectedInfos != null && expectedInfos.isNotEmpty() && receiver == null) {
|
||||||
|
TypeInstantiationItems(resolutionFacade, moduleDescriptor, bindingContext, visibilityFilter, toFromOriginalFileMapper, inheritorSearchScope, lookupElementFactory, forBasicCompletion)
|
||||||
.addTo(items, inheritanceSearchers, expectedInfos)
|
.addTo(items, inheritanceSearchers, expectedInfos)
|
||||||
|
|
||||||
if (expression is JetSimpleNameExpression) {
|
if (expression is JetSimpleNameExpression) {
|
||||||
StaticMembers(bindingContext, lookupElementFactory).addToCollection(items, expectedInfos, expression, descriptorsToSkip)
|
StaticMembers(bindingContext, lookupElementFactory).addToCollection(items, expectedInfos, expression, descriptorsToSkip)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!forOrdinaryCompletion) {
|
if (!forBasicCompletion) {
|
||||||
items.addThisItems(expression, expectedInfos, smartCastCalculator)
|
items.addThisItems(expression, expectedInfos, smartCastCalculator)
|
||||||
|
|
||||||
LambdaItems.addToCollection(items, expectedInfos)
|
LambdaItems.addToCollection(items, expectedInfos)
|
||||||
@@ -193,6 +199,12 @@ class SmartCompletion(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun calcExpectedInfos(expression: JetExpression): Collection<ExpectedInfo>? {
|
private fun calcExpectedInfos(expression: JetExpression): Collection<ExpectedInfo>? {
|
||||||
|
if (forBasicCompletion) {
|
||||||
|
return ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useOuterCallsExpectedTypeCount = 0)
|
||||||
|
.calculate(expression)
|
||||||
|
?.map { it.copy(tail = null) }
|
||||||
|
}
|
||||||
|
|
||||||
// if our expression is initializer of implicitly typed variable - take type of variable from original file (+ the same for function)
|
// if our expression is initializer of implicitly typed variable - take type of variable from original file (+ the same for function)
|
||||||
val declaration = implicitlyTypedDeclarationFromInitializer(expression)
|
val declaration = implicitlyTypedDeclarationFromInitializer(expression)
|
||||||
if (declaration != null) {
|
if (declaration != null) {
|
||||||
@@ -227,7 +239,6 @@ class SmartCompletion(
|
|||||||
}
|
}
|
||||||
|
|
||||||
public val descriptorsToSkip: Set<DeclarationDescriptor> by lazy<Set<DeclarationDescriptor>> {
|
public val descriptorsToSkip: Set<DeclarationDescriptor> by lazy<Set<DeclarationDescriptor>> {
|
||||||
val expressionWithType = expression.toExpressionWithType()
|
|
||||||
val parent = expressionWithType.getParent()
|
val parent = expressionWithType.getParent()
|
||||||
when (parent) {
|
when (parent) {
|
||||||
is JetBinaryExpression -> {
|
is JetBinaryExpression -> {
|
||||||
@@ -324,7 +335,7 @@ class SmartCompletion(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildForAsTypePosition(): Result? {
|
private fun buildForAsTypePosition(): Collection<LookupElement>? {
|
||||||
val binaryExpression = ((expression.getParent() as? JetUserType)
|
val binaryExpression = ((expression.getParent() as? JetUserType)
|
||||||
?.getParent() as? JetTypeReference)
|
?.getParent() as? JetTypeReference)
|
||||||
?.getParent() as? JetBinaryExpressionWithTypeRHS
|
?.getParent() as? JetBinaryExpressionWithTypeRHS
|
||||||
@@ -341,7 +352,7 @@ class SmartCompletion(
|
|||||||
val lookupElement = lookupElementFactory.createLookupElementForType(type) ?: continue
|
val lookupElement = lookupElementFactory.createLookupElementForType(type) ?: continue
|
||||||
items.add(lookupElement.addTailAndNameSimilarity(infos))
|
items.add(lookupElement.addTailAndNameSimilarity(infos))
|
||||||
}
|
}
|
||||||
return Result(null, items, null)
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -29,9 +29,6 @@ import org.jetbrains.kotlin.idea.completion.*
|
|||||||
import org.jetbrains.kotlin.idea.completion.handlers.WithExpressionPrefixInsertHandler
|
import org.jetbrains.kotlin.idea.completion.handlers.WithExpressionPrefixInsertHandler
|
||||||
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
|
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
|
||||||
import org.jetbrains.kotlin.idea.util.*
|
import org.jetbrains.kotlin.idea.util.*
|
||||||
import org.jetbrains.kotlin.psi.JetExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.types.JetType
|
import org.jetbrains.kotlin.types.JetType
|
||||||
@@ -41,7 +38,6 @@ import org.jetbrains.kotlin.types.typeUtil.isNothing
|
|||||||
import org.jetbrains.kotlin.util.descriptorsEqualWithSubstitution
|
import org.jetbrains.kotlin.util.descriptorsEqualWithSubstitution
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
import java.util.HashSet
|
|
||||||
|
|
||||||
class ArtificialElementInsertHandler(
|
class ArtificialElementInsertHandler(
|
||||||
val textBeforeCaret: String, val textAfterCaret: String, val shortenRefs: Boolean) : InsertHandler<LookupElement>{
|
val textBeforeCaret: String, val textAfterCaret: String, val shortenRefs: Boolean) : InsertHandler<LookupElement>{
|
||||||
@@ -59,8 +55,7 @@ class ArtificialElementInsertHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun mergeTails(tails: Collection<Tail?>): Tail? {
|
fun mergeTails(tails: Collection<Tail?>): Tail? {
|
||||||
if (tails.size() == 1) return tails.single()
|
return tails.singleOrNull() ?: tails.toSet().singleOrNull()
|
||||||
return if (HashSet(tails).size() == 1) tails.first() else null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun LookupElement.addTail(tail: Tail?): LookupElement {
|
fun LookupElement.addTail(tail: Tail?): LookupElement {
|
||||||
@@ -187,7 +182,7 @@ fun<TDescriptor: DeclarationDescriptor?> MutableCollection<LookupElement>.addLoo
|
|||||||
val lookupElement = itemData.createLookupElement()
|
val lookupElement = itemData.createLookupElement()
|
||||||
if (lookupElement != null) {
|
if (lookupElement != null) {
|
||||||
val nameSimilarityInfos = if (noNameSimilarityForReturnItself && descriptor is CallableDescriptor) {
|
val nameSimilarityInfos = if (noNameSimilarityForReturnItself && descriptor is CallableDescriptor) {
|
||||||
infos.filter { (it as? ReturnValueExpectedInfo)?.callable != descriptor } // do not calculate name similarity with function itself in its return
|
infos.filter { (it.additionalData as? ReturnValueAdditionalData)?.callable != descriptor } // do not calculate name similarity with function itself in its return
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
infos
|
infos
|
||||||
@@ -343,10 +338,6 @@ fun DeclarationDescriptor.fuzzyTypesForSmartCompletion(smartCastCalculator: Smar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun JetExpression.toExpressionWithType(): JetExpression {
|
|
||||||
return (this as? JetSimpleNameExpression)?.getReceiverExpression()?.parent as? JetExpression ?: this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Collection<ExpectedInfo>.filterFunctionExpected()
|
fun Collection<ExpectedInfo>.filterFunctionExpected()
|
||||||
= filter { it.fuzzyType != null && KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(it.fuzzyType!!.type) }
|
= filter { it.fuzzyType != null && KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(it.fuzzyType!!.type) }
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun foo(list: List<String>){}
|
||||||
|
|
||||||
|
fun bar(o: Any) {
|
||||||
|
foo(o as <caret>)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: { itemText: "List<String>" }
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
class Xyz
|
||||||
|
|
||||||
|
fun foo(xyz: Xyz){}
|
||||||
|
|
||||||
|
fun bar(o: Any) {
|
||||||
|
foo(o as Xy<caret>)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: Xyz
|
||||||
|
// NOTHING_ELSE
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class CCC {
|
||||||
|
companion object {
|
||||||
|
fun create(): CCC = CCC()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun f(ccc: CCC, p: Int){}
|
||||||
|
|
||||||
|
fun g() {
|
||||||
|
f(<caret>)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: create
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class CCC {
|
||||||
|
companion object {
|
||||||
|
fun create(): CCC = CCC()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun f(ccc: CCC, p: Int){}
|
||||||
|
|
||||||
|
fun g() {
|
||||||
|
f(CCC.create()<caret>)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: create
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class Xx1
|
||||||
|
class Xx2
|
||||||
|
class Xx3
|
||||||
|
|
||||||
|
fun foo(xx: Xx2){}
|
||||||
|
|
||||||
|
fun bar(o: Any) {
|
||||||
|
foo(o as Xx<caret>)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ORDER: Xx2
|
||||||
|
// ORDER: Xx1
|
||||||
|
// ORDER: Xx3
|
||||||
+12
@@ -1310,6 +1310,18 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
|
|||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class FromSmart extends AbstractJSBasicCompletionTest {
|
public static class FromSmart extends AbstractJSBasicCompletionTest {
|
||||||
|
@TestMetadata("AfterAs.kt")
|
||||||
|
public void testAfterAs() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/fromSmart/AfterAs.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("AfterAsNoDuplicates.kt")
|
||||||
|
public void testAfterAsNoDuplicates() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/fromSmart/AfterAsNoDuplicates.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
public void testAllFilesPresentInFromSmart() throws Exception {
|
public void testAllFilesPresentInFromSmart() throws Exception {
|
||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/fromSmart"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/fromSmart"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -1310,6 +1310,18 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
|||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class FromSmart extends AbstractJvmBasicCompletionTest {
|
public static class FromSmart extends AbstractJvmBasicCompletionTest {
|
||||||
|
@TestMetadata("AfterAs.kt")
|
||||||
|
public void testAfterAs() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/fromSmart/AfterAs.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("AfterAsNoDuplicates.kt")
|
||||||
|
public void testAfterAsNoDuplicates() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/fromSmart/AfterAsNoDuplicates.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
public void testAllFilesPresentInFromSmart() throws Exception {
|
public void testAllFilesPresentInFromSmart() throws Exception {
|
||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/fromSmart"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/fromSmart"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -77,6 +77,12 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("NoTailFromSmart.kt")
|
||||||
|
public void testNoTailFromSmart() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/NoTailFromSmart.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("PlatformStaticInClass.kt")
|
@TestMetadata("PlatformStaticInClass.kt")
|
||||||
public void testPlatformStaticInClass() throws Exception {
|
public void testPlatformStaticInClass() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/PlatformStaticInClass.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/PlatformStaticInClass.kt");
|
||||||
|
|||||||
+6
@@ -147,6 +147,12 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
|
|||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class ExpectedInfo extends AbstractBasicCompletionWeigherTest {
|
public static class ExpectedInfo extends AbstractBasicCompletionWeigherTest {
|
||||||
|
@TestMetadata("AfterAs.kt")
|
||||||
|
public void testAfterAs() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo/AfterAs.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
public void testAllFilesPresentInExpectedInfo() throws Exception {
|
public void testAllFilesPresentInExpectedInfo() throws Exception {
|
||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/weighers/basic/expectedInfo"), Pattern.compile("^([^\\.]+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/weighers/basic/expectedInfo"), Pattern.compile("^([^\\.]+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user