KT-8898 If invocation context contains functional value compatible with function in completion list, show non-literal item
#KT-8898 Fixed
This commit is contained in:
+41
-35
@@ -191,41 +191,7 @@ class BasicLookupElementFactory(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor is CallableDescriptor) {
|
if (descriptor is CallableDescriptor) {
|
||||||
val extensionReceiver = descriptor.original.extensionReceiverParameter
|
appendContainerAndReceiverInformation(descriptor) { tail, grayed -> element = element.appendTailText(tail, grayed) }
|
||||||
when {
|
|
||||||
descriptor is SyntheticJavaPropertyDescriptor -> {
|
|
||||||
var from = descriptor.getMethod.getName().asString() + "()"
|
|
||||||
descriptor.setMethod?.let { from += "/" + it.getName().asString() + "()" }
|
|
||||||
element = element.appendTailText(" (from $from)", true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// no need to show them as extensions
|
|
||||||
descriptor is SamAdapterExtensionFunctionDescriptor -> {}
|
|
||||||
|
|
||||||
extensionReceiver != null -> {
|
|
||||||
val receiverPresentation = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(extensionReceiver.type)
|
|
||||||
element = element.appendTailText(" for $receiverPresentation", true)
|
|
||||||
|
|
||||||
val container = descriptor.getContainingDeclaration()
|
|
||||||
val containerPresentation = if (container is ClassDescriptor)
|
|
||||||
DescriptorUtils.getFqNameFromTopLevelClass(container).toString()
|
|
||||||
else if (container is PackageFragmentDescriptor)
|
|
||||||
container.fqName.toString()
|
|
||||||
else
|
|
||||||
null
|
|
||||||
if (containerPresentation != null) {
|
|
||||||
element = element.appendTailText(" in $containerPresentation", true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
val container = descriptor.getContainingDeclaration()
|
|
||||||
if (container is PackageFragmentDescriptor) { // we show container only for global functions and properties
|
|
||||||
//TODO: it would be probably better to show it also for static declarations which are not from the current class (imported)
|
|
||||||
element = element.appendTailText(" (${container.fqName})", true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor is PropertyDescriptor) {
|
if (descriptor is PropertyDescriptor) {
|
||||||
@@ -249,6 +215,46 @@ class BasicLookupElementFactory(
|
|||||||
return element.withIconFromLookupObject()
|
return element.withIconFromLookupObject()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun appendContainerAndReceiverInformation(descriptor: CallableDescriptor, appendTailText: (String, Boolean) -> Unit) {
|
||||||
|
val extensionReceiver = descriptor.original.extensionReceiverParameter
|
||||||
|
when {
|
||||||
|
descriptor is SyntheticJavaPropertyDescriptor -> {
|
||||||
|
var from = descriptor.getMethod.getName().asString() + "()"
|
||||||
|
descriptor.setMethod?.let { from += "/" + it.getName().asString() + "()" }
|
||||||
|
appendTailText(" (from $from)", true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// no need to show them as extensions
|
||||||
|
descriptor is SamAdapterExtensionFunctionDescriptor -> {
|
||||||
|
}
|
||||||
|
|
||||||
|
extensionReceiver != null -> {
|
||||||
|
val receiverPresentation = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(extensionReceiver.type)
|
||||||
|
appendTailText(" for $receiverPresentation", true)
|
||||||
|
|
||||||
|
val container = descriptor.getContainingDeclaration()
|
||||||
|
val containerPresentation = if (container is ClassDescriptor)
|
||||||
|
DescriptorUtils.getFqNameFromTopLevelClass(container).toString()
|
||||||
|
else if (container is PackageFragmentDescriptor)
|
||||||
|
container.fqName.toString()
|
||||||
|
else
|
||||||
|
null
|
||||||
|
if (containerPresentation != null) {
|
||||||
|
appendTailText(" in $containerPresentation", true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
val container = descriptor.getContainingDeclaration()
|
||||||
|
if (container is PackageFragmentDescriptor) {
|
||||||
|
// we show container only for global functions and properties
|
||||||
|
//TODO: it would be probably better to show it also for static declarations which are not from the current class (imported)
|
||||||
|
appendTailText(" (${container.fqName})", true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun LookupElement.withIconFromLookupObject(): LookupElement {
|
private fun LookupElement.withIconFromLookupObject(): LookupElement {
|
||||||
// add icon in renderElement only to pass presentation.isReal()
|
// add icon in renderElement only to pass presentation.isReal()
|
||||||
return object : LookupElementDecorator<LookupElement>(this) {
|
return object : LookupElementDecorator<LookupElement>(this) {
|
||||||
|
|||||||
@@ -140,14 +140,14 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
|
|||||||
|
|
||||||
protected val receiversData: ReferenceVariantsHelper.ReceiversData? = nameExpression?.let { referenceVariantsHelper.getReferenceVariantsReceivers(it) }
|
protected val receiversData: ReferenceVariantsHelper.ReceiversData? = nameExpression?.let { referenceVariantsHelper.getReferenceVariantsReceivers(it) }
|
||||||
|
|
||||||
private val factoryContext = if (expression?.getParent() is JetSimpleNameStringTemplateEntry)
|
|
||||||
LookupElementFactory.Context.STRING_TEMPLATE_AFTER_DOLLAR
|
|
||||||
else if (receiversData?.callType == CallType.INFIX)
|
|
||||||
LookupElementFactory.Context.INFIX_CALL
|
|
||||||
else
|
|
||||||
LookupElementFactory.Context.NORMAL
|
|
||||||
|
|
||||||
protected val lookupElementFactory: LookupElementFactory = run {
|
protected val lookupElementFactory: LookupElementFactory = run {
|
||||||
|
val contextType = if (expression?.getParent() is JetSimpleNameStringTemplateEntry)
|
||||||
|
LookupElementFactory.ContextType.STRING_TEMPLATE_AFTER_DOLLAR
|
||||||
|
else if (receiversData?.callType == CallType.INFIX)
|
||||||
|
LookupElementFactory.ContextType.INFIX_CALL
|
||||||
|
else
|
||||||
|
LookupElementFactory.ContextType.NORMAL
|
||||||
|
|
||||||
var receiverTypes = emptyList<JetType>()
|
var receiverTypes = emptyList<JetType>()
|
||||||
if (receiversData != null) {
|
if (receiversData != null) {
|
||||||
val dataFlowInfo = bindingContext.getDataFlowInfo(expression)
|
val dataFlowInfo = bindingContext.getDataFlowInfo(expression)
|
||||||
@@ -168,7 +168,14 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LookupElementFactory(resolutionFacade, receiverTypes, factoryContext, inDescriptor, InsertHandlerProvider { expectedInfos })
|
val contextVariablesProvider = {
|
||||||
|
nameExpression?.let {
|
||||||
|
referenceVariantsHelper.getReferenceVariants(it, DescriptorKindFilter.VARIABLES, { true }, explicitReceiverData = null)
|
||||||
|
.map { it as VariableDescriptor }
|
||||||
|
} ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
LookupElementFactory(resolutionFacade, receiverTypes, contextType, inDescriptor, InsertHandlerProvider { expectedInfos }, contextVariablesProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LookupElementsCollector instantiation is deferred because virtual call to createSorter uses data from derived classes
|
// LookupElementsCollector instantiation is deferred because virtual call to createSorter uses data from derived classes
|
||||||
|
|||||||
+61
-7
@@ -30,6 +30,8 @@ import org.jetbrains.kotlin.idea.completion.handlers.GenerateLambdaInfo
|
|||||||
import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler
|
import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler
|
||||||
import org.jetbrains.kotlin.idea.completion.handlers.buildLambdaPresentation
|
import org.jetbrains.kotlin.idea.completion.handlers.buildLambdaPresentation
|
||||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||||
|
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||||
|
import org.jetbrains.kotlin.idea.util.fuzzyReturnType
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.JetProperty
|
import org.jetbrains.kotlin.psi.JetProperty
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -45,13 +47,18 @@ import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
|||||||
class LookupElementFactory(
|
class LookupElementFactory(
|
||||||
private val resolutionFacade: ResolutionFacade,
|
private val resolutionFacade: ResolutionFacade,
|
||||||
private val receiverTypes: Collection<JetType>,
|
private val receiverTypes: Collection<JetType>,
|
||||||
private val context: LookupElementFactory.Context,
|
private val contextType: LookupElementFactory.ContextType,
|
||||||
private val inDescriptor: DeclarationDescriptor?,
|
private val inDescriptor: DeclarationDescriptor?,
|
||||||
public val insertHandlerProvider: InsertHandlerProvider
|
public val insertHandlerProvider: InsertHandlerProvider,
|
||||||
|
contextVariablesProvider: () -> Collection<VariableDescriptor>
|
||||||
) {
|
) {
|
||||||
private val basicFactory = BasicLookupElementFactory(resolutionFacade.project, insertHandlerProvider)
|
private val basicFactory = BasicLookupElementFactory(resolutionFacade.project, insertHandlerProvider)
|
||||||
|
|
||||||
public enum class Context {
|
private val functionTypeContextVariables by lazy {
|
||||||
|
contextVariablesProvider().filter { KotlinBuiltIns.isFunctionOrExtensionFunctionType(it.type) }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum class ContextType {
|
||||||
NORMAL,
|
NORMAL,
|
||||||
STRING_TEMPLATE_AFTER_DOLLAR,
|
STRING_TEMPLATE_AFTER_DOLLAR,
|
||||||
INFIX_CALL
|
INFIX_CALL
|
||||||
@@ -61,20 +68,20 @@ class LookupElementFactory(
|
|||||||
val result = SmartList<LookupElement>()
|
val result = SmartList<LookupElement>()
|
||||||
|
|
||||||
var lookupElement = createLookupElement(descriptor, useReceiverTypes)
|
var lookupElement = createLookupElement(descriptor, useReceiverTypes)
|
||||||
if (context == Context.STRING_TEMPLATE_AFTER_DOLLAR && (descriptor is FunctionDescriptor || descriptor is ClassifierDescriptor)) {
|
if (contextType == ContextType.STRING_TEMPLATE_AFTER_DOLLAR && (descriptor is FunctionDescriptor || descriptor is ClassifierDescriptor)) {
|
||||||
lookupElement = lookupElement.withBracesSurrounding()
|
lookupElement = lookupElement.withBracesSurrounding()
|
||||||
}
|
}
|
||||||
result.add(lookupElement)
|
result.add(lookupElement)
|
||||||
|
|
||||||
// add special item for function with one argument of function type with more than one parameter
|
// add special item for function with one argument of function type with more than one parameter
|
||||||
if (context != Context.INFIX_CALL && descriptor is FunctionDescriptor) {
|
if (contextType != ContextType.INFIX_CALL && descriptor is FunctionDescriptor) {
|
||||||
result.addSpecialFunctionCallElements(descriptor, useReceiverTypes)
|
result.addSpecialFunctionCallElements(descriptor, useReceiverTypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor is PropertyDescriptor && inDescriptor != null) {
|
if (descriptor is PropertyDescriptor && inDescriptor != null) {
|
||||||
var backingFieldElement = createBackingFieldLookupElement(descriptor, useReceiverTypes)
|
var backingFieldElement = createBackingFieldLookupElement(descriptor, useReceiverTypes)
|
||||||
if (backingFieldElement != null) {
|
if (backingFieldElement != null) {
|
||||||
if (context == Context.STRING_TEMPLATE_AFTER_DOLLAR) {
|
if (contextType == ContextType.STRING_TEMPLATE_AFTER_DOLLAR) {
|
||||||
backingFieldElement = backingFieldElement.withBracesSurrounding()
|
backingFieldElement = backingFieldElement.withBracesSurrounding()
|
||||||
}
|
}
|
||||||
result.add(backingFieldElement)
|
result.add(backingFieldElement)
|
||||||
@@ -92,6 +99,17 @@ class LookupElementFactory(
|
|||||||
if (functionParameterCount > 1) {
|
if (functionParameterCount > 1) {
|
||||||
add(createFunctionCallElementWithExplicitLambdaParameters(descriptor, parameterType, useReceiverTypes))
|
add(createFunctionCallElementWithExplicitLambdaParameters(descriptor, parameterType, useReceiverTypes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: also ::function? at least for local functions
|
||||||
|
//TODO: order for them
|
||||||
|
val fuzzyParameterType = FuzzyType(parameterType, descriptor.typeParameters)
|
||||||
|
for (variable in functionTypeContextVariables) {
|
||||||
|
val substitutor = variable.fuzzyReturnType()?.checkIsSubtypeOf(fuzzyParameterType)
|
||||||
|
if (substitutor != null) {
|
||||||
|
val substitutedDescriptor = descriptor.substitute(substitutor) ?: continue
|
||||||
|
add(createFunctionCallElementWithArgument(substitutedDescriptor, variable.name.asString(), useReceiverTypes))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,13 +133,49 @@ class LookupElementFactory(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context == Context.STRING_TEMPLATE_AFTER_DOLLAR) {
|
if (contextType == ContextType.STRING_TEMPLATE_AFTER_DOLLAR) {
|
||||||
lookupElement = lookupElement.withBracesSurrounding()
|
lookupElement = lookupElement.withBracesSurrounding()
|
||||||
}
|
}
|
||||||
|
|
||||||
return lookupElement
|
return lookupElement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createFunctionCallElementWithArgument(descriptor: FunctionDescriptor, argumentText: String, useReceiverTypes: Boolean): LookupElement {
|
||||||
|
var lookupElement = createLookupElement(descriptor, useReceiverTypes)
|
||||||
|
|
||||||
|
val needTypeArguments = (insertHandlerProvider.insertHandler(descriptor) as KotlinFunctionInsertHandler).needTypeArguments
|
||||||
|
lookupElement = FunctionCallWithArgumentLookupElement(lookupElement, descriptor, argumentText, needTypeArguments)
|
||||||
|
|
||||||
|
if (contextType == ContextType.STRING_TEMPLATE_AFTER_DOLLAR) {
|
||||||
|
lookupElement = lookupElement.withBracesSurrounding()
|
||||||
|
}
|
||||||
|
|
||||||
|
return lookupElement
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class FunctionCallWithArgumentLookupElement(
|
||||||
|
originalLookupElement: LookupElement,
|
||||||
|
private val descriptor: FunctionDescriptor,
|
||||||
|
private val argumentText: String,
|
||||||
|
private val needTypeArguments: Boolean
|
||||||
|
) : LookupElementDecorator<LookupElement>(originalLookupElement) {
|
||||||
|
|
||||||
|
override fun equals(other: Any?) = other is FunctionCallWithArgumentLookupElement && delegate == other.delegate && argumentText == other.argumentText
|
||||||
|
override fun hashCode() = delegate.hashCode() * 17 + argumentText.hashCode()
|
||||||
|
|
||||||
|
override fun renderElement(presentation: LookupElementPresentation) {
|
||||||
|
super.renderElement(presentation)
|
||||||
|
|
||||||
|
presentation.clearTail()
|
||||||
|
presentation.appendTailText("($argumentText)", false)
|
||||||
|
basicFactory.appendContainerAndReceiverInformation(descriptor) { tail, grayed -> presentation.appendTailText(tail, grayed) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun handleInsert(context: InsertionContext) {
|
||||||
|
KotlinFunctionInsertHandler(needTypeArguments = needTypeArguments, needValueArguments = false, argumentText = argumentText).handleInsert(context, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createBackingFieldLookupElement(property: PropertyDescriptor, useReceiverTypes: Boolean): LookupElement? {
|
private fun createBackingFieldLookupElement(property: PropertyDescriptor, useReceiverTypes: Boolean): LookupElement? {
|
||||||
if (inDescriptor == null) return null
|
if (inDescriptor == null) return null
|
||||||
val insideAccessor = inDescriptor is PropertyAccessorDescriptor && inDescriptor.getCorrespondingProperty() == property
|
val insideAccessor = inDescriptor is PropertyAccessorDescriptor && inDescriptor.getCorrespondingProperty() == property
|
||||||
|
|||||||
+15
-3
@@ -35,14 +35,21 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.types.JetType
|
import org.jetbrains.kotlin.types.JetType
|
||||||
|
|
||||||
data class GenerateLambdaInfo(val lambdaType: JetType, val explicitParameters: Boolean)
|
class GenerateLambdaInfo(val lambdaType: JetType, val explicitParameters: Boolean)
|
||||||
|
|
||||||
class KotlinFunctionInsertHandler(
|
class KotlinFunctionInsertHandler(
|
||||||
val needTypeArguments: Boolean,
|
val needTypeArguments: Boolean,
|
||||||
val needValueArguments: Boolean,
|
val needValueArguments: Boolean,
|
||||||
|
val argumentText: String = "",
|
||||||
val lambdaInfo: GenerateLambdaInfo? = null
|
val lambdaInfo: GenerateLambdaInfo? = null
|
||||||
) : KotlinCallableInsertHandler() {
|
) : KotlinCallableInsertHandler() {
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (lambdaInfo != null) {
|
||||||
|
assert(argumentText == "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
super.handleInsert(context, item)
|
super.handleInsert(context, item)
|
||||||
|
|
||||||
@@ -66,7 +73,7 @@ class KotlinFunctionInsertHandler(
|
|||||||
context.getEditor().getCaretModel().moveToOffset(tailOffset + 1)
|
context.getEditor().getCaretModel().moveToOffset(tailOffset + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> addBrackets(context, element)
|
else -> addArguments(context, element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +83,7 @@ class KotlinFunctionInsertHandler(
|
|||||||
return parent is JetSimpleNameExpression && grandParent is JetBinaryExpression && parent == grandParent.getOperationReference()
|
return parent is JetSimpleNameExpression && grandParent is JetBinaryExpression && parent == grandParent.getOperationReference()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addBrackets(context : InsertionContext, offsetElement : PsiElement) {
|
private fun addArguments(context : InsertionContext, offsetElement : PsiElement) {
|
||||||
val completionChar = context.getCompletionChar()
|
val completionChar = context.getCompletionChar()
|
||||||
if (completionChar == '(') { //TODO: more correct behavior related to braces type
|
if (completionChar == '(') { //TODO: more correct behavior related to braces type
|
||||||
context.setAddCompletionChar(false)
|
context.setAddCompletionChar(false)
|
||||||
@@ -153,6 +160,11 @@ class KotlinFunctionInsertHandler(
|
|||||||
closeBracketOffset = chars.indexOfSkippingSpace(closingBracket, openingBracketOffset + 1)!!
|
closeBracketOffset = chars.indexOfSkippingSpace(closingBracket, openingBracketOffset + 1)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.insertString(openingBracketOffset + 1, argumentText)
|
||||||
|
if (closeBracketOffset != null) {
|
||||||
|
closeBracketOffset += argumentText.length()
|
||||||
|
}
|
||||||
|
|
||||||
if (!insertTypeArguments) {
|
if (!insertTypeArguments) {
|
||||||
if (shouldPlaceCaretInBrackets(completionChar) || closeBracketOffset == null) {
|
if (shouldPlaceCaretInBrackets(completionChar) || closeBracketOffset == null) {
|
||||||
editor.caretModel.moveToOffset(openingBracketOffset + 1 + inBracketsShift)
|
editor.caretModel.moveToOffset(openingBracketOffset + 1 + inBracketsShift)
|
||||||
|
|||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
interface I : () -> Unit
|
||||||
|
|
||||||
|
fun xfoo(p: () -> Unit){}
|
||||||
|
|
||||||
|
val global: () -> Unit = { }
|
||||||
|
|
||||||
|
fun X.test(p1: () -> Unit, p2: () -> String, p3: I) {
|
||||||
|
val local: () -> Unit = { }
|
||||||
|
xfoo<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface X {
|
||||||
|
public val publicVal: () -> Unit
|
||||||
|
protected val protectedVal: () -> Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
val X.extension: () -> Unit
|
||||||
|
get() = {}
|
||||||
|
|
||||||
|
val String.wrongExtension: () -> Unit
|
||||||
|
get() = {}
|
||||||
|
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: " {...} (p: () -> Unit) (<root>)", typeText:"Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(p1) (<root>)", typeText: "Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(p3) (<root>)", typeText: "Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(local) (<root>)", typeText: "Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(global) (<root>)", typeText: "Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(publicVal) (<root>)", typeText: "Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(extension) (<root>)", typeText: "Unit" }
|
||||||
|
// NOTHING_ELSE
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
interface I : () -> Unit
|
||||||
|
|
||||||
|
fun String.xfoo(p: () -> Unit){}
|
||||||
|
|
||||||
|
val global: () -> Unit = { }
|
||||||
|
|
||||||
|
fun X.test(p1: () -> Unit, p2: () -> String, p3: I) {
|
||||||
|
val local: () -> Unit = { }
|
||||||
|
"a".xfoo<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface X {
|
||||||
|
public val publicVal: () -> Unit
|
||||||
|
protected val protectedVal: () -> Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
val X.extension: () -> Unit
|
||||||
|
get() = {}
|
||||||
|
|
||||||
|
val String.wrongExtension: () -> Unit
|
||||||
|
get() = {}
|
||||||
|
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: " {...} (p: () -> Unit) for String in <root>", typeText:"Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(p1) for String in <root>", typeText: "Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(p3) for String in <root>", typeText: "Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(local) for String in <root>", typeText: "Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(global) for String in <root>", typeText: "Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(publicVal) for String in <root>", typeText: "Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(extension) for String in <root>", typeText: "Unit" }
|
||||||
|
// NOTHING_ELSE
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
fun test(p1: (String) -> Boolean, p2: (Int) -> Boolean) {
|
||||||
|
listOf("a", "b").filt<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: { itemText: "filter", tailText: " {...} (predicate: (String) -> Boolean) for Iterable<T> in kotlin", typeText:"List<String>" }
|
||||||
|
// EXIST: { itemText: "filter", tailText: "(p1) for Iterable<T> in kotlin", typeText: "List<String>" }
|
||||||
|
// ABSENT: { itemText: "filter", tailText: "(p2) for Iterable<T> in kotlin", typeText: "List<String>" }
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
fun test(p1: (String) -> Int, p2: (Int) -> Int, p3: (String) -> Char) {
|
||||||
|
listOf("a", "b").map<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: { itemText: "map", tailText: " {...} (transform: (String) -> R) for Iterable<T> in kotlin", typeText:"List<R>" }
|
||||||
|
// EXIST: { itemText: "map", tailText: "(p1) for Iterable<T> in kotlin", typeText: "List<Int>" }
|
||||||
|
// ABSENT: { itemText: "map", tailText: "(p2) for Iterable<T> in kotlin", typeText: "List<Int>" }
|
||||||
|
// EXIST: { itemText: "map", tailText: "(p3) for Iterable<T> in kotlin", typeText: "List<Char>" }
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
interface I1 {
|
||||||
|
val v: () -> Unit
|
||||||
|
val v1: () -> Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
interface I2 {
|
||||||
|
val v: String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.xfoo(p: () -> Unit){}
|
||||||
|
|
||||||
|
fun X.test(i1: I1, i2: I2) {
|
||||||
|
with(i1) {
|
||||||
|
with(i2) {
|
||||||
|
"a".xfoo<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface X
|
||||||
|
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: " {...} (p: () -> Unit) for String in <root>", typeText:"Unit" }
|
||||||
|
// EXIST: { itemText: "xfoo", tailText: "(v1) for String in <root>", typeText: "Unit" }
|
||||||
|
// NOTHING_ELSE
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
fun foo(p: (String, Char) -> Unit){}
|
fun foo(p: (String, Char) -> Unit){}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
fo<caret>
|
foo<caret>
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXIST: { lookupString:"foo", itemText: "foo", tailText: "(p: (String, Char) -> Unit) (<root>)", typeText:"Unit" }
|
// EXIST: { lookupString:"foo", itemText: "foo", tailText: "(p: (String, Char) -> Unit) (<root>)", typeText:"Unit" }
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
fun String.xfoo(p: () -> Unit){}
|
||||||
|
|
||||||
|
fun X.test() {
|
||||||
|
val local: () -> Unit = { }
|
||||||
|
"a".xf<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: xfoo
|
||||||
|
// TAIL_TEXT: "(local) for String in <root>"
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
fun String.xfoo(p: () -> Unit){}
|
||||||
|
|
||||||
|
fun X.test() {
|
||||||
|
val local: () -> Unit = { }
|
||||||
|
"a".xfoo(local)<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: xfoo
|
||||||
|
// TAIL_TEXT: "(local) for String in <root>"
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun String.xfoo(p: () -> Unit): String = ""
|
||||||
|
|
||||||
|
fun X.test() {
|
||||||
|
val local: () -> Unit = { }
|
||||||
|
"a".xf<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: xfoo
|
||||||
|
// TAIL_TEXT: "(local) for String in <root>"
|
||||||
|
// CHAR: '.'
|
||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun String.xfoo(p: () -> Unit): String = ""
|
||||||
|
|
||||||
|
fun X.test() {
|
||||||
|
val local: () -> Unit = { }
|
||||||
|
"a".xfoo(local).<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: xfoo
|
||||||
|
// TAIL_TEXT: "(local) for String in <root>"
|
||||||
|
// CHAR: '.'
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
inline fun <reified T> String.xfoo(p: () -> Unit){}
|
||||||
|
|
||||||
|
fun X.test() {
|
||||||
|
val local: () -> Unit = { }
|
||||||
|
"a".xf<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: xfoo
|
||||||
|
// TAIL_TEXT: "(local) for String in <root>"
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
inline fun <reified T> String.xfoo(p: () -> Unit){}
|
||||||
|
|
||||||
|
fun X.test() {
|
||||||
|
val local: () -> Unit = { }
|
||||||
|
"a".xfoo<<caret>>(local)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: xfoo
|
||||||
|
// TAIL_TEXT: "(local) for String in <root>"
|
||||||
+51
-12
@@ -217,18 +217,6 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("HigherOrderFunction1.kt")
|
|
||||||
public void testHigherOrderFunction1() throws Exception {
|
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/HigherOrderFunction1.kt");
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("HigherOrderFunction2.kt")
|
|
||||||
public void testHigherOrderFunction2() throws Exception {
|
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/HigherOrderFunction2.kt");
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("ImportedEnumMembers.kt")
|
@TestMetadata("ImportedEnumMembers.kt")
|
||||||
public void testImportedEnumMembers() throws Exception {
|
public void testImportedEnumMembers() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/ImportedEnumMembers.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/ImportedEnumMembers.kt");
|
||||||
@@ -1327,6 +1315,57 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class HighOrderFunctions extends AbstractJSBasicCompletionTest {
|
||||||
|
public void testAllFilesPresentInHighOrderFunctions() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/highOrderFunctions"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariables1.kt")
|
||||||
|
public void testContextVariables1() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/ContextVariables1.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariables2.kt")
|
||||||
|
public void testContextVariables2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/ContextVariables2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariablesFilter.kt")
|
||||||
|
public void testContextVariablesFilter() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/ContextVariablesFilter.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariablesMap.kt")
|
||||||
|
public void testContextVariablesMap() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/ContextVariablesMap.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariablesShadowing.kt")
|
||||||
|
public void testContextVariablesShadowing() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/ContextVariablesShadowing.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("HigherOrderFunction1.kt")
|
||||||
|
public void testHigherOrderFunction1() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/HigherOrderFunction1.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("HigherOrderFunction2.kt")
|
||||||
|
public void testHigherOrderFunction2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/HigherOrderFunction2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/idea-completion/testData/basic/common/lambdaSignature")
|
@TestMetadata("idea/idea-completion/testData/basic/common/lambdaSignature")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+51
-12
@@ -217,18 +217,6 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("HigherOrderFunction1.kt")
|
|
||||||
public void testHigherOrderFunction1() throws Exception {
|
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/HigherOrderFunction1.kt");
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("HigherOrderFunction2.kt")
|
|
||||||
public void testHigherOrderFunction2() throws Exception {
|
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/HigherOrderFunction2.kt");
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("ImportedEnumMembers.kt")
|
@TestMetadata("ImportedEnumMembers.kt")
|
||||||
public void testImportedEnumMembers() throws Exception {
|
public void testImportedEnumMembers() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/ImportedEnumMembers.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/ImportedEnumMembers.kt");
|
||||||
@@ -1327,6 +1315,57 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class HighOrderFunctions extends AbstractJvmBasicCompletionTest {
|
||||||
|
public void testAllFilesPresentInHighOrderFunctions() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/highOrderFunctions"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariables1.kt")
|
||||||
|
public void testContextVariables1() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/ContextVariables1.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariables2.kt")
|
||||||
|
public void testContextVariables2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/ContextVariables2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariablesFilter.kt")
|
||||||
|
public void testContextVariablesFilter() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/ContextVariablesFilter.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariablesMap.kt")
|
||||||
|
public void testContextVariablesMap() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/ContextVariablesMap.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariablesShadowing.kt")
|
||||||
|
public void testContextVariablesShadowing() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/ContextVariablesShadowing.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("HigherOrderFunction1.kt")
|
||||||
|
public void testHigherOrderFunction1() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/HigherOrderFunction1.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("HigherOrderFunction2.kt")
|
||||||
|
public void testHigherOrderFunction2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions/HigherOrderFunction2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/idea-completion/testData/basic/common/lambdaSignature")
|
@TestMetadata("idea/idea-completion/testData/basic/common/lambdaSignature")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+18
@@ -202,6 +202,24 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/highOrderFunctions"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/highOrderFunctions"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariable.kt")
|
||||||
|
public void testContextVariable() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/ContextVariable.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariableDot.kt")
|
||||||
|
public void testContextVariableDot() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/ContextVariableDot.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ContextVariableTypeArgsNeeded.kt")
|
||||||
|
public void testContextVariableTypeArgsNeeded() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/ContextVariableTypeArgsNeeded.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ForceParenthesisForTabChar.kt")
|
@TestMetadata("ForceParenthesisForTabChar.kt")
|
||||||
public void testForceParenthesisForTabChar() throws Exception {
|
public void testForceParenthesisForTabChar() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/ForceParenthesisForTabChar.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/ForceParenthesisForTabChar.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user