CompletionUtils: cleanup code
This commit is contained in:
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
*
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.completion
|
package org.jetbrains.kotlin.idea.completion
|
||||||
@@ -52,8 +41,7 @@ import java.util.*
|
|||||||
tailrec fun <T : Any> LookupElement.putUserDataDeep(key: Key<T>, value: T?) {
|
tailrec fun <T : Any> LookupElement.putUserDataDeep(key: Key<T>, value: T?) {
|
||||||
if (this is LookupElementDecorator<*>) {
|
if (this is LookupElementDecorator<*>) {
|
||||||
getDelegate().putUserDataDeep(key, value)
|
getDelegate().putUserDataDeep(key, value)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
putUserData(key, value)
|
putUserData(key, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,8 +49,7 @@ tailrec fun <T : Any> LookupElement.putUserDataDeep(key: Key<T>, value: T?) {
|
|||||||
tailrec fun <T : Any> LookupElement.getUserDataDeep(key: Key<T>): T? {
|
tailrec fun <T : Any> LookupElement.getUserDataDeep(key: Key<T>): T? {
|
||||||
return if (this is LookupElementDecorator<*>) {
|
return if (this is LookupElementDecorator<*>) {
|
||||||
getDelegate().getUserDataDeep(key)
|
getDelegate().getUserDataDeep(key)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
getUserData(key)
|
getUserData(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +80,7 @@ val NOT_IMPORTED_KEY = Key<Unit>("NOT_IMPORTED_KEY")
|
|||||||
fun LookupElement.suppressAutoInsertion() = AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(this)
|
fun LookupElement.suppressAutoInsertion() = AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(this)
|
||||||
|
|
||||||
fun LookupElement.withReceiverCast(): LookupElement {
|
fun LookupElement.withReceiverCast(): LookupElement {
|
||||||
return object: LookupElementDecorator<LookupElement>(this) {
|
return object : LookupElementDecorator<LookupElement>(this) {
|
||||||
override fun handleInsert(context: InsertionContext) {
|
override fun handleInsert(context: InsertionContext) {
|
||||||
super.handleInsert(context)
|
super.handleInsert(context)
|
||||||
CastReceiverInsertHandler.postHandleInsert(context, delegate)
|
CastReceiverInsertHandler.postHandleInsert(context, delegate)
|
||||||
@@ -118,8 +105,7 @@ fun ((String) -> Boolean).toNameFilter(): (Name) -> Boolean {
|
|||||||
return { name -> !name.isSpecial && this(name.identifier) }
|
return { name -> !name.isSpecial && this(name.identifier) }
|
||||||
}
|
}
|
||||||
|
|
||||||
infix fun <T> ((T) -> Boolean).or(otherFilter: (T) -> Boolean): (T) -> Boolean
|
infix fun <T> ((T) -> Boolean).or(otherFilter: (T) -> Boolean): (T) -> Boolean = { this(it) || otherFilter(it) }
|
||||||
= { this(it) || otherFilter(it) }
|
|
||||||
|
|
||||||
fun LookupElementPresentation.prependTailText(text: String, grayed: Boolean) {
|
fun LookupElementPresentation.prependTailText(text: String, grayed: Boolean) {
|
||||||
val tails = tailFragments
|
val tails = tailFragments
|
||||||
@@ -172,9 +158,14 @@ fun shouldCompleteThisItems(prefixMatcher: PrefixMatcher): Boolean {
|
|||||||
class ThisItemLookupObject(val receiverParameter: ReceiverParameterDescriptor, val labelName: Name?) : KeywordLookupObject()
|
class ThisItemLookupObject(val receiverParameter: ReceiverParameterDescriptor, val labelName: Name?) : KeywordLookupObject()
|
||||||
|
|
||||||
fun ThisItemLookupObject.createLookupElement() = createKeywordElement("this", labelName.labelNameToTail(), lookupObject = this)
|
fun ThisItemLookupObject.createLookupElement() = createKeywordElement("this", labelName.labelNameToTail(), lookupObject = this)
|
||||||
.withTypeText(BasicLookupElementFactory.SHORT_NAMES_RENDERER.renderType(receiverParameter.type))
|
.withTypeText(BasicLookupElementFactory.SHORT_NAMES_RENDERER.renderType(receiverParameter.type))
|
||||||
|
|
||||||
fun thisExpressionItems(bindingContext: BindingContext, position: KtExpression, prefix: String, resolutionFacade: ResolutionFacade): Collection<ThisItemLookupObject> {
|
fun thisExpressionItems(
|
||||||
|
bindingContext: BindingContext,
|
||||||
|
position: KtExpression,
|
||||||
|
prefix: String,
|
||||||
|
resolutionFacade: ResolutionFacade
|
||||||
|
): Collection<ThisItemLookupObject> {
|
||||||
val scope = position.getResolutionScope(bindingContext, resolutionFacade)
|
val scope = position.getResolutionScope(bindingContext, resolutionFacade)
|
||||||
|
|
||||||
val psiFactory = KtPsiFactory(position)
|
val psiFactory = KtPsiFactory(position)
|
||||||
@@ -183,7 +174,8 @@ fun thisExpressionItems(bindingContext: BindingContext, position: KtExpression,
|
|||||||
for ((receiver, expressionFactory) in scope.getImplicitReceiversWithInstanceToExpression()) {
|
for ((receiver, expressionFactory) in scope.getImplicitReceiversWithInstanceToExpression()) {
|
||||||
if (expressionFactory == null) continue
|
if (expressionFactory == null) continue
|
||||||
// if prefix does not start with "this@" do not include immediate this in the form with label
|
// if prefix does not start with "this@" do not include immediate this in the form with label
|
||||||
val expression = expressionFactory.createExpression(psiFactory, shortThis = !prefix.startsWith("this@")) as? KtThisExpression ?: continue
|
val expression =
|
||||||
|
expressionFactory.createExpression(psiFactory, shortThis = !prefix.startsWith("this@")) as? KtThisExpression ?: continue
|
||||||
result.add(ThisItemLookupObject(receiver, expression.getLabelNameAsName()))
|
result.add(ThisItemLookupObject(receiver, expression.getLabelNameAsName()))
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@@ -204,8 +196,7 @@ fun returnExpressionItems(bindingContext: BindingContext, position: KtElement):
|
|||||||
// check if the current function literal is inlined and stop processing outer declarations if it's not
|
// check if the current function literal is inlined and stop processing outer declarations if it's not
|
||||||
val callee = call?.calleeExpression as? KtReferenceExpression ?: break // not inlined
|
val callee = call?.calleeExpression as? KtReferenceExpression ?: break // not inlined
|
||||||
if (!InlineUtil.isInline(bindingContext[BindingContext.REFERENCE_TARGET, callee])) break // not inlined
|
if (!InlineUtil.isInline(bindingContext[BindingContext.REFERENCE_TARGET, callee])) break // not inlined
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (parent.hasBlockBody()) {
|
if (parent.hasBlockBody()) {
|
||||||
result.add(createKeywordElementWithSpace("return", addSpaceAfter = !isUnit))
|
result.add(createKeywordElementWithSpace("return", addSpaceAfter = !isUnit))
|
||||||
|
|
||||||
@@ -217,11 +208,12 @@ fun returnExpressionItems(bindingContext: BindingContext, position: KtElement):
|
|||||||
if (KotlinBuiltIns.isBooleanOrNullableBoolean(returnType)) {
|
if (KotlinBuiltIns.isBooleanOrNullableBoolean(returnType)) {
|
||||||
result.add(createKeywordElement("return true"))
|
result.add(createKeywordElement("return true"))
|
||||||
result.add(createKeywordElement("return false"))
|
result.add(createKeywordElement("return false"))
|
||||||
}
|
} else if (KotlinBuiltIns.isCollectionOrNullableCollection(returnType) || KotlinBuiltIns.isListOrNullableList(
|
||||||
else if (KotlinBuiltIns.isCollectionOrNullableCollection(returnType) || KotlinBuiltIns.isListOrNullableList(returnType) || KotlinBuiltIns.isIterableOrNullableIterable(returnType)) {
|
returnType
|
||||||
|
) || KotlinBuiltIns.isIterableOrNullableIterable(returnType)
|
||||||
|
) {
|
||||||
result.add(createKeywordElement("return", tail = " emptyList()"))
|
result.add(createKeywordElement("return", tail = " emptyList()"))
|
||||||
}
|
} else if (KotlinBuiltIns.isSetOrNullableSet(returnType)) {
|
||||||
else if (KotlinBuiltIns.isSetOrNullableSet(returnType)) {
|
|
||||||
result.add(createKeywordElement("return", tail = " emptySet()"))
|
result.add(createKeywordElement("return", tail = " emptySet()"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,28 +233,27 @@ private fun KtDeclarationWithBody.returnType(bindingContext: BindingContext): Ko
|
|||||||
private fun Name?.labelNameToTail(): String = if (this != null) "@" + render() else ""
|
private fun Name?.labelNameToTail(): String = if (this != null) "@" + render() else ""
|
||||||
|
|
||||||
private fun createKeywordElementWithSpace(
|
private fun createKeywordElementWithSpace(
|
||||||
keyword: String,
|
keyword: String,
|
||||||
tail: String = "",
|
tail: String = "",
|
||||||
addSpaceAfter: Boolean = false,
|
addSpaceAfter: Boolean = false,
|
||||||
lookupObject: KeywordLookupObject = KeywordLookupObject()
|
lookupObject: KeywordLookupObject = KeywordLookupObject()
|
||||||
): LookupElement {
|
): LookupElement {
|
||||||
val element = createKeywordElement(keyword, tail, lookupObject)
|
val element = createKeywordElement(keyword, tail, lookupObject)
|
||||||
return if (addSpaceAfter) {
|
return if (addSpaceAfter) {
|
||||||
object: LookupElementDecorator<LookupElement>(element) {
|
object : LookupElementDecorator<LookupElement>(element) {
|
||||||
override fun handleInsert(context: InsertionContext) {
|
override fun handleInsert(context: InsertionContext) {
|
||||||
WithTailInsertHandler.SPACE.handleInsert(context, delegate)
|
WithTailInsertHandler.SPACE.handleInsert(context, delegate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
element
|
element
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createKeywordElement(
|
private fun createKeywordElement(
|
||||||
keyword: String,
|
keyword: String,
|
||||||
tail: String = "",
|
tail: String = "",
|
||||||
lookupObject: KeywordLookupObject = KeywordLookupObject()
|
lookupObject: KeywordLookupObject = KeywordLookupObject()
|
||||||
): LookupElementBuilder {
|
): LookupElementBuilder {
|
||||||
var element = LookupElementBuilder.create(lookupObject, keyword + tail)
|
var element = LookupElementBuilder.create(lookupObject, keyword + tail)
|
||||||
element = element.withPresentableText(keyword)
|
element = element.withPresentableText(keyword)
|
||||||
@@ -303,8 +294,7 @@ fun BasicLookupElementFactory.createLookupElementForType(type: KotlinType): Look
|
|||||||
val text = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.renderType(type)
|
val text = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.renderType(type)
|
||||||
val baseLookupElement = LookupElementBuilder.create(text).withIcon(KotlinIcons.LAMBDA)
|
val baseLookupElement = LookupElementBuilder.create(text).withIcon(KotlinIcons.LAMBDA)
|
||||||
BaseTypeLookupElement(type, baseLookupElement)
|
BaseTypeLookupElement(type, baseLookupElement)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val classifier = type.constructor.declarationDescriptor ?: return null
|
val classifier = type.constructor.declarationDescriptor ?: return null
|
||||||
val baseLookupElement = createLookupElement(classifier, qualifyNestedClasses = true, includeClassTypeArguments = false)
|
val baseLookupElement = createLookupElement(classifier, qualifyNestedClasses = true, includeClassTypeArguments = false)
|
||||||
|
|
||||||
@@ -325,7 +315,8 @@ fun BasicLookupElementFactory.createLookupElementForType(type: KotlinType): Look
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private open class BaseTypeLookupElement(type: KotlinType, baseLookupElement: LookupElement) : LookupElementDecorator<LookupElement>(baseLookupElement) {
|
private open class BaseTypeLookupElement(type: KotlinType, baseLookupElement: LookupElement) :
|
||||||
|
LookupElementDecorator<LookupElement>(baseLookupElement) {
|
||||||
val fullText = IdeDescriptorRenderers.SOURCE_CODE.renderType(type)
|
val fullText = IdeDescriptorRenderers.SOURCE_CODE.renderType(type)
|
||||||
|
|
||||||
override fun equals(other: Any?) = other is BaseTypeLookupElement && fullText == other.fullText
|
override fun equals(other: Any?) = other is BaseTypeLookupElement && fullText == other.fullText
|
||||||
@@ -354,8 +345,8 @@ infix fun <T> ElementPattern<T>.or(rhs: ElementPattern<T>) = StandardPatterns.or
|
|||||||
fun singleCharPattern(char: Char) = StandardPatterns.character().equalTo(char)
|
fun singleCharPattern(char: Char) = StandardPatterns.character().equalTo(char)
|
||||||
|
|
||||||
fun LookupElement.decorateAsStaticMember(
|
fun LookupElement.decorateAsStaticMember(
|
||||||
memberDescriptor: DeclarationDescriptor,
|
memberDescriptor: DeclarationDescriptor,
|
||||||
classNameAsLookupString: Boolean
|
classNameAsLookupString: Boolean
|
||||||
): LookupElement? {
|
): LookupElement? {
|
||||||
val container = memberDescriptor.containingDeclaration as? ClassDescriptor ?: return null
|
val container = memberDescriptor.containingDeclaration as? ClassDescriptor ?: return null
|
||||||
val classDescriptor = if (container.isCompanionObject)
|
val classDescriptor = if (container.isCompanionObject)
|
||||||
@@ -366,7 +357,7 @@ fun LookupElement.decorateAsStaticMember(
|
|||||||
val containerFqName = container.importableFqName ?: return null
|
val containerFqName = container.importableFqName ?: return null
|
||||||
val qualifierPresentation = classDescriptor.name.asString()
|
val qualifierPresentation = classDescriptor.name.asString()
|
||||||
|
|
||||||
return object: LookupElementDecorator<LookupElement>(this) {
|
return object : LookupElementDecorator<LookupElement>(this) {
|
||||||
override fun getAllLookupStrings(): Set<String> {
|
override fun getAllLookupStrings(): Set<String> {
|
||||||
return if (classNameAsLookupString) setOf(delegate.lookupString, qualifierPresentation) else super.getAllLookupStrings()
|
return if (classNameAsLookupString) setOf(delegate.lookupString, qualifierPresentation) else super.getAllLookupStrings()
|
||||||
}
|
}
|
||||||
@@ -379,8 +370,7 @@ fun LookupElement.decorateAsStaticMember(
|
|||||||
val tailText = " (" + DescriptorUtils.getFqName(classDescriptor.containingDeclaration) + ")"
|
val tailText = " (" + DescriptorUtils.getFqName(classDescriptor.containingDeclaration) + ")"
|
||||||
if (memberDescriptor is FunctionDescriptor) {
|
if (memberDescriptor is FunctionDescriptor) {
|
||||||
presentation.appendTailText(tailText, true)
|
presentation.appendTailText(tailText, true)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
presentation.setTailText(tailText, true)
|
presentation.setTailText(tailText, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,15 +399,14 @@ fun LookupElement.decorateAsStaticMember(
|
|||||||
fun ImportableFqNameClassifier.isImportableDescriptorImported(descriptor: DeclarationDescriptor): Boolean {
|
fun ImportableFqNameClassifier.isImportableDescriptorImported(descriptor: DeclarationDescriptor): Boolean {
|
||||||
val classification = classify(descriptor.importableFqName!!, false)
|
val classification = classify(descriptor.importableFqName!!, false)
|
||||||
return classification != ImportableFqNameClassifier.Classification.notImported
|
return classification != ImportableFqNameClassifier.Classification.notImported
|
||||||
&& classification != ImportableFqNameClassifier.Classification.siblingImported
|
&& classification != ImportableFqNameClassifier.Classification.siblingImported
|
||||||
}
|
}
|
||||||
|
|
||||||
fun OffsetMap.tryGetOffset(key: OffsetKey): Int? {
|
fun OffsetMap.tryGetOffset(key: OffsetKey): Int? {
|
||||||
try {
|
try {
|
||||||
if (!containsOffset(key)) return null
|
if (!containsOffset(key)) return null
|
||||||
return getOffset(key).takeIf { it != -1 } // prior to IDEA 2016.3 getOffset() returned -1 if not found, now it throws exception
|
return getOffset(key).takeIf { it != -1 } // prior to IDEA 2016.3 getOffset() returned -1 if not found, now it throws exception
|
||||||
}
|
} catch (e: Exception) {
|
||||||
catch(e: Exception) {
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user