Rename getParameterTypeProjectionsFromFunctionType -> getValueParameterTypesFromFunctionType

Also add getValueParametersCountFromFunctionType which doesn't create a new
list every time but only returns the number of value parameters
This commit is contained in:
Alexander Udalov
2016-03-14 17:15:41 +03:00
parent 5b7115dc38
commit 63eb6712eb
8 changed files with 29 additions and 19 deletions
@@ -223,7 +223,7 @@ class FunctionDescriptorResolver(
private fun KotlinType.getValueParameters(owner: FunctionDescriptor): List<ValueParameterDescriptor>? = private fun KotlinType.getValueParameters(owner: FunctionDescriptor): List<ValueParameterDescriptor>? =
if (functionTypeExpected()) { if (functionTypeExpected()) {
createValueParametersFromFunctionType(owner, getParameterTypeProjectionsFromFunctionType(this)) createValueParametersFromFunctionType(owner, getValueParameterTypesFromFunctionType(this))
} }
else null else null
@@ -104,7 +104,13 @@ fun getReturnTypeFromFunctionType(type: KotlinType): KotlinType {
return type.arguments.last().type return type.arguments.last().type
} }
fun getParameterTypeProjectionsFromFunctionType(type: KotlinType): List<TypeProjection> { fun getValueParametersCountFromFunctionType(type: KotlinType): Int {
assert(type.isFunctionType) { "Not a function type: $type" }
// Function type arguments = receiver? + parameters + return-type
return type.arguments.size - (if (type.isExtensionFunctionType) 1 else 0) - 1
}
fun getValueParameterTypesFromFunctionType(type: KotlinType): List<TypeProjection> {
assert(type.isFunctionType) { "Not a function type: $type" } assert(type.isFunctionType) { "Not a function type: $type" }
val arguments = type.arguments val arguments = type.arguments
val first = if (type.isExtensionFunctionType) 1 else 0 val first = if (type.isExtensionFunctionType) 1 else 0
@@ -319,7 +319,7 @@ internal class DescriptorRendererImpl(
} }
append("(") append("(")
appendTypeProjections(getParameterTypeProjectionsFromFunctionType(type), this) appendTypeProjections(getValueParameterTypesFromFunctionType(type), this)
append(") ").append(arrow()).append(" ") append(") ").append(arrow()).append(" ")
append(renderNormalizedType(getReturnTypeFromFunctionType(type))) append(renderNormalizedType(getReturnTypeFromFunctionType(type)))
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.idea.completion
import com.intellij.codeInsight.completion.InsertHandler import com.intellij.codeInsight.completion.InsertHandler
import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElement
import org.jetbrains.kotlin.builtins.getParameterTypeProjectionsFromFunctionType
import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
import org.jetbrains.kotlin.builtins.getValueParametersCountFromFunctionType
import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.completion.handlers.* import org.jetbrains.kotlin.idea.completion.handlers.*
@@ -54,10 +54,12 @@ class InsertHandlerProvider(
if (callType != CallType.SUPER_MEMBERS) { // for super call we don't suggest to generate "super.foo { ... }" (seems to be non-typical use) if (callType != CallType.SUPER_MEMBERS) { // for super call we don't suggest to generate "super.foo { ... }" (seems to be non-typical use)
val parameterType = parameters.single().type val parameterType = parameters.single().type
if (parameterType.isFunctionType) { if (parameterType.isFunctionType) {
val parameterCount = getParameterTypeProjectionsFromFunctionType(parameterType).size if (getValueParametersCountFromFunctionType(parameterType) <= 1) {
if (parameterCount <= 1) {
// otherwise additional item with lambda template is to be added // otherwise additional item with lambda template is to be added
return KotlinFunctionInsertHandler.Normal(needTypeArguments, inputValueArguments = false, lambdaInfo = GenerateLambdaInfo(parameterType, false)) return KotlinFunctionInsertHandler.Normal(
needTypeArguments, inputValueArguments = false,
lambdaInfo = GenerateLambdaInfo(parameterType, false)
)
} }
} }
} }
@@ -98,7 +100,7 @@ class InsertHandlerProvider(
potentiallyInferred.add(descriptor) potentiallyInferred.add(descriptor)
} }
if (type.isFunctionType && getParameterTypeProjectionsFromFunctionType(type).size <= 1) { if (type.isFunctionType && getValueParametersCountFromFunctionType(type) <= 1) {
// do not rely on inference from input of function type with one or no arguments - use only return type of functional type // do not rely on inference from input of function type with one or no arguments - use only return type of functional type
addPotentiallyInferred(getReturnTypeFromFunctionType(type)) addPotentiallyInferred(getReturnTypeFromFunctionType(type))
return return
@@ -22,7 +22,7 @@ import com.intellij.codeInsight.lookup.LookupElementDecorator
import com.intellij.codeInsight.lookup.LookupElementPresentation import com.intellij.codeInsight.lookup.LookupElementPresentation
import com.intellij.codeInsight.lookup.impl.LookupCellRenderer import com.intellij.codeInsight.lookup.impl.LookupCellRenderer
import com.intellij.util.SmartList import com.intellij.util.SmartList
import org.jetbrains.kotlin.builtins.getParameterTypeProjectionsFromFunctionType import org.jetbrains.kotlin.builtins.getValueParametersCountFromFunctionType
import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.completion.handlers.GenerateLambdaInfo import org.jetbrains.kotlin.idea.completion.handlers.GenerateLambdaInfo
@@ -112,7 +112,7 @@ class LookupElementFactory(
val isSingleParameter = descriptor.valueParameters.size == 1 val isSingleParameter = descriptor.valueParameters.size == 1
val parameterType = lastParameter.type val parameterType = lastParameter.type
val functionParameterCount = getParameterTypeProjectionsFromFunctionType(parameterType).size val functionParameterCount = getValueParametersCountFromFunctionType(parameterType)
// we don't need special item inserting lambda for single functional parameter that does not need multiple arguments because the default item will be special in this case // we don't need special item inserting lambda for single functional parameter that does not need multiple arguments because the default item will be special in this case
if (!isSingleParameter || functionParameterCount > 1) { if (!isSingleParameter || functionParameterCount > 1) {
add(createFunctionCallElementWithLambda(descriptor, parameterType, functionParameterCount > 1, useReceiverTypes)) add(createFunctionCallElementWithLambda(descriptor, parameterType, functionParameterCount > 1, useReceiverTypes))
@@ -25,7 +25,8 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.builtins.getParameterTypeProjectionsFromFunctionType import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
import org.jetbrains.kotlin.builtins.getValueParametersCountFromFunctionType
import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.ExpectedInfos import org.jetbrains.kotlin.idea.core.ExpectedInfos
@@ -37,6 +38,7 @@ import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjection
fun insertLambdaTemplate(context: InsertionContext, placeholderRange: TextRange, lambdaType: KotlinType) { fun insertLambdaTemplate(context: InsertionContext, placeholderRange: TextRange, lambdaType: KotlinType) {
val explicitParameterTypes = needExplicitParameterTypes(context, placeholderRange, lambdaType) val explicitParameterTypes = needExplicitParameterTypes(context, placeholderRange, lambdaType)
@@ -88,8 +90,8 @@ private fun needExplicitParameterTypes(context: InsertionContext, placeholderRan
.toSet() .toSet()
if (functionTypes.size <= 1) return false if (functionTypes.size <= 1) return false
val lambdaParameterCount = getParameterTypeProjectionsFromFunctionType(lambdaType).size val lambdaParameterCount = getValueParametersCountFromFunctionType(lambdaType)
return functionTypes.filter { getParameterTypeProjectionsFromFunctionType(it).size == lambdaParameterCount }.size > 1 return functionTypes.filter { getValueParametersCountFromFunctionType(it) == lambdaParameterCount }.size > 1
} }
private fun buildTemplate(lambdaType: KotlinType, explicitParameterTypes: Boolean, project: Project): Template { private fun buildTemplate(lambdaType: KotlinType, explicitParameterTypes: Boolean, project: Project): Template {
@@ -128,5 +130,5 @@ private class ParameterNameExpression(val nameSuggestions: Array<String>) : Expr
= Array<LookupElement>(nameSuggestions.size, { LookupElementBuilder.create(nameSuggestions[it]) }) = Array<LookupElement>(nameSuggestions.size, { LookupElementBuilder.create(nameSuggestions[it]) })
} }
fun functionParameterTypes(functionType: KotlinType): List<KotlinType> fun functionParameterTypes(functionType: KotlinType): List<KotlinType> =
= getParameterTypeProjectionsFromFunctionType(functionType).map { it.type } getValueParameterTypesFromFunctionType(functionType).map(TypeProjection::getType)
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.idea.completion.smart
import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.builtins.getParameterTypeProjectionsFromFunctionType import org.jetbrains.kotlin.builtins.getValueParametersCountFromFunctionType
import org.jetbrains.kotlin.idea.completion.handlers.insertLambdaTemplate import org.jetbrains.kotlin.idea.completion.handlers.insertLambdaTemplate
import org.jetbrains.kotlin.idea.completion.handlers.lambdaPresentation import org.jetbrains.kotlin.idea.completion.handlers.lambdaPresentation
import org.jetbrains.kotlin.idea.completion.suppressAutoInsertion import org.jetbrains.kotlin.idea.completion.suppressAutoInsertion
@@ -43,7 +43,7 @@ object LambdaItems {
.toSet() .toSet()
val singleType = if (distinctTypes.size == 1) distinctTypes.single() else null val singleType = if (distinctTypes.size == 1) distinctTypes.single() else null
val singleSignatureLength = singleType?.let { getParameterTypeProjectionsFromFunctionType(it).size } val singleSignatureLength = singleType?.let(::getValueParametersCountFromFunctionType)
val offerNoParametersLambda = singleSignatureLength == 0 || singleSignatureLength == 1 val offerNoParametersLambda = singleSignatureLength == 0 || singleSignatureLength == 1
if (offerNoParametersLambda) { if (offerNoParametersLambda) {
val lookupElement = LookupElementBuilder.create(lambdaPresentation(null)) val lookupElement = LookupElementBuilder.create(lambdaPresentation(null))
@@ -17,7 +17,7 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import com.intellij.util.SmartList import com.intellij.util.SmartList
import org.jetbrains.kotlin.builtins.getParameterTypeProjectionsFromFunctionType import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.builtins.isFunctionType
@@ -55,7 +55,7 @@ object CreateFunctionFromCallableReferenceActionFactory : CreateCallableMemberFr
add(ParameterInfo(TypeInfo(expectedReceiverType, Variance.IN_VARIANCE))) add(ParameterInfo(TypeInfo(expectedReceiverType, Variance.IN_VARIANCE)))
} }
getParameterTypeProjectionsFromFunctionType(it) getValueParameterTypesFromFunctionType(it)
.let { .let {
if (actualReceiverTypeRef != null && expectedReceiverType == null && it.isNotEmpty()) if (actualReceiverTypeRef != null && expectedReceiverType == null && it.isNotEmpty())
it.subList(1, it.size) it.subList(1, it.size)