Smart completion: ExpectedTypeInfo renamed to ExpectedInfo
This commit is contained in:
+10
-10
@@ -24,19 +24,19 @@ import java.util.HashSet
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
|
||||
|
||||
class ExpectedTypes(val bindingContext: BindingContext, val moduleDescriptor: ModuleDescriptor) {
|
||||
public fun calculate(expressionWithType: JetExpression): Collection<ExpectedTypeInfo>? {
|
||||
val expectedTypes = calculateForArgument(expressionWithType)
|
||||
if (expectedTypes != null) {
|
||||
return expectedTypes
|
||||
class ExpectedInfos(val bindingContext: BindingContext, val moduleDescriptor: ModuleDescriptor) {
|
||||
public fun calculate(expressionWithType: JetExpression): Collection<ExpectedInfo>? {
|
||||
val expectedInfos = calculateForArgument(expressionWithType)
|
||||
if (expectedInfos != null) {
|
||||
return expectedInfos
|
||||
}
|
||||
else {
|
||||
val expectedType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, expressionWithType] ?: return null
|
||||
return listOf(ExpectedTypeInfo(expectedType, null))
|
||||
return listOf(ExpectedInfo(expectedType, null))
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateForArgument(expressionWithType: JetExpression): Collection<ExpectedTypeInfo>? {
|
||||
private fun calculateForArgument(expressionWithType: JetExpression): Collection<ExpectedInfo>? {
|
||||
val argument = expressionWithType.getParent() as? JetValueArgument ?: return null
|
||||
if (argument.isNamed()) return null //TODO - support named arguments (also do not forget to check for presence of named arguments before)
|
||||
val argumentList = argument.getParent() as JetValueArgumentList
|
||||
@@ -74,14 +74,14 @@ class ExpectedTypes(val bindingContext: BindingContext, val moduleDescriptor: Mo
|
||||
val callResolver = InjectorForMacros(expressionWithType.getProject(), moduleDescriptor).getCallResolver()!!
|
||||
val results: OverloadResolutionResults<FunctionDescriptor> = callResolver.resolveFunctionCall(callResolutionContext)
|
||||
|
||||
val expectedTypes = HashSet<ExpectedTypeInfo>()
|
||||
val expectedInfos = HashSet<ExpectedInfo>()
|
||||
for (candidate: ResolvedCall<FunctionDescriptor> in results.getAllCandidates()!!) {
|
||||
val parameters = candidate.getResultingDescriptor().getValueParameters()
|
||||
if (parameters.size <= argumentIndex) continue
|
||||
val parameterDescriptor = parameters[argumentIndex]
|
||||
val tail = if (argumentIndex == parameters.size - 1) Tail.PARENTHESIS else Tail.COMMA
|
||||
expectedTypes.add(ExpectedTypeInfo(parameterDescriptor.getType(), tail))
|
||||
expectedInfos.add(ExpectedInfo(parameterDescriptor.getType(), tail))
|
||||
}
|
||||
return expectedTypes
|
||||
return expectedInfos
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,8 @@ import org.jetbrains.jet.plugin.refactoring.JetNameSuggester
|
||||
import com.intellij.openapi.project.Project
|
||||
|
||||
class LambdaItems(val project: Project) {
|
||||
public fun addToCollection(collection: MutableCollection<LookupElement>, functionExpectedTypes: Collection<ExpectedTypeInfo>) {
|
||||
val distinctTypes = functionExpectedTypes.map { it.`type` }.toSet()
|
||||
public fun addToCollection(collection: MutableCollection<LookupElement>, functionExpectedInfos: Collection<ExpectedInfo>) {
|
||||
val distinctTypes = functionExpectedInfos.map { it.`type` }.toSet()
|
||||
|
||||
fun createLookupElement(lookupString: String, textBeforeCaret: String, textAfterCaret: String, shortenRefs: Boolean)
|
||||
= LookupElementBuilder.create(lookupString)
|
||||
@@ -23,7 +23,7 @@ class LambdaItems(val project: Project) {
|
||||
val offerNoParametersLambda = singleSignatureLength == 0 || singleSignatureLength == 1
|
||||
if (offerNoParametersLambda) {
|
||||
val lookupElement = createLookupElement("{...}", "{ ", " }", shortenRefs = false)
|
||||
collection.add(addTailToLookupElement(lookupElement, functionExpectedTypes))
|
||||
collection.add(addTailToLookupElement(lookupElement, functionExpectedInfos))
|
||||
}
|
||||
|
||||
if (singleSignatureLength != 0) {
|
||||
@@ -53,7 +53,7 @@ class LambdaItems(val project: Project) {
|
||||
|
||||
val lookupString = "{ ${wrap(parametersPresentation)} -> ... }"
|
||||
val lookupElement = createLookupElement(lookupString, "{ ${wrap(parametersText)} -> ", " }", shortenRefs = true)
|
||||
collection.add(addTailToLookupElement(lookupElement, functionExpectedTypes.filter { it.`type` == functionType }))
|
||||
collection.add(addTailToLookupElement(lookupElement, functionExpectedInfos.filter { it.`type` == functionType }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ enum class Tail {
|
||||
PARENTHESIS
|
||||
}
|
||||
|
||||
data class ExpectedTypeInfo(val `type`: JetType, val tail: Tail?)
|
||||
data class ExpectedInfo(val `type`: JetType, val tail: Tail?)
|
||||
|
||||
class SmartCompletion(val expression: JetSimpleNameExpression,
|
||||
val resolveSession: ResolveSessionForBodies,
|
||||
@@ -40,9 +40,9 @@ class SmartCompletion(val expression: JetSimpleNameExpression,
|
||||
receiver = null
|
||||
}
|
||||
|
||||
val allExpectedTypes = ExpectedTypes(bindingContext, moduleDescriptor).calculate(expressionWithType) ?: return null
|
||||
val expectedTypes = allExpectedTypes.filter { !it.`type`.isError() }
|
||||
if (expectedTypes.isEmpty()) return null
|
||||
val allExpectedInfos = ExpectedInfos(bindingContext, moduleDescriptor).calculate(expressionWithType) ?: return null
|
||||
val expectedInfos = allExpectedInfos.filter { !it.`type`.isError() }
|
||||
if (expectedInfos.isEmpty()) return null
|
||||
|
||||
val result = ArrayList<LookupElement>()
|
||||
|
||||
@@ -50,32 +50,32 @@ class SmartCompletion(val expression: JetSimpleNameExpression,
|
||||
|
||||
val itemsToSkip = calcItemsToSkip(expressionWithType)
|
||||
|
||||
val functionExpectedTypes = expectedTypes.filter { KotlinBuiltIns.getInstance().isExactFunctionOrExtensionFunctionType(it.`type`) }
|
||||
val functionExpectedInfos = expectedInfos.filter { KotlinBuiltIns.getInstance().isExactFunctionOrExtensionFunctionType(it.`type`) }
|
||||
|
||||
for (descriptor in referenceVariants) {
|
||||
if (itemsToSkip.contains(descriptor)) continue
|
||||
|
||||
val matchedExpectedTypes = expectedTypes.filter { expectedType ->
|
||||
typesWithAutoCasts(descriptor).any { it.isSubtypeOf(expectedType.`type`) }
|
||||
val matchedExpectedInfos = expectedInfos.filter { expectedInfo ->
|
||||
typesWithAutoCasts(descriptor).any { it.isSubtypeOf(expectedInfo.`type`) }
|
||||
}
|
||||
if (matchedExpectedTypes.isNotEmpty()) {
|
||||
if (matchedExpectedInfos.isNotEmpty()) {
|
||||
val lookupElement = DescriptorLookupConverter.createLookupElement(resolveSession, bindingContext, descriptor)
|
||||
result.add(addTailToLookupElement(lookupElement, matchedExpectedTypes))
|
||||
result.add(addTailToLookupElement(lookupElement, matchedExpectedInfos))
|
||||
}
|
||||
|
||||
if (receiver == null) {
|
||||
toFunctionReferenceLookupElement(descriptor, functionExpectedTypes)?.let { result.add(it) }
|
||||
toFunctionReferenceLookupElement(descriptor, functionExpectedInfos)?.let { result.add(it) }
|
||||
}
|
||||
}
|
||||
|
||||
if (receiver == null) {
|
||||
TypeInstantiationItems(bindingContext, resolveSession).addToCollection(result, expectedTypes)
|
||||
TypeInstantiationItems(bindingContext, resolveSession).addToCollection(result, expectedInfos)
|
||||
|
||||
StaticMembers(bindingContext, resolveSession).addToCollection(result, expectedTypes, expression)
|
||||
StaticMembers(bindingContext, resolveSession).addToCollection(result, expectedInfos, expression)
|
||||
|
||||
ThisItems(bindingContext).addToCollection(result, expressionWithType, expectedTypes)
|
||||
ThisItems(bindingContext).addToCollection(result, expressionWithType, expectedInfos)
|
||||
|
||||
LambdaItems(project).addToCollection(result, functionExpectedTypes)
|
||||
LambdaItems(project).addToCollection(result, functionExpectedInfos)
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -104,15 +104,15 @@ class SmartCompletion(val expression: JetSimpleNameExpression,
|
||||
}
|
||||
|
||||
private fun toFunctionReferenceLookupElement(descriptor: DeclarationDescriptor,
|
||||
functionExpectedTypes: Collection<ExpectedTypeInfo>): LookupElement? {
|
||||
if (functionExpectedTypes.isEmpty()) return null
|
||||
functionExpectedInfos: Collection<ExpectedInfo>): LookupElement? {
|
||||
if (functionExpectedInfos.isEmpty()) return null
|
||||
|
||||
fun toLookupElement(descriptor: FunctionDescriptor): LookupElement? {
|
||||
val functionType = functionType(descriptor)
|
||||
if (functionType == null) return null
|
||||
|
||||
val matchedExpectedTypes = functionExpectedTypes.filter { functionType.isSubtypeOf(it.`type`) }
|
||||
if (matchedExpectedTypes.isEmpty()) return null
|
||||
val matchedExpectedInfos = functionExpectedInfos.filter { functionType.isSubtypeOf(it.`type`) }
|
||||
if (matchedExpectedInfos.isEmpty()) return null
|
||||
|
||||
var lookupElement = DescriptorLookupConverter.createLookupElement(resolveSession, bindingContext, descriptor)
|
||||
val text = "::" + (if (descriptor is ConstructorDescriptor) descriptor.getContainingDeclaration().getName() else descriptor.getName())
|
||||
@@ -129,7 +129,7 @@ class SmartCompletion(val expression: JetSimpleNameExpression,
|
||||
}
|
||||
}
|
||||
|
||||
return addTailToLookupElement(lookupElement, matchedExpectedTypes)
|
||||
return addTailToLookupElement(lookupElement, matchedExpectedInfos)
|
||||
}
|
||||
|
||||
if (descriptor is SimpleFunctionDescriptor) {
|
||||
|
||||
@@ -24,14 +24,14 @@ import org.jetbrains.jet.lang.psi.JetExpression
|
||||
|
||||
// adds java static members, enum members and members from class object
|
||||
class StaticMembers(val bindingContext: BindingContext, val resolveSession: ResolveSessionForBodies) {
|
||||
public fun addToCollection(collection: MutableCollection<LookupElement>, expectedTypes: Collection<ExpectedTypeInfo>, context: JetExpression) {
|
||||
public fun addToCollection(collection: MutableCollection<LookupElement>, expectedInfos: Collection<ExpectedInfo>, context: JetExpression) {
|
||||
val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, context]
|
||||
if (scope == null) return
|
||||
|
||||
val expectedTypesByClass = expectedTypes.groupBy { TypeUtils.getClassDescriptor(it.`type`) }
|
||||
for ((classDescriptor, expectedTypesForClass) in expectedTypesByClass) {
|
||||
val expectedInfosByClass = expectedInfos.groupBy { TypeUtils.getClassDescriptor(it.`type`) }
|
||||
for ((classDescriptor, expectedInfosForClass) in expectedInfosByClass) {
|
||||
if (classDescriptor != null && !classDescriptor.getName().isSpecial()) {
|
||||
addToCollection(collection, classDescriptor, expectedTypesForClass, scope)
|
||||
addToCollection(collection, classDescriptor, expectedInfosForClass, scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,21 +39,21 @@ class StaticMembers(val bindingContext: BindingContext, val resolveSession: Reso
|
||||
private fun addToCollection(
|
||||
collection: MutableCollection<LookupElement>,
|
||||
classDescriptor: ClassDescriptor,
|
||||
expectedTypes: Collection<ExpectedTypeInfo>,
|
||||
expectedInfos: Collection<ExpectedInfo>,
|
||||
scope: JetScope) {
|
||||
|
||||
fun processMember(descriptor: DeclarationDescriptor) {
|
||||
if (descriptor is DeclarationDescriptorWithVisibility && !Visibilities.isVisible(descriptor, scope.getContainingDeclaration())) return
|
||||
|
||||
val matchedExpectedTypes = expectedTypes.filter {
|
||||
expectedType ->
|
||||
descriptor is CallableDescriptor && descriptor.getReturnType()?.let { it.isSubtypeOf(expectedType.`type`) } ?: false
|
||||
val matchedExpectedInfos = expectedInfos.filter {
|
||||
expectedInfo ->
|
||||
descriptor is CallableDescriptor && descriptor.getReturnType()?.let { it.isSubtypeOf(expectedInfo.`type`) } ?: false
|
||||
|| descriptor is ClassDescriptor && descriptor.getKind() == ClassKind.ENUM_ENTRY
|
||||
}
|
||||
if (matchedExpectedTypes.isEmpty()) return
|
||||
if (matchedExpectedInfos.isEmpty()) return
|
||||
|
||||
val lookupElement = createLookupElement(descriptor, classDescriptor)
|
||||
collection.add(addTailToLookupElement(lookupElement, matchedExpectedTypes))
|
||||
collection.add(addTailToLookupElement(lookupElement, matchedExpectedInfos))
|
||||
}
|
||||
|
||||
if (classDescriptor is JavaClassDescriptor) {
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
|
||||
class ThisItems(val bindingContext: BindingContext) {
|
||||
public fun addToCollection(collection: MutableCollection<LookupElement>, context: JetExpression, expectedTypes: Collection<ExpectedTypeInfo>) {
|
||||
public fun addToCollection(collection: MutableCollection<LookupElement>, context: JetExpression, expectedInfos: Collection<ExpectedInfo>) {
|
||||
val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, context]
|
||||
if (scope == null) return
|
||||
|
||||
@@ -27,14 +27,14 @@ class ThisItems(val bindingContext: BindingContext) {
|
||||
for (i in 0..receivers.size - 1) {
|
||||
val receiver = receivers[i]
|
||||
val thisType = receiver.getType()
|
||||
val matchedExpectedTypes = expectedTypes.filter { thisType.isSubtypeOf(it.`type`) }
|
||||
if (matchedExpectedTypes.notEmpty) {
|
||||
val matchedExpectedInfos = expectedInfos.filter { thisType.isSubtypeOf(it.`type`) }
|
||||
if (matchedExpectedInfos.notEmpty) {
|
||||
//TODO: use this code when KT-4258 fixed
|
||||
//val expressionText = if (i == 0) "this" else "this@" + (thisQualifierName(receiver, bindingContext) ?: continue)
|
||||
val qualifier = if (i == 0) null else thisQualifierName(receiver) ?: continue
|
||||
val expressionText = if (qualifier == null) "this" else "this@" + qualifier
|
||||
val lookupElement = LookupElementBuilder.create(expressionText).withTypeText(DescriptorRenderer.TEXT.renderType(thisType))
|
||||
collection.add(addTailToLookupElement(lookupElement, matchedExpectedTypes))
|
||||
collection.add(addTailToLookupElement(lookupElement, matchedExpectedInfos))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
|
||||
|
||||
class TypeInstantiationItems(val bindingContext: BindingContext, val resolveSession: ResolveSessionForBodies) {
|
||||
public fun addToCollection(collection: MutableCollection<LookupElement>, expectedTypes: Collection<ExpectedTypeInfo>) {
|
||||
val expectedTypesGrouped: Map<JetType, List<ExpectedTypeInfo>> = expectedTypes.groupBy { TypeUtils.makeNotNullable(it.`type`) }
|
||||
for ((jetType, types) in expectedTypesGrouped) {
|
||||
public fun addToCollection(collection: MutableCollection<LookupElement>, expectedInfos: Collection<ExpectedInfo>) {
|
||||
val expectedInfosGrouped: Map<JetType, List<ExpectedInfo>> = expectedInfos.groupBy { TypeUtils.makeNotNullable(it.`type`) }
|
||||
for ((jetType, types) in expectedInfosGrouped) {
|
||||
val tail = mergeTails(types.map { it.tail })
|
||||
addToCollection(collection, jetType, tail)
|
||||
}
|
||||
|
||||
@@ -64,8 +64,8 @@ fun addTailToLookupElement(lookupElement: LookupElement, tail: Tail?): LookupEle
|
||||
}
|
||||
}
|
||||
|
||||
fun addTailToLookupElement(lookupElement: LookupElement, matchedExpectedTypes: Collection<ExpectedTypeInfo>): LookupElement
|
||||
= addTailToLookupElement(lookupElement, mergeTails(matchedExpectedTypes.map { it.tail }))
|
||||
fun addTailToLookupElement(lookupElement: LookupElement, matchedExpectedInfos: Collection<ExpectedInfo>): LookupElement
|
||||
= addTailToLookupElement(lookupElement, mergeTails(matchedExpectedInfos.map { it.tail }))
|
||||
|
||||
fun LookupElement.suppressAutoInsertion() = AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(this)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user