No "{...}" in presentation for functions in completion of imports and callable references

This commit is contained in:
Valentin Kipyatkov
2015-10-01 21:14:04 +03:00
parent 08335a2ac9
commit e562c019f9
9 changed files with 192 additions and 166 deletions
@@ -151,7 +151,7 @@ class BasicLookupElementFactory(
val returnType = descriptor.getReturnType() val returnType = descriptor.getReturnType()
element = element.withTypeText(if (returnType != null) DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(returnType) else "") element = element.withTypeText(if (returnType != null) DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(returnType) else "")
val insertsLambda = (insertHandler as KotlinFunctionInsertHandler).lambdaInfo != null val insertsLambda = (insertHandler as? KotlinFunctionInsertHandler.Normal)?.lambdaInfo != null
if (insertsLambda) { if (insertsLambda) {
element = element.appendTailText(" {...} ", false) element = element.appendTailText(" {...} ", false)
} }
@@ -211,7 +211,7 @@ class BasicLookupElementFactory(
element = element.withStrikeoutness(true) element = element.withStrikeoutness(true)
} }
if (insertHandler is KotlinFunctionInsertHandler && insertHandler.lambdaInfo != null) { if ((insertHandler as? KotlinFunctionInsertHandler.Normal)?.lambdaInfo != null) {
element.putUserData(KotlinCompletionCharFilter.ACCEPT_OPENING_BRACE, Unit) element.putUserData(KotlinCompletionCharFilter.ACCEPT_OPENING_BRACE, Unit)
} }
@@ -39,10 +39,12 @@ class InsertHandlerProvider(
return when (descriptor) { return when (descriptor) {
is FunctionDescriptor -> { is FunctionDescriptor -> {
when (callType) {
is CallType.DEFAULT, is CallType.DOT, is CallType.SAFE -> {
val needTypeArguments = needTypeArguments(descriptor) val needTypeArguments = needTypeArguments(descriptor)
val parameters = descriptor.valueParameters val parameters = descriptor.valueParameters
when (parameters.size()) { when (parameters.size()) {
0 -> KotlinFunctionInsertHandler(callType, needTypeArguments, inputValueArguments = false) 0 -> KotlinFunctionInsertHandler.Normal(needTypeArguments, inputValueArguments = false)
1 -> { 1 -> {
val parameterType = parameters.single().getType() val parameterType = parameters.single().getType()
@@ -50,16 +52,23 @@ class InsertHandlerProvider(
val parameterCount = KotlinBuiltIns.getParameterTypeProjectionsFromFunctionType(parameterType).size() val parameterCount = KotlinBuiltIns.getParameterTypeProjectionsFromFunctionType(parameterType).size()
if (parameterCount <= 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(callType, needTypeArguments, inputValueArguments = false, lambdaInfo = GenerateLambdaInfo(parameterType, false)) return KotlinFunctionInsertHandler.Normal(needTypeArguments, inputValueArguments = false, lambdaInfo = GenerateLambdaInfo(parameterType, false))
} }
} }
KotlinFunctionInsertHandler(callType, needTypeArguments, inputValueArguments = true) KotlinFunctionInsertHandler.Normal(needTypeArguments, inputValueArguments = true)
} }
else -> KotlinFunctionInsertHandler(callType, needTypeArguments, inputValueArguments = true) else -> KotlinFunctionInsertHandler.Normal(needTypeArguments, inputValueArguments = true)
} }
} }
is CallType.INFIX -> KotlinFunctionInsertHandler.Infix
else -> KotlinFunctionInsertHandler.OnlyName
}
}
is PropertyDescriptor -> KotlinPropertyInsertHandler is PropertyDescriptor -> KotlinPropertyInsertHandler
is ClassifierDescriptor -> KotlinClassifierInsertHandler is ClassifierDescriptor -> KotlinClassifierInsertHandler
@@ -29,7 +29,6 @@ import com.intellij.psi.filters.position.PositionElementFilter
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler
import org.jetbrains.kotlin.idea.completion.handlers.KotlinKeywordInsertHandler import org.jetbrains.kotlin.idea.completion.handlers.KotlinKeywordInsertHandler
import org.jetbrains.kotlin.idea.util.CallType
import org.jetbrains.kotlin.lexer.JetKeywordToken import org.jetbrains.kotlin.lexer.JetKeywordToken
import org.jetbrains.kotlin.lexer.JetTokens.* import org.jetbrains.kotlin.lexer.JetTokens.*
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
@@ -77,7 +76,7 @@ object KeywordCompletion {
.withInsertHandler(if (keywordToken !in FUNCTION_KEYWORDS) .withInsertHandler(if (keywordToken !in FUNCTION_KEYWORDS)
KotlinKeywordInsertHandler KotlinKeywordInsertHandler
else else
KotlinFunctionInsertHandler(CallType.DEFAULT, inputTypeArguments = false, inputValueArguments = false)) KotlinFunctionInsertHandler.Normal(inputTypeArguments = false, inputValueArguments = false))
consumer(element) consumer(element)
} }
} }
@@ -104,7 +104,7 @@ class LookupElementFactory(
private fun createFunctionCallElementWithLambda(descriptor: FunctionDescriptor, parameterType: JetType, explicitLambdaParameters: Boolean, useReceiverTypes: Boolean): LookupElement { private fun createFunctionCallElementWithLambda(descriptor: FunctionDescriptor, parameterType: JetType, explicitLambdaParameters: Boolean, useReceiverTypes: Boolean): LookupElement {
var lookupElement = createLookupElement(descriptor, useReceiverTypes) var lookupElement = createLookupElement(descriptor, useReceiverTypes)
val inputTypeArguments = (insertHandlerProvider.insertHandler(descriptor) as KotlinFunctionInsertHandler).inputTypeArguments val inputTypeArguments = (insertHandlerProvider.insertHandler(descriptor) as KotlinFunctionInsertHandler.Normal).inputTypeArguments
val lambdaInfo = GenerateLambdaInfo(parameterType, explicitLambdaParameters) val lambdaInfo = GenerateLambdaInfo(parameterType, explicitLambdaParameters)
val lambdaPresentation = lambdaPresentation(if (explicitLambdaParameters) parameterType else null) val lambdaPresentation = lambdaPresentation(if (explicitLambdaParameters) parameterType else null)
@@ -132,7 +132,7 @@ class LookupElementFactory(
} }
override fun handleInsert(context: InsertionContext) { override fun handleInsert(context: InsertionContext) {
KotlinFunctionInsertHandler(callType!!, inputTypeArguments, inputValueArguments = false, lambdaInfo = lambdaInfo).handleInsert(context, this) KotlinFunctionInsertHandler.Normal(inputTypeArguments, inputValueArguments = false, lambdaInfo = lambdaInfo).handleInsert(context, this)
} }
} }
@@ -146,7 +146,7 @@ class LookupElementFactory(
private fun createFunctionCallElementWithArgument(descriptor: FunctionDescriptor, argumentText: String, useReceiverTypes: Boolean): LookupElement { private fun createFunctionCallElementWithArgument(descriptor: FunctionDescriptor, argumentText: String, useReceiverTypes: Boolean): LookupElement {
var lookupElement = createLookupElement(descriptor, useReceiverTypes) var lookupElement = createLookupElement(descriptor, useReceiverTypes)
val needTypeArguments = (insertHandlerProvider.insertHandler(descriptor) as KotlinFunctionInsertHandler).inputTypeArguments val needTypeArguments = (insertHandlerProvider.insertHandler(descriptor) as KotlinFunctionInsertHandler.Normal).inputTypeArguments
lookupElement = FunctionCallWithArgumentLookupElement(lookupElement, descriptor, argumentText, needTypeArguments) lookupElement = FunctionCallWithArgumentLookupElement(lookupElement, descriptor, argumentText, needTypeArguments)
if (isInStringTemplateAfterDollar) { if (isInStringTemplateAfterDollar) {
@@ -175,7 +175,7 @@ class LookupElementFactory(
} }
override fun handleInsert(context: InsertionContext) { override fun handleInsert(context: InsertionContext) {
KotlinFunctionInsertHandler(callType!!, inputTypeArguments = needTypeArguments, inputValueArguments = false, argumentText = argumentText).handleInsert(context, this) KotlinFunctionInsertHandler.Normal(inputTypeArguments = needTypeArguments, inputValueArguments = false, argumentText = argumentText).handleInsert(context, this)
} }
} }
@@ -26,7 +26,6 @@ import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.codeStyle.CodeStyleSettingsManager import com.intellij.psi.codeStyle.CodeStyleSettingsManager
import org.jetbrains.kotlin.idea.core.formatter.JetCodeStyleSettings import org.jetbrains.kotlin.idea.core.formatter.JetCodeStyleSettings
import org.jetbrains.kotlin.idea.util.CallType
import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.JetTypeArgumentList import org.jetbrains.kotlin.psi.JetTypeArgumentList
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -34,14 +33,16 @@ import org.jetbrains.kotlin.types.JetType
class GenerateLambdaInfo(val lambdaType: JetType, val explicitParameters: Boolean) class GenerateLambdaInfo(val lambdaType: JetType, val explicitParameters: Boolean)
class KotlinFunctionInsertHandler( sealed class KotlinFunctionInsertHandler(
val callType: CallType<*>,
) : KotlinCallableInsertHandler() {
class Normal(
val inputTypeArguments: Boolean, val inputTypeArguments: Boolean,
val inputValueArguments: Boolean, val inputValueArguments: Boolean,
val argumentText: String = "", val argumentText: String = "",
val lambdaInfo: GenerateLambdaInfo? = null val lambdaInfo: GenerateLambdaInfo? = null
) : KotlinCallableInsertHandler() { ) : KotlinFunctionInsertHandler() {
init { init {
if (lambdaInfo != null) { if (lambdaInfo != null) {
assert(argumentText == "") assert(argumentText == "")
@@ -53,26 +54,12 @@ class KotlinFunctionInsertHandler(
val psiDocumentManager = PsiDocumentManager.getInstance(context.project) val psiDocumentManager = PsiDocumentManager.getInstance(context.project)
psiDocumentManager.commitAllDocuments() psiDocumentManager.commitAllDocuments()
psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.getDocument()) psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.document)
val startOffset = context.getStartOffset() val startOffset = context.getStartOffset()
val element = context.getFile().findElementAt(startOffset) ?: return val element = context.getFile().findElementAt(startOffset) ?: return
when (callType) { addArguments(context, element)
CallType.PACKAGE_DIRECTIVE, CallType.IMPORT_DIRECTIVE, CallType.CALLABLE_REFERENCE -> return
CallType.INFIX -> {
if (context.getCompletionChar() == ' ') {
context.setAddCompletionChar(false)
}
val tailOffset = context.getTailOffset()
context.getDocument().insertString(tailOffset, " ")
context.getEditor().getCaretModel().moveToOffset(tailOffset + 1)
}
else -> addArguments(context, element)
}
} }
private fun addArguments(context : InsertionContext, offsetElement : PsiElement) { private fun addArguments(context : InsertionContext, offsetElement : PsiElement) {
@@ -184,3 +171,28 @@ class KotlinFunctionInsertHandler(
private fun isInsertSpacesInOneLineFunctionEnabled(project: Project) private fun isInsertSpacesInOneLineFunctionEnabled(project: Project)
= CodeStyleSettingsManager.getSettings(project).getCustomSettings(javaClass<JetCodeStyleSettings>())!!.INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD = CodeStyleSettingsManager.getSettings(project).getCustomSettings(javaClass<JetCodeStyleSettings>())!!.INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD
} }
object Infix : KotlinFunctionInsertHandler() {
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
super.handleInsert(context, item)
if (context.completionChar == ' ') {
context.setAddCompletionChar(false)
}
val tailOffset = context.tailOffset
context.document.insertString(tailOffset, " ")
context.editor.caretModel.moveToOffset(tailOffset + 1)
}
}
object OnlyName : KotlinFunctionInsertHandler()
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
super.handleInsert(context, item)
val psiDocumentManager = PsiDocumentManager.getInstance(context.project)
psiDocumentManager.commitAllDocuments()
psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.document)
}
}
@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler
import org.jetbrains.kotlin.idea.core.psiClassToDescriptor import org.jetbrains.kotlin.idea.core.psiClassToDescriptor
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.util.CallType
import org.jetbrains.kotlin.idea.util.FuzzyType import org.jetbrains.kotlin.idea.util.FuzzyType
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.idea.util.makeNotNullable import org.jetbrains.kotlin.idea.util.makeNotNullable
@@ -204,9 +203,9 @@ class TypeInstantiationItems(
} }
val baseInsertHandler = when (visibleConstructors.size()) { val baseInsertHandler = when (visibleConstructors.size()) {
0 -> KotlinFunctionInsertHandler(CallType.DEFAULT, inputTypeArguments = false, inputValueArguments = false) 0 -> KotlinFunctionInsertHandler.Normal(inputTypeArguments = false, inputValueArguments = false)
1 -> lookupElementFactory.insertHandlerProvider.insertHandler(visibleConstructors.single()) as KotlinFunctionInsertHandler 1 -> lookupElementFactory.insertHandlerProvider.insertHandler(visibleConstructors.single()) as KotlinFunctionInsertHandler.Normal
else -> KotlinFunctionInsertHandler(CallType.DEFAULT, inputTypeArguments = false, inputValueArguments = true) else -> KotlinFunctionInsertHandler.Normal(inputTypeArguments = false, inputValueArguments = true)
} }
insertHandler = object : InsertHandler<LookupElement> { insertHandler = object : InsertHandler<LookupElement> {
@@ -12,6 +12,8 @@ class C {
val memberVal = 1 val memberVal = 1
fun funWithFunctionParameter(p: () -> Unit) {}
class NestedClass class NestedClass
inner class InnerClass inner class InnerClass
@@ -48,3 +50,4 @@ abstract class AbstractClass
// ABSENT: AbstractClass // ABSENT: AbstractClass
// ABSENT: class // ABSENT: class
// ABSENT: class.java // ABSENT: class.java
// EXIST: { itemText: "funWithFunctionParameter", tailText: "(p: () -> Unit)", attributes: "bold" }
@@ -3,5 +3,7 @@ package second
fun String.extensionFun(){} fun String.extensionFun(){}
val Int.extensionVal: Int get() = 1 val Int.extensionVal: Int get() = 1
fun topLevelFun(p: (String, Int) -> Unit){} fun topLevelFun1(p: (String, Int) -> Unit){}
fun topLevelFun2(p: () -> Unit){}
val topLevelVal: Int = 1 val topLevelVal: Int = 1
@@ -4,5 +4,7 @@ import second.<caret>
// EXIST: { itemText: "extensionFun", tailText: "() for String in second", attributes: "" } // EXIST: { itemText: "extensionFun", tailText: "() for String in second", attributes: "" }
// EXIST: { itemText: "extensionVal", tailText: " for Int in second", attributes: "" } // EXIST: { itemText: "extensionVal", tailText: " for Int in second", attributes: "" }
// EXIST: { itemText: "topLevelFun", tailText: "(p: (String, Int) -> Unit) (second)", attributes: "" } // EXIST: { itemText: "topLevelFun1", tailText: "(p: (String, Int) -> Unit) (second)", attributes: "" }
// EXIST: { itemText: "topLevelFun2", tailText: "(p: () -> Unit) (second)", attributes: "" }
// EXIST: { itemText: "topLevelVal", tailText: " (second)", attributes: "" } // EXIST: { itemText: "topLevelVal", tailText: " (second)", attributes: "" }
// NOTHING_ELSE