Make HeuristicSignatures an IDE service
This commit is contained in:
@@ -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<HeuristicSignatures>(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<HeuristicSignatures>(binaryExpression))
|
||||
|
||||
val byTypeFilter = object : ByTypeFilter {
|
||||
override fun matchingSubstitutor(descriptorType: FuzzyType): TypeSubstitutor? {
|
||||
|
||||
+35
-30
@@ -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<Pair<FqName, Name>, List<String>>()
|
||||
|
||||
init {
|
||||
registerSignature("kotlin.Collection", "contains", "E")
|
||||
registerSignature("kotlin.Collection", "containsAll", "kotlin.Collection<E>")
|
||||
registerSignature("kotlin.MutableCollection", "remove", "E")
|
||||
registerSignature("kotlin.MutableCollection", "removeAll", "kotlin.Collection<E>")
|
||||
registerSignature("kotlin.MutableCollection", "retainAll", "kotlin.Collection<E>")
|
||||
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<TypeParameterDescriptor>, moduleDescriptor: ModuleDescriptor, project: Project): JetType {
|
||||
private fun typeFromText(text: String, typeParameters: Collection<TypeParameterDescriptor>): 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<Pair<FqName, Name>, List<String>>()
|
||||
|
||||
init {
|
||||
registerSignature("kotlin.Collection", "contains", "E")
|
||||
registerSignature("kotlin.Collection", "containsAll", "kotlin.Collection<E>")
|
||||
registerSignature("kotlin.MutableCollection", "remove", "E")
|
||||
registerSignature("kotlin.MutableCollection", "removeAll", "kotlin.Collection<E>")
|
||||
registerSignature("kotlin.MutableCollection", "retainAll", "kotlin.Collection<E>")
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-6
@@ -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<FuzzyType, Boolean>()
|
||||
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<TypeParameterDescriptor>): 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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user