KT-6191 Support completion for backing field
#KT-6191 Fixed
This commit is contained in:
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.*
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.patterns.CharPattern
|
import com.intellij.patterns.CharPattern
|
||||||
|
import com.intellij.patterns.ElementPattern
|
||||||
import com.intellij.patterns.PatternCondition
|
import com.intellij.patterns.PatternCondition
|
||||||
import com.intellij.patterns.StandardPatterns
|
import com.intellij.patterns.StandardPatterns
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
@@ -37,10 +38,12 @@ import org.jetbrains.kotlin.idea.refactoring.comparePossiblyOverridingDescriptor
|
|||||||
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference
|
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference
|
||||||
import org.jetbrains.kotlin.idea.util.CallType
|
import org.jetbrains.kotlin.idea.util.CallType
|
||||||
import org.jetbrains.kotlin.idea.util.makeNotNullable
|
import org.jetbrains.kotlin.idea.util.makeNotNullable
|
||||||
|
import org.jetbrains.kotlin.lexer.JetTokens
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptorKindExclude
|
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptorKindExclude
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.prevLeaf
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils
|
||||||
@@ -90,6 +93,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
|||||||
protected val bindingContext: BindingContext? = expression?.let { resolutionFacade.analyze(it, BodyResolveMode.PARTIAL_FOR_COMPLETION) }
|
protected val bindingContext: BindingContext? = expression?.let { resolutionFacade.analyze(it, BodyResolveMode.PARTIAL_FOR_COMPLETION) }
|
||||||
protected val inDescriptor: DeclarationDescriptor? = expression?.let { bindingContext!!.get(BindingContext.RESOLUTION_SCOPE, it)?.getContainingDeclaration() }
|
protected val inDescriptor: DeclarationDescriptor? = expression?.let { bindingContext!!.get(BindingContext.RESOLUTION_SCOPE, it)?.getContainingDeclaration() }
|
||||||
|
|
||||||
|
|
||||||
private fun singleCharPattern(char: Char): CharPattern {
|
private fun singleCharPattern(char: Char): CharPattern {
|
||||||
return StandardPatterns.character().with(
|
return StandardPatterns.character().with(
|
||||||
object : PatternCondition<Char>(char.toString()) {
|
object : PatternCondition<Char>(char.toString()) {
|
||||||
@@ -97,8 +101,20 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private val kotlinIdentifierStartPattern = StandardPatterns.and(StandardPatterns.character().javaIdentifierStart(), StandardPatterns.not(singleCharPattern('$')))
|
private val kotlinIdentifierStartPattern: ElementPattern<Char>
|
||||||
private val kotlinIdentifierPartPattern = StandardPatterns.and(StandardPatterns.character().javaIdentifierPart(), StandardPatterns.not(singleCharPattern('$')))
|
private val kotlinIdentifierPartPattern: ElementPattern<Char>
|
||||||
|
|
||||||
|
;{
|
||||||
|
val includeDollar = position.prevLeaf()?.getNode()?.getElementType() != JetTokens.SHORT_TEMPLATE_ENTRY_START
|
||||||
|
if (includeDollar) {
|
||||||
|
kotlinIdentifierStartPattern = StandardPatterns.character().javaIdentifierStart()
|
||||||
|
kotlinIdentifierPartPattern = StandardPatterns.character().javaIdentifierPart()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
kotlinIdentifierStartPattern = StandardPatterns.and(StandardPatterns.character().javaIdentifierStart(), StandardPatterns.not(singleCharPattern('$')))
|
||||||
|
kotlinIdentifierPartPattern = StandardPatterns.and(StandardPatterns.character().javaIdentifierPart(), StandardPatterns.not(singleCharPattern('$')))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected val prefix: String = CompletionUtil.findIdentifierPrefix(
|
protected val prefix: String = CompletionUtil.findIdentifierPrefix(
|
||||||
parameters.getPosition().getContainingFile(),
|
parameters.getPosition().getContainingFile(),
|
||||||
@@ -135,11 +151,10 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected val collector: LookupElementsCollector = LookupElementsCollector(
|
protected val collector: LookupElementsCollector = LookupElementsCollector(
|
||||||
prefixMatcher, parameters, resolutionFacade, lookupElementFactory, expression?.getParent() is JetSimpleNameStringTemplateEntry)
|
prefixMatcher, parameters, resolutionFacade, lookupElementFactory, inDescriptor, expression?.getParent() is JetSimpleNameStringTemplateEntry)
|
||||||
|
|
||||||
protected val project: Project = position.getProject()
|
protected val project: Project = position.getProject()
|
||||||
|
|
||||||
|
|
||||||
protected val originalSearchScope: GlobalSearchScope = parameters.getOriginalFile().getResolveScope()
|
protected val originalSearchScope: GlobalSearchScope = parameters.getOriginalFile().getResolveScope()
|
||||||
|
|
||||||
// we need to exclude the original file from scope because our resolve session is built with this file replaced by synthetic one
|
// we need to exclude the original file from scope because our resolve session is built with this file replaced by synthetic one
|
||||||
@@ -378,7 +393,7 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
|||||||
if (expression != null) {
|
if (expression != null) {
|
||||||
val mapper = ToFromOriginalFileMapper(parameters.getOriginalFile() as JetFile, position.getContainingFile() as JetFile, parameters.getOffset())
|
val mapper = ToFromOriginalFileMapper(parameters.getOriginalFile() as JetFile, position.getContainingFile() as JetFile, parameters.getOffset())
|
||||||
val completion = SmartCompletion(expression, resolutionFacade, moduleDescriptor,
|
val completion = SmartCompletion(expression, resolutionFacade, moduleDescriptor,
|
||||||
bindingContext!!, { isVisibleDescriptor(it) }, prefixMatcher, originalSearchScope,
|
bindingContext!!, { isVisibleDescriptor(it) }, inDescriptor, prefixMatcher, originalSearchScope,
|
||||||
mapper, lookupElementFactory)
|
mapper, lookupElementFactory)
|
||||||
val result = completion.execute()
|
val result = completion.execute()
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
|
|||||||
@@ -16,58 +16,38 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.completion
|
package org.jetbrains.kotlin.idea.completion
|
||||||
|
|
||||||
import com.intellij.openapi.util.Key
|
|
||||||
import com.intellij.codeInsight.lookup.LookupElement
|
|
||||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy
|
|
||||||
import com.intellij.openapi.progress.ProcessCanceledException
|
|
||||||
import com.intellij.codeInsight.completion.CompletionService
|
|
||||||
import com.intellij.codeInsight.completion.CompletionProgressIndicator
|
import com.intellij.codeInsight.completion.CompletionProgressIndicator
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import com.intellij.codeInsight.completion.CompletionService
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
|
||||||
import com.intellij.codeInsight.completion.PrefixMatcher
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
|
||||||
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
|
||||||
import com.intellij.codeInsight.completion.InsertionContext
|
import com.intellij.codeInsight.completion.InsertionContext
|
||||||
import org.jetbrains.kotlin.idea.completion.handlers.CastReceiverInsertHandler
|
import com.intellij.codeInsight.completion.PrefixMatcher
|
||||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
import com.intellij.codeInsight.lookup.*
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import com.intellij.openapi.progress.ProcessCanceledException
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
import com.intellij.openapi.util.Key
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import com.intellij.util.PlatformIcons
|
||||||
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
|
||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
|
||||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
|
||||||
import org.jetbrains.kotlin.psi.JetFunctionLiteral
|
|
||||||
import org.jetbrains.kotlin.psi.JetFunctionLiteralExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetValueArgument
|
|
||||||
import org.jetbrains.kotlin.psi.JetValueArgumentList
|
|
||||||
import org.jetbrains.kotlin.psi.JetCallExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetExpression
|
|
||||||
import java.util.ArrayList
|
|
||||||
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance
|
|
||||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
|
||||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
|
||||||
import org.jetbrains.kotlin.psi.JetLabeledExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetElement
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
|
||||||
import org.jetbrains.kotlin.psi.JetReferenceExpression
|
|
||||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.psi.JetDeclarationWithBody
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
|
||||||
|
import org.jetbrains.kotlin.idea.completion.handlers.CastReceiverInsertHandler
|
||||||
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
|
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
|
||||||
import org.jetbrains.kotlin.psi.JetLoopExpression
|
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRendererBuilder
|
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance
|
||||||
import org.jetbrains.kotlin.renderer.NameShortness
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||||
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
enum class ItemPriority {
|
enum class ItemPriority {
|
||||||
MULTIPLE_ARGUMENTS_ITEM
|
MULTIPLE_ARGUMENTS_ITEM
|
||||||
DEFAULT
|
DEFAULT
|
||||||
|
BACKING_FIELD
|
||||||
NAMED_PARAMETER
|
NAMED_PARAMETER
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +101,20 @@ fun rethrowWithCancelIndicator(exception: ProcessCanceledException): ProcessCanc
|
|||||||
return exception
|
return exception
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PrefixMatcher.asNameFilter() = { (name: Name) -> !name.isSpecial() && prefixMatches(name.getIdentifier()) }
|
fun PrefixMatcher.asNameFilter() = { (name: Name) ->
|
||||||
|
if (name.isSpecial()) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val identifier = name.getIdentifier()
|
||||||
|
if (getPrefix().startsWith("$")) { // we need properties from scope for backing field completion
|
||||||
|
prefixMatches("$" + identifier)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prefixMatches(identifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun LookupElementPresentation.prependTailText(text: String, grayed: Boolean) {
|
fun LookupElementPresentation.prependTailText(text: String, grayed: Boolean) {
|
||||||
val tails = getTailFragments()
|
val tails = getTailFragments()
|
||||||
@@ -354,3 +347,36 @@ fun breakOrContinueExpressionItems(position: JetElement, breakOrContinue: String
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun LookupElementFactory.createBackingFieldLookupElement(
|
||||||
|
property: PropertyDescriptor,
|
||||||
|
inDescriptor: DeclarationDescriptor?,
|
||||||
|
resolutionFacade: ResolutionFacade
|
||||||
|
): LookupElement? {
|
||||||
|
if (inDescriptor == null) return null // no backing field accessible
|
||||||
|
val insideAccessor = inDescriptor is PropertyAccessorDescriptor && inDescriptor.getCorrespondingProperty() == property
|
||||||
|
if (!insideAccessor) {
|
||||||
|
val container = property.getContainingDeclaration()
|
||||||
|
if (container !is ClassDescriptor || !DescriptorUtils.isAncestor(container, inDescriptor, false)) return null // backing field not accessible
|
||||||
|
}
|
||||||
|
|
||||||
|
val declaration = (DescriptorToSourceUtils.descriptorToDeclaration(property) as? JetProperty) ?: return null
|
||||||
|
|
||||||
|
val accessors = declaration.getAccessors()
|
||||||
|
if (accessors.all { it.getBodyExpression() == null }) return null // makes no sense to access backing field - it's the same as accessing property directly
|
||||||
|
|
||||||
|
val bindingContext = resolutionFacade.analyze(declaration)
|
||||||
|
if (!bindingContext[BindingContext.BACKING_FIELD_REQUIRED, property]) return null
|
||||||
|
|
||||||
|
val lookupElement = createLookupElement(resolutionFacade, property, true)
|
||||||
|
return object : LookupElementDecorator<LookupElement>(lookupElement) {
|
||||||
|
override fun getLookupString() = "$" + super.getLookupString()
|
||||||
|
override fun getAllLookupStrings() = setOf(getLookupString())
|
||||||
|
|
||||||
|
override fun renderElement(presentation: LookupElementPresentation) {
|
||||||
|
super.renderElement(presentation)
|
||||||
|
presentation.setItemText("$" + presentation.getItemText())
|
||||||
|
presentation.setIcon(PlatformIcons.FIELD_ICON) //TODO: special icon
|
||||||
|
}
|
||||||
|
}.assignPriority(ItemPriority.BACKING_FIELD)
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,26 +16,28 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.completion
|
package org.jetbrains.kotlin.idea.completion
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.CompletionParameters
|
||||||
|
import com.intellij.codeInsight.completion.CompletionResultSet
|
||||||
import com.intellij.codeInsight.completion.InsertionContext
|
import com.intellij.codeInsight.completion.InsertionContext
|
||||||
|
import com.intellij.codeInsight.completion.PrefixMatcher
|
||||||
import com.intellij.codeInsight.lookup.LookupElement
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
||||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.idea.completion.handlers.*
|
|
||||||
import com.intellij.codeInsight.completion.PrefixMatcher
|
|
||||||
import java.util.ArrayList
|
|
||||||
import com.intellij.codeInsight.completion.CompletionResultSet
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.codeInsight.completion.CompletionParameters
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
|
||||||
|
import org.jetbrains.kotlin.idea.completion.handlers.*
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
class LookupElementsCollector(
|
class LookupElementsCollector(
|
||||||
private val prefixMatcher: PrefixMatcher,
|
private val prefixMatcher: PrefixMatcher,
|
||||||
private val completionParameters: CompletionParameters,
|
private val completionParameters: CompletionParameters,
|
||||||
private val resolutionFacade: ResolutionFacade,
|
private val resolutionFacade: ResolutionFacade,
|
||||||
private val lookupElementFactory: LookupElementFactory,
|
private val lookupElementFactory: LookupElementFactory,
|
||||||
|
private val inDescriptor: DeclarationDescriptor?,
|
||||||
private val surroundCallsWithBraces: Boolean
|
private val surroundCallsWithBraces: Boolean
|
||||||
) {
|
) {
|
||||||
private val elements = ArrayList<LookupElement>()
|
private val elements = ArrayList<LookupElement>()
|
||||||
@@ -114,6 +116,13 @@ class LookupElementsCollector(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (descriptor is PropertyDescriptor) {
|
||||||
|
val lookupElement = lookupElementFactory.createBackingFieldLookupElement(descriptor, inDescriptor, resolutionFacade)
|
||||||
|
if (lookupElement != null) {
|
||||||
|
addElement(lookupElement)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun addElement(element: LookupElement) {
|
public fun addElement(element: LookupElement) {
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ class SmartCompletion(
|
|||||||
val moduleDescriptor: ModuleDescriptor,
|
val moduleDescriptor: ModuleDescriptor,
|
||||||
val bindingContext: BindingContext,
|
val bindingContext: BindingContext,
|
||||||
val visibilityFilter: (DeclarationDescriptor) -> Boolean,
|
val visibilityFilter: (DeclarationDescriptor) -> Boolean,
|
||||||
|
val inDescriptor: DeclarationDescriptor?,
|
||||||
val prefixMatcher: PrefixMatcher,
|
val prefixMatcher: PrefixMatcher,
|
||||||
val inheritorSearchScope: GlobalSearchScope,
|
val inheritorSearchScope: GlobalSearchScope,
|
||||||
val toFromOriginalFileMapper: ToFromOriginalFileMapper,
|
val toFromOriginalFileMapper: ToFromOriginalFileMapper,
|
||||||
@@ -141,11 +142,18 @@ class SmartCompletion(
|
|||||||
|
|
||||||
val result = ArrayList<LookupElement>()
|
val result = ArrayList<LookupElement>()
|
||||||
val types = descriptor.fuzzyTypes(smartCastTypes)
|
val types = descriptor.fuzzyTypes(smartCastTypes)
|
||||||
val classifier = { (expectedInfo: ExpectedInfo) -> types.classifyExpectedInfo(expectedInfo) }
|
val infoClassifier = { (expectedInfo: ExpectedInfo) -> types.classifyExpectedInfo(expectedInfo) }
|
||||||
result.addLookupElements(descriptor, expectedInfos, classifier) { descriptor ->
|
|
||||||
|
result.addLookupElements(descriptor, expectedInfos, infoClassifier) { descriptor ->
|
||||||
lookupElementFactory.createLookupElement(descriptor, resolutionFacade, bindingContext, true)
|
lookupElementFactory.createLookupElement(descriptor, resolutionFacade, bindingContext, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (descriptor is PropertyDescriptor) {
|
||||||
|
result.addLookupElements(descriptor, expectedInfos, infoClassifier) { descriptor ->
|
||||||
|
lookupElementFactory.createBackingFieldLookupElement(descriptor, inDescriptor, resolutionFacade)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (receiver == null) {
|
if (receiver == null) {
|
||||||
toFunctionReferenceLookupElement(descriptor, functionExpectedInfos)?.let { result.add(it) }
|
toFunctionReferenceLookupElement(descriptor, functionExpectedInfos)?.let { result.add(it) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
var globalProperty = "abc" // has backing field and accessor but backing field is not accessible
|
||||||
|
get() = $globalProperty + 1
|
||||||
|
|
||||||
|
class C {
|
||||||
|
var property1 = "abc" // has backing field but accessors are default - no sense to show in completion
|
||||||
|
|
||||||
|
var property2 = "abc" // has backing field but accessors are also default
|
||||||
|
private set
|
||||||
|
|
||||||
|
var property3: String // no backing field
|
||||||
|
get() = "abc"
|
||||||
|
set(value){}
|
||||||
|
|
||||||
|
var property4 = "abc" // has backing field and accessor
|
||||||
|
get() = $property4 + 1
|
||||||
|
|
||||||
|
fun foo(){
|
||||||
|
<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABSENT: $globalProperty
|
||||||
|
// ABSENT: $property1
|
||||||
|
// ABSENT: $property2
|
||||||
|
// ABSENT: $property3
|
||||||
|
// EXIST: { lookupString: "$property4", itemText: "$property4", tailText: null, typeText: "String" }
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
var globalProperty = "abc"
|
||||||
|
get() = <caret>
|
||||||
|
|
||||||
|
// EXIST: $globalProperty
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
class C {
|
||||||
|
var property = "abc"
|
||||||
|
get() = $property + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun foo(c: C){
|
||||||
|
c.<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABSENT: $property
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
class C {
|
||||||
|
var property = "abc"
|
||||||
|
get() = $property + 1
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
this.<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: $property
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
class C {
|
||||||
|
var property1 = "abc"
|
||||||
|
get() = $property1 + 1
|
||||||
|
var property2 = "abc"
|
||||||
|
get() = $property2 + 1
|
||||||
|
|
||||||
|
fun foo(){
|
||||||
|
$<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: $property1
|
||||||
|
// EXIST: $property2
|
||||||
|
// ABSENT: property1
|
||||||
|
// ABSENT: property2
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class C {
|
||||||
|
var aProperty = "abc"
|
||||||
|
get() {}
|
||||||
|
var bProperty = "abc"
|
||||||
|
get() {}
|
||||||
|
|
||||||
|
fun foo(){
|
||||||
|
$a<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: $aProperty
|
||||||
|
// ABSENT: $bProperty
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
class C {
|
||||||
|
var property1 = "abc"
|
||||||
|
get() = $property1 + 1
|
||||||
|
var property2 = "abc"
|
||||||
|
get() = $property2 + 1
|
||||||
|
|
||||||
|
fun foo(){
|
||||||
|
"${$<caret>}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: $property1
|
||||||
|
// EXIST: $property2
|
||||||
|
// ABSENT: property1
|
||||||
|
// ABSENT: property2
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
class C {
|
||||||
|
var property1 = "abc" // has backing field but accessors are default - no sense to show in completion
|
||||||
|
|
||||||
|
var property2: String // no backing field
|
||||||
|
get() = "abc"
|
||||||
|
set(value){}
|
||||||
|
|
||||||
|
var property3 = "abc" // has backing field and accessor
|
||||||
|
get() = $property3 + 1
|
||||||
|
|
||||||
|
var property4 = 1
|
||||||
|
get() = $property4 + 1
|
||||||
|
|
||||||
|
var property5: String? = null
|
||||||
|
get() = $property3 + 1
|
||||||
|
|
||||||
|
fun foo(): String {
|
||||||
|
return <caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABSENT: $property1
|
||||||
|
// ABSENT: $property2
|
||||||
|
// EXIST: $property3
|
||||||
|
// ABSENT: $property4
|
||||||
|
// EXIST: { itemText: "!! $property5" }
|
||||||
|
// EXIST: { itemText: "?: $property5" }
|
||||||
@@ -79,6 +79,48 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/completion/basic/common"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/completion/basic/common"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields1.kt")
|
||||||
|
public void testBackingFields1() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFields1.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields2.kt")
|
||||||
|
public void testBackingFields2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFields2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields3.kt")
|
||||||
|
public void testBackingFields3() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFields3.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields4.kt")
|
||||||
|
public void testBackingFields4() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFields4.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields5.kt")
|
||||||
|
public void testBackingFields5() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFields5.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields6.kt")
|
||||||
|
public void testBackingFields6() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFields6.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFieldsInStringTemplate.kt")
|
||||||
|
public void testBackingFieldsInStringTemplate() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFieldsInStringTemplate.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("BasicAny.kt")
|
@TestMetadata("BasicAny.kt")
|
||||||
public void testBasicAny() throws Exception {
|
public void testBasicAny() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BasicAny.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BasicAny.kt");
|
||||||
|
|||||||
@@ -79,6 +79,48 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/completion/basic/common"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/completion/basic/common"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields1.kt")
|
||||||
|
public void testBackingFields1() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFields1.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields2.kt")
|
||||||
|
public void testBackingFields2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFields2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields3.kt")
|
||||||
|
public void testBackingFields3() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFields3.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields4.kt")
|
||||||
|
public void testBackingFields4() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFields4.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields5.kt")
|
||||||
|
public void testBackingFields5() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFields5.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields6.kt")
|
||||||
|
public void testBackingFields6() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFields6.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFieldsInStringTemplate.kt")
|
||||||
|
public void testBackingFieldsInStringTemplate() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BackingFieldsInStringTemplate.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("BasicAny.kt")
|
@TestMetadata("BasicAny.kt")
|
||||||
public void testBasicAny() throws Exception {
|
public void testBasicAny() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BasicAny.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/BasicAny.kt");
|
||||||
|
|||||||
@@ -66,6 +66,12 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BackingFields.kt")
|
||||||
|
public void testBackingFields() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smart/BackingFields.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("BeforeArgumentWithBinaryOperation.kt")
|
@TestMetadata("BeforeArgumentWithBinaryOperation.kt")
|
||||||
public void testBeforeArgumentWithBinaryOperation() throws Exception {
|
public void testBeforeArgumentWithBinaryOperation() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smart/BeforeArgumentWithBinaryOperation.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/smart/BeforeArgumentWithBinaryOperation.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user