From f98cb74d53418a099f5923a0952359d08b8c4d00 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Thu, 30 Jul 2015 19:21:55 +0300 Subject: [PATCH] Make HeuristicSignatures an IDE service --- .../kotlin/idea/completion/ExpectedInfos.kt | 6 +- .../idea/completion/HeuristicSignatures.kt | 65 ++++++++++--------- .../smart/TypesWithContainsDetector.kt | 8 +-- 3 files changed, 41 insertions(+), 38 deletions(-) diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt index 1d151cbd8f0..be2510b0966 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.getService import org.jetbrains.kotlin.idea.completion.smart.TypesWithContainsDetector import org.jetbrains.kotlin.idea.core.IterableTypesDetection import org.jetbrains.kotlin.idea.core.IterableTypesDetector +import org.jetbrains.kotlin.idea.caches.resolve.ideService import org.jetbrains.kotlin.idea.core.mapArgumentsToParameters import org.jetbrains.kotlin.idea.util.FuzzyType import org.jetbrains.kotlin.idea.util.fuzzyReturnType @@ -319,7 +320,8 @@ class ExpectedInfos( if (alreadyHasStar) continue val parameterType = if (useHeuristicSignatures) - HeuristicSignatures.correctedParameterType(descriptor, parameter, moduleDescriptor, project) ?: parameter.getType() + resolutionFacade.ideService(moduleDescriptor). + correctedParameterType(descriptor, parameter) ?: parameter.getType() else parameter.getType() @@ -524,7 +526,7 @@ class ExpectedInfos( val leftOperandType = binaryExpression.left?.let { bindingContext.getType(it) } ?: return null val scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, expressionWithType)!! - val detector = TypesWithContainsDetector(scope, leftOperandType, binaryExpression.project, moduleDescriptor) + val detector = TypesWithContainsDetector(scope, leftOperandType, resolutionFacade.ideService(binaryExpression)) val byTypeFilter = object : ByTypeFilter { override fun matchingSubstitutor(descriptorType: FuzzyType): TypeSubstitutor? { diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/HeuristicSignatures.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/HeuristicSignatures.kt index c2ee55d281c..dbd6bc5c3c4 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/HeuristicSignatures.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/HeuristicSignatures.kt @@ -34,43 +34,23 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.types.* import java.util.HashMap -public object HeuristicSignatures { - private val signatures = HashMap, List>() - - init { - registerSignature("kotlin.Collection", "contains", "E") - registerSignature("kotlin.Collection", "containsAll", "kotlin.Collection") - registerSignature("kotlin.MutableCollection", "remove", "E") - registerSignature("kotlin.MutableCollection", "removeAll", "kotlin.Collection") - registerSignature("kotlin.MutableCollection", "retainAll", "kotlin.Collection") - registerSignature("kotlin.List", "indexOf", "E") - registerSignature("kotlin.List", "lastIndexOf", "E") - registerSignature("kotlin.Map", "get", "K") - registerSignature("kotlin.Map", "containsKey", "K") - registerSignature("kotlin.Map", "containsValue", "V") - registerSignature("kotlin.MutableMap", "remove", "K") - } - - private fun registerSignature( - classFqName: String, - name: String, - vararg parameterTypes: String) { - signatures[FqName(classFqName) to Name.identifier(name)] = parameterTypes.toList() - } - - public fun correctedParameterType(function: FunctionDescriptor, parameter: ValueParameterDescriptor, moduleDescriptor: ModuleDescriptor, project: Project): JetType? { +public class HeuristicSignatures( + private val moduleDescriptor: ModuleDescriptor, + private val project: Project +) { + public fun correctedParameterType(function: FunctionDescriptor, parameter: ValueParameterDescriptor): JetType? { val parameterIndex = function.getValueParameters().indexOf(parameter) assert(parameterIndex >= 0) - return correctedParameterType(function, parameterIndex, moduleDescriptor, project) + return correctedParameterType(function, parameterIndex) } - private fun correctedParameterType(function: FunctionDescriptor, parameterIndex: Int, moduleDescriptor: ModuleDescriptor, project: Project): JetType? { + private fun correctedParameterType(function: FunctionDescriptor, parameterIndex: Int): JetType? { val ownerType = function.getDispatchReceiverParameter()?.getType() ?: return null val superFunctions = function.getOverriddenDescriptors() if (superFunctions.isNotEmpty()) { for (superFunction in superFunctions) { - val correctedType = correctedParameterType(superFunction, parameterIndex, moduleDescriptor, project) ?: continue + val correctedType = correctedParameterType(superFunction, parameterIndex) ?: continue val typeSubstitutor = SubstitutionUtils.buildDeepSubstitutor(ownerType) return typeSubstitutor.safeSubstitute(correctedType, Variance.INVARIANT) } @@ -84,14 +64,14 @@ public object HeuristicSignatures { val typeStr = parameterTypes[parameterIndex] val typeParameters = ownerClass.getTypeConstructor().getParameters() - val type = typeFromText(typeStr, typeParameters, moduleDescriptor, project) + val type = typeFromText(typeStr, typeParameters) val substitutor = IndexedParametersSubstitution(ownerClass.typeConstructor, ownerType.arguments).buildSubstitutor() return substitutor.substitute(type, Variance.INVARIANT) } } - private fun typeFromText(text: String, typeParameters: Collection, moduleDescriptor: ModuleDescriptor, project: Project): JetType { + private fun typeFromText(text: String, typeParameters: Collection): JetType { val typeRef = JetPsiFactory(project).createType(text) val container = createContainerForMacros(project, moduleDescriptor) val rootPackagesScope = SubpackagesScope(moduleDescriptor, FqName.ROOT) @@ -107,4 +87,29 @@ public object HeuristicSignatures { override fun getClassifier(name: Name, location: LookupLocation) = paramsByName[name] } + + companion object { + private val signatures = HashMap, List>() + + init { + registerSignature("kotlin.Collection", "contains", "E") + registerSignature("kotlin.Collection", "containsAll", "kotlin.Collection") + registerSignature("kotlin.MutableCollection", "remove", "E") + registerSignature("kotlin.MutableCollection", "removeAll", "kotlin.Collection") + registerSignature("kotlin.MutableCollection", "retainAll", "kotlin.Collection") + registerSignature("kotlin.List", "indexOf", "E") + registerSignature("kotlin.List", "lastIndexOf", "E") + registerSignature("kotlin.Map", "get", "K") + registerSignature("kotlin.Map", "containsKey", "K") + registerSignature("kotlin.Map", "containsValue", "V") + registerSignature("kotlin.MutableMap", "remove", "K") + } + + private fun registerSignature( + classFqName: String, + name: String, + vararg parameterTypes: String) { + signatures[FqName(classFqName) to Name.identifier(name)] = parameterTypes.toList() + } + } } diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/TypesWithContainsDetector.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/TypesWithContainsDetector.kt index 723518777bd..4152ab7d193 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/TypesWithContainsDetector.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/TypesWithContainsDetector.kt @@ -16,10 +16,8 @@ package org.jetbrains.kotlin.idea.completion.smart -import com.intellij.openapi.project.Project import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.idea.completion.HeuristicSignatures import org.jetbrains.kotlin.idea.util.FuzzyType @@ -35,10 +33,8 @@ import java.util.HashMap class TypesWithContainsDetector( private val scope: JetScope, private val argumentType: JetType, - private val project: Project, - private val moduleDescriptor: ModuleDescriptor + private val heuristicSignatures: HeuristicSignatures ) { - private val cache = HashMap() private val containsName = Name.identifier("contains") private val booleanType = KotlinBuiltIns.getInstance().getBooleanType() @@ -60,7 +56,7 @@ class TypesWithContainsDetector( private fun isGoodContainsFunction(function: FunctionDescriptor, freeTypeParams: Collection): Boolean { if (!TypeUtils.equalTypes(function.getReturnType()!!, booleanType)) return false val parameter = function.getValueParameters().singleOrNull() ?: return false - val parameterType = HeuristicSignatures.correctedParameterType(function, parameter, moduleDescriptor, project) ?: parameter.getType() + val parameterType = heuristicSignatures.correctedParameterType(function, parameter) ?: parameter.getType() val fuzzyParameterType = FuzzyType(parameterType, function.getTypeParameters() + freeTypeParams) return fuzzyParameterType.checkIsSuperTypeOf(argumentType) != null }