Renamed term "classifier" to "matcher"

This commit is contained in:
Valentin Kipyatkov
2015-10-01 14:20:40 +03:00
parent c0bfca4f89
commit 3a2bc51445
6 changed files with 47 additions and 47 deletions
@@ -33,7 +33,7 @@ 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.ExpectedInfoClassification import org.jetbrains.kotlin.idea.completion.smart.ExpectedInfoMatch
import org.jetbrains.kotlin.idea.completion.smart.SMART_COMPLETION_ITEM_PRIORITY_KEY 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.SmartCompletionItemPriority import org.jetbrains.kotlin.idea.completion.smart.SmartCompletionItemPriority
@@ -278,13 +278,13 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
val keywordsToSkip = HashSet<String>() val keywordsToSkip = HashSet<String>()
val keywordValueConsumer = object : KeywordValues.Consumer { val keywordValueConsumer = object : KeywordValues.Consumer {
override fun consume(lookupString: String, expectedInfoClassifier: (ExpectedInfo) -> ExpectedInfoClassification, priority: SmartCompletionItemPriority, factory: () -> LookupElement) { override fun consume(lookupString: String, expectedInfoMatcher: (ExpectedInfo) -> ExpectedInfoMatch, priority: SmartCompletionItemPriority, factory: () -> LookupElement) {
keywordsToSkip.add(lookupString) keywordsToSkip.add(lookupString)
val lookupElement = factory() val lookupElement = factory()
val matched = expectedInfos.any { val matched = expectedInfos.any {
val classification = expectedInfoClassifier(it) val match = expectedInfoMatcher(it)
assert(!classification.makeNotNullable) { "Nullable keyword values not supported" } assert(!match.makeNotNullable) { "Nullable keyword values not supported" }
classification.isMatch() match.isMatch()
} }
if (matched) { if (matched) {
lookupElement.putUserData(SmartCompletionInBasicWeigher.KEYWORD_VALUE_MATCHED_KEY, matched) lookupElement.putUserData(SmartCompletionInBasicWeigher.KEYWORD_VALUE_MATCHED_KEY, matched)
@@ -23,9 +23,9 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.completion.smart.ExpectedInfoClassification import org.jetbrains.kotlin.idea.completion.smart.ExpectedInfoMatch
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletionItemPriority import org.jetbrains.kotlin.idea.completion.smart.SmartCompletionItemPriority
import org.jetbrains.kotlin.idea.completion.smart.classifyExpectedInfo import org.jetbrains.kotlin.idea.completion.smart.matchExpectedInfo
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
import org.jetbrains.kotlin.idea.util.FuzzyType import org.jetbrains.kotlin.idea.util.FuzzyType
@@ -40,7 +40,7 @@ object KeywordValues {
interface Consumer { interface Consumer {
fun consume( fun consume(
lookupString: String, lookupString: String,
expectedInfoClassifier: (ExpectedInfo) -> ExpectedInfoClassification, expectedInfoMatcher: (ExpectedInfo) -> ExpectedInfoMatch,
priority: SmartCompletionItemPriority, priority: SmartCompletionItemPriority,
factory: () -> LookupElement) factory: () -> LookupElement)
} }
@@ -54,29 +54,29 @@ object KeywordValues {
isJvmModule: Boolean isJvmModule: Boolean
) { ) {
if (callTypeAndReceiver is CallTypeAndReceiver.DEFAULT) { if (callTypeAndReceiver is CallTypeAndReceiver.DEFAULT) {
val booleanInfoClassifier = classifier@ { info: ExpectedInfo -> val booleanInfoMatcher = matcher@ { info: ExpectedInfo ->
// no sense in true or false as when entry // no sense in true or false as when entry
if (info.additionalData is WhenEntryAdditionalData) return@classifier ExpectedInfoClassification.noMatch if (info.additionalData is WhenEntryAdditionalData) return@matcher ExpectedInfoMatch.noMatch
if (info.fuzzyType?.type?.isBooleanOrNullableBoolean() ?: false) if (info.fuzzyType?.type?.isBooleanOrNullableBoolean() ?: false)
ExpectedInfoClassification.match(TypeSubstitutor.EMPTY) ExpectedInfoMatch.match(TypeSubstitutor.EMPTY)
else else
ExpectedInfoClassification.noMatch ExpectedInfoMatch.noMatch
} }
consumer.consume("true", booleanInfoClassifier, SmartCompletionItemPriority.TRUE) { consumer.consume("true", booleanInfoMatcher, SmartCompletionItemPriority.TRUE) {
LookupElementBuilder.create(KeywordLookupObject(), "true").bold() LookupElementBuilder.create(KeywordLookupObject(), "true").bold()
} }
consumer.consume("false", booleanInfoClassifier, SmartCompletionItemPriority.FALSE) { consumer.consume("false", booleanInfoMatcher, SmartCompletionItemPriority.FALSE) {
LookupElementBuilder.create(KeywordLookupObject(), "false").bold() LookupElementBuilder.create(KeywordLookupObject(), "false").bold()
} }
val nullClassifier = { info: ExpectedInfo -> val nullMatcher = { info: ExpectedInfo ->
if (info.fuzzyType != null && info.fuzzyType!!.type.isMarkedNullable()) if (info.fuzzyType != null && info.fuzzyType!!.type.isMarkedNullable())
ExpectedInfoClassification.match(TypeSubstitutor.EMPTY) ExpectedInfoMatch.match(TypeSubstitutor.EMPTY)
else else
ExpectedInfoClassification.noMatch ExpectedInfoMatch.noMatch
} }
consumer.consume("null", nullClassifier, SmartCompletionItemPriority.NULL) { consumer.consume("null", nullMatcher, SmartCompletionItemPriority.NULL) {
LookupElementBuilder.create(KeywordLookupObject(), "null").bold() LookupElementBuilder.create(KeywordLookupObject(), "null").bold()
} }
} }
@@ -87,8 +87,8 @@ object KeywordValues {
val kClassDescriptor = resolutionFacade.getFrontendService(ReflectionTypes::class.java).kClass val kClassDescriptor = resolutionFacade.getFrontendService(ReflectionTypes::class.java).kClass
val classLiteralType = JetTypeImpl.create(Annotations.EMPTY, kClassDescriptor, false, listOf(TypeProjectionImpl(qualifierType))) val classLiteralType = JetTypeImpl.create(Annotations.EMPTY, kClassDescriptor, false, listOf(TypeProjectionImpl(qualifierType)))
val kClassTypes = listOf(FuzzyType(classLiteralType, emptyList())) val kClassTypes = listOf(FuzzyType(classLiteralType, emptyList()))
val kClassClassifier = { info: ExpectedInfo -> kClassTypes.classifyExpectedInfo(info) } val kClassMatcher = { info: ExpectedInfo -> kClassTypes.matchExpectedInfo(info) }
consumer.consume("class", kClassClassifier, SmartCompletionItemPriority.CLASS_LITERAL) { consumer.consume("class", kClassMatcher, SmartCompletionItemPriority.CLASS_LITERAL) {
LookupElementBuilder.create(KeywordLookupObject(), "class").bold() LookupElementBuilder.create(KeywordLookupObject(), "class").bold()
} }
@@ -99,8 +99,8 @@ object KeywordValues {
if (javaLangClassDescriptor != null) { if (javaLangClassDescriptor != null) {
val javaLangClassType = JetTypeImpl.create(Annotations.EMPTY, javaLangClassDescriptor, false, listOf(TypeProjectionImpl(qualifierType))) val javaLangClassType = JetTypeImpl.create(Annotations.EMPTY, javaLangClassDescriptor, false, listOf(TypeProjectionImpl(qualifierType)))
val javaClassTypes = listOf(FuzzyType(javaLangClassType, emptyList())) val javaClassTypes = listOf(FuzzyType(javaLangClassType, emptyList()))
val javaClassClassifier = { info: ExpectedInfo -> javaClassTypes.classifyExpectedInfo(info) } val javaClassMatcher = { info: ExpectedInfo -> javaClassTypes.matchExpectedInfo(info) }
consumer.consume("class", javaClassClassifier, SmartCompletionItemPriority.CLASS_LITERAL) { consumer.consume("class", javaClassMatcher, SmartCompletionItemPriority.CLASS_LITERAL) {
LookupElementBuilder.create(KeywordLookupObject(), "class.java") LookupElementBuilder.create(KeywordLookupObject(), "class.java")
.withPresentableText("class") .withPresentableText("class")
.withTailText(".java") .withTailText(".java")
@@ -233,18 +233,18 @@ class SmartCompletionInBasicWeigher(
if (fuzzyTypes.isEmpty()) return NO_MATCH_WEIGHT if (fuzzyTypes.isEmpty()) return NO_MATCH_WEIGHT
val classified: Collection<Pair<ExpectedInfo, ExpectedInfoClassification>> = expectedInfos.map { it to fuzzyTypes.classifyExpectedInfo(it) } val matched: Collection<Pair<ExpectedInfo, ExpectedInfoMatch>> = expectedInfos.map { it to fuzzyTypes.matchExpectedInfo(it) }
if (classified.all { it.second == ExpectedInfoClassification.noMatch }) return NO_MATCH_WEIGHT if (matched.all { it.second == ExpectedInfoMatch.noMatch }) return NO_MATCH_WEIGHT
val nameSimilarity = if (name != null) { val nameSimilarity = if (name != null) {
val matchingInfos = classified.filter { it.second != ExpectedInfoClassification.noMatch }.map { it.first } val matchingInfos = matched.filter { it.second != ExpectedInfoMatch.noMatch }.map { it.first }
calcNameSimilarity(name.asString(), matchingInfos) calcNameSimilarity(name.asString(), matchingInfos)
} }
else { else {
0 0
} }
return if (classified.any { it.second.isMatch() }) return if (matched.any { it.second.isMatch() })
fullMatchWeight(nameSimilarity) fullMatchWeight(nameSimilarity)
else else
ifNotNullMatchWeight(nameSimilarity) ifNotNullMatchWeight(nameSimilarity)
@@ -155,9 +155,9 @@ class SmartCompletion(
val result = SmartList<LookupElement>() val result = SmartList<LookupElement>()
val types = descriptor.fuzzyTypesForSmartCompletion(smartCastCalculator, callType, resolutionFacade) val types = descriptor.fuzzyTypesForSmartCompletion(smartCastCalculator, callType, resolutionFacade)
val infoClassifier = { expectedInfo: ExpectedInfo -> types.classifyExpectedInfo(expectedInfo) } val infoMatcher = { expectedInfo: ExpectedInfo -> types.matchExpectedInfo(expectedInfo) }
result.addLookupElements(descriptor, expectedInfos, infoClassifier, noNameSimilarityForReturnItself = callTypeAndReceiver is CallTypeAndReceiver.DEFAULT) { descriptor -> result.addLookupElements(descriptor, expectedInfos, infoMatcher, noNameSimilarityForReturnItself = callTypeAndReceiver is CallTypeAndReceiver.DEFAULT) { descriptor ->
lookupElementFactory.createLookupElementsInSmartCompletion(descriptor, bindingContext, true) lookupElementFactory.createLookupElementsInSmartCompletion(descriptor, bindingContext, true)
} }
@@ -180,8 +180,8 @@ class SmartCompletion(
if (!forBasicCompletion) { // basic completion adds keyword values on its own if (!forBasicCompletion) { // basic completion adds keyword values on its own
val keywordValueConsumer = object : KeywordValues.Consumer { val keywordValueConsumer = object : KeywordValues.Consumer {
override fun consume(lookupString: String, expectedInfoClassifier: (ExpectedInfo) -> ExpectedInfoClassification, priority: SmartCompletionItemPriority, factory: () -> LookupElement) { override fun consume(lookupString: String, expectedInfoMatcher: (ExpectedInfo) -> ExpectedInfoMatch, priority: SmartCompletionItemPriority, factory: () -> LookupElement) {
items.addLookupElements(null, expectedInfos, expectedInfoClassifier) { items.addLookupElements(null, expectedInfos, expectedInfoMatcher) {
val lookupElement = factory() val lookupElement = factory()
lookupElement.putUserData(SMART_COMPLETION_ITEM_PRIORITY_KEY, priority) lookupElement.putUserData(SMART_COMPLETION_ITEM_PRIORITY_KEY, priority)
listOf(lookupElement) listOf(lookupElement)
@@ -266,8 +266,8 @@ class SmartCompletion(
val items = thisExpressionItems(bindingContext, place, prefixMatcher.getPrefix(), resolutionFacade) val items = thisExpressionItems(bindingContext, place, prefixMatcher.getPrefix(), resolutionFacade)
for (item in items) { for (item in items) {
val types = smartCastCalculator.types(item.receiverParameter).map { FuzzyType(it, emptyList()) } val types = smartCastCalculator.types(item.receiverParameter).map { FuzzyType(it, emptyList()) }
val classifier = { expectedInfo: ExpectedInfo -> types.classifyExpectedInfo(expectedInfo) } val matcher = { expectedInfo: ExpectedInfo -> types.matchExpectedInfo(expectedInfo) }
addLookupElements(null, expectedInfos, classifier) { addLookupElements(null, expectedInfos, matcher) {
item.createLookupElement().assignSmartCompletionPriority(SmartCompletionItemPriority.THIS).singletonList() item.createLookupElement().assignSmartCompletionPriority(SmartCompletionItemPriority.THIS).singletonList()
} }
} }
@@ -69,19 +69,19 @@ class StaticMembers(
fun processMember(descriptor: DeclarationDescriptor) { fun processMember(descriptor: DeclarationDescriptor) {
if (descriptor is DeclarationDescriptorWithVisibility && !descriptor.isVisible(scope.getContainingDeclaration(), bindingContext, context)) return if (descriptor is DeclarationDescriptorWithVisibility && !descriptor.isVisible(scope.getContainingDeclaration(), bindingContext, context)) return
val classifier: (ExpectedInfo) -> ExpectedInfoClassification val matcher: (ExpectedInfo) -> ExpectedInfoMatch
if (descriptor is CallableDescriptor) { if (descriptor is CallableDescriptor) {
val returnType = descriptor.fuzzyReturnType() ?: return val returnType = descriptor.fuzzyReturnType() ?: return
classifier = { expectedInfo -> returnType.classifyExpectedInfo(expectedInfo) } matcher = { expectedInfo -> returnType.classifyExpectedInfo(expectedInfo) }
} }
else if (DescriptorUtils.isEnumEntry(descriptor) && !enumEntriesToSkip.contains(descriptor)) { else if (DescriptorUtils.isEnumEntry(descriptor) && !enumEntriesToSkip.contains(descriptor)) {
classifier = { ExpectedInfoClassification.match(TypeSubstitutor.EMPTY) } /* we do not need to check type of enum entry because it's taken from proper enum */ matcher = { ExpectedInfoMatch.match(TypeSubstitutor.EMPTY) } /* we do not need to check type of enum entry because it's taken from proper enum */
} }
else { else {
return return
} }
collection.addLookupElements(descriptor, expectedInfos, classifier) { collection.addLookupElements(descriptor, expectedInfos, matcher) {
descriptor -> createLookupElements(descriptor, classDescriptor) descriptor -> createLookupElements(descriptor, classDescriptor)
} }
} }
@@ -119,7 +119,7 @@ fun LookupElement.addTailAndNameSimilarity(
return lookupElement return lookupElement
} }
class ExpectedInfoClassification class ExpectedInfoMatch
private constructor( private constructor(
val substitutor: TypeSubstitutor?, val substitutor: TypeSubstitutor?,
val makeNotNullable: Boolean val makeNotNullable: Boolean
@@ -127,35 +127,35 @@ private constructor(
fun isMatch() = substitutor != null && !makeNotNullable fun isMatch() = substitutor != null && !makeNotNullable
companion object { companion object {
val noMatch = ExpectedInfoClassification(null, false) val noMatch = ExpectedInfoMatch(null, false)
fun match(substitutor: TypeSubstitutor) = ExpectedInfoClassification(substitutor, false) fun match(substitutor: TypeSubstitutor) = ExpectedInfoMatch(substitutor, false)
fun ifNotNullMatch(substitutor: TypeSubstitutor) = ExpectedInfoClassification(substitutor, true) fun ifNotNullMatch(substitutor: TypeSubstitutor) = ExpectedInfoMatch(substitutor, true)
} }
} }
fun Collection<FuzzyType>.classifyExpectedInfo(expectedInfo: ExpectedInfo): ExpectedInfoClassification { fun Collection<FuzzyType>.matchExpectedInfo(expectedInfo: ExpectedInfo): ExpectedInfoMatch {
val sequence = asSequence() val sequence = asSequence()
val substitutor = sequence.map { expectedInfo.matchingSubstitutor(it) }.firstOrNull() val substitutor = sequence.map { expectedInfo.matchingSubstitutor(it) }.firstOrNull()
if (substitutor != null) { if (substitutor != null) {
return ExpectedInfoClassification.match(substitutor) return ExpectedInfoMatch.match(substitutor)
} }
if (sequence.any { it.nullability() == TypeNullability.NULLABLE }) { if (sequence.any { it.nullability() == TypeNullability.NULLABLE }) {
val substitutor2 = sequence.map { expectedInfo.matchingSubstitutor(it.makeNotNullable()) }.firstOrNull() val substitutor2 = sequence.map { expectedInfo.matchingSubstitutor(it.makeNotNullable()) }.firstOrNull()
if (substitutor2 != null) { if (substitutor2 != null) {
return ExpectedInfoClassification.ifNotNullMatch(substitutor2) return ExpectedInfoMatch.ifNotNullMatch(substitutor2)
} }
} }
return ExpectedInfoClassification.noMatch return ExpectedInfoMatch.noMatch
} }
fun FuzzyType.classifyExpectedInfo(expectedInfo: ExpectedInfo) = listOf(this).classifyExpectedInfo(expectedInfo) fun FuzzyType.classifyExpectedInfo(expectedInfo: ExpectedInfo) = listOf(this).matchExpectedInfo(expectedInfo)
fun<TDescriptor: DeclarationDescriptor?> MutableCollection<LookupElement>.addLookupElements( fun<TDescriptor: DeclarationDescriptor?> MutableCollection<LookupElement>.addLookupElements(
descriptor: TDescriptor, descriptor: TDescriptor,
expectedInfos: Collection<ExpectedInfo>, expectedInfos: Collection<ExpectedInfo>,
infoClassifier: (ExpectedInfo) -> ExpectedInfoClassification, infoMatcher: (ExpectedInfo) -> ExpectedInfoMatch,
noNameSimilarityForReturnItself: Boolean = false, noNameSimilarityForReturnItself: Boolean = false,
lookupElementFactory: (TDescriptor) -> Collection<LookupElement> lookupElementFactory: (TDescriptor) -> Collection<LookupElement>
) { ) {
@@ -170,7 +170,7 @@ fun<TDescriptor: DeclarationDescriptor?> MutableCollection<LookupElement>.addLoo
val matchedInfos = HashMap<ItemData, MutableList<ExpectedInfo>>() val matchedInfos = HashMap<ItemData, MutableList<ExpectedInfo>>()
val makeNullableInfos = HashMap<ItemData, MutableList<ExpectedInfo>>() val makeNullableInfos = HashMap<ItemData, MutableList<ExpectedInfo>>()
for (info in expectedInfos) { for (info in expectedInfos) {
val classification = infoClassifier(info) val classification = infoMatcher(info)
if (classification.substitutor != null) { if (classification.substitutor != null) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val substitutedDescriptor = descriptor.substituteFixed(classification.substitutor) val substitutedDescriptor = descriptor.substituteFixed(classification.substitutor)