WEB-70390 WebSymbols: lazily evaluate types for code completion

(cherry picked from commit 38c3e555ef3f422904c1e26e14edc3c9df9db84d)

IJ-CR-149824

GitOrigin-RevId: 885e9d7b85880e9f27197dfa281f41f086e436c6
This commit is contained in:
Piotr Tomiak
2024-11-20 11:52:03 +01:00
committed by intellij-monorepo-bot
parent 2b93b6f4ea
commit c3f95a5afd
4 changed files with 276 additions and 77 deletions

View File

@@ -332,7 +332,7 @@
- *sf:Companion:com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem$Companion
- a:addToResult(com.intellij.codeInsight.completion.CompletionParameters,com.intellij.codeInsight.completion.CompletionResultSet,D):V
- bs:addToResult$default(com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem,com.intellij.codeInsight.completion.CompletionParameters,com.intellij.codeInsight.completion.CompletionResultSet,D,I,java.lang.Object):V
- s:create(java.lang.String,I,Z,java.util.Set,java.lang.String,com.intellij.webSymbols.WebSymbol,com.intellij.webSymbols.WebSymbol$Priority,java.lang.Integer,com.intellij.webSymbols.WebSymbolApiStatus,java.util.Set,javax.swing.Icon,java.lang.String,java.lang.String,com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemInsertHandler):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem
- s:create(java.lang.String,I,com.intellij.webSymbols.WebSymbol,kotlin.jvm.functions.Function1):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem
- a:getAliases():java.util.Set
- a:getApiStatus():com.intellij.webSymbols.WebSymbolApiStatus
- a:getCompleteAfterChars():java.util.Set
@@ -371,10 +371,26 @@
- a:withSymbol(com.intellij.webSymbols.WebSymbol):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem
- a:withTailText(java.lang.String):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem
- a:withTypeText(java.lang.String):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem
- a:withTypeText(kotlin.jvm.functions.Function0):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem
*f:com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem$Companion
- f:create(java.lang.String,I,Z,java.util.Set,java.lang.String,com.intellij.webSymbols.WebSymbol,com.intellij.webSymbols.WebSymbol$Priority,java.lang.Integer,com.intellij.webSymbols.WebSymbolApiStatus,java.util.Set,javax.swing.Icon,java.lang.String,java.lang.String,com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemInsertHandler):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem
- bs:create$default(com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem$Companion,java.lang.String,I,Z,java.util.Set,java.lang.String,com.intellij.webSymbols.WebSymbol,com.intellij.webSymbols.WebSymbol$Priority,java.lang.Integer,com.intellij.webSymbols.WebSymbolApiStatus,java.util.Set,javax.swing.Icon,java.lang.String,java.lang.String,com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemInsertHandler,I,java.lang.Object):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem
- f:create(java.lang.String,I,com.intellij.webSymbols.WebSymbol,kotlin.jvm.functions.Function1):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem
- bs:create$default(com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem$Companion,java.lang.String,I,com.intellij.webSymbols.WebSymbol,kotlin.jvm.functions.Function1,I,java.lang.Object):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem
- f:getPsiElement(com.intellij.codeInsight.lookup.LookupElement):com.intellij.psi.PsiElement
*:com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:aliases(java.util.Set):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:apiStatus(com.intellij.webSymbols.WebSymbolApiStatus):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:completeAfterChars(java.util.Set):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:completeAfterInsert(Z):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:displayName(java.lang.String):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:icon(javax.swing.Icon):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:insertHandler(com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemInsertHandler):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:offset(I):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:priority(com.intellij.webSymbols.WebSymbol$Priority):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:proximity(java.lang.Integer):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:symbol(com.intellij.webSymbols.WebSymbol):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:tailText(java.lang.String):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:typeText(java.lang.String):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
- a:typeText(kotlin.jvm.functions.Function0):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
*:com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemCustomizer
- *sf:Companion:com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemCustomizer$Companion
- a:customize(com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem,java.lang.String,com.intellij.webSymbols.WebSymbolQualifiedKind,com.intellij.psi.PsiElement):com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem

View File

@@ -12,6 +12,7 @@ import com.intellij.webSymbols.WebSymbol
import com.intellij.webSymbols.WebSymbolApiStatus
import com.intellij.webSymbols.completion.impl.WebSymbolCodeCompletionItemImpl
import com.intellij.webSymbols.query.WebSymbolDefaultIconProvider
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.ApiStatus.NonExtendable
import javax.swing.Icon
@@ -41,9 +42,11 @@ interface WebSymbolCodeCompletionItem {
fun withPrefix(prefix: String): WebSymbolCodeCompletionItem
fun addToResult(parameters: CompletionParameters,
result: CompletionResultSet,
baselinePriorityValue: Double = WebSymbol.Priority.NORMAL.value)
fun addToResult(
parameters: CompletionParameters,
result: CompletionResultSet,
baselinePriorityValue: Double = WebSymbol.Priority.NORMAL.value,
)
fun withName(name: String): WebSymbolCodeCompletionItem
@@ -71,6 +74,8 @@ interface WebSymbolCodeCompletionItem {
fun withTypeText(typeText: String?): WebSymbolCodeCompletionItem
fun withTypeText(typeTextProvider: () -> String?): WebSymbolCodeCompletionItem
fun withTailText(tailText: String?): WebSymbolCodeCompletionItem
fun withCompleteAfterChar(char: Char): WebSymbolCodeCompletionItem
@@ -79,47 +84,71 @@ interface WebSymbolCodeCompletionItem {
fun withInsertHandlerReplaced(insertHandler: WebSymbolCodeCompletionItemInsertHandler?): WebSymbolCodeCompletionItem
fun withInsertHandlerAdded(insertHandler: InsertHandler<LookupElement>,
priority: WebSymbol.Priority = WebSymbol.Priority.NORMAL): WebSymbolCodeCompletionItem
fun withInsertHandlerAdded(
insertHandler: InsertHandler<LookupElement>,
priority: WebSymbol.Priority = WebSymbol.Priority.NORMAL,
): WebSymbolCodeCompletionItem
fun withInsertHandlerAdded(insertHandler: WebSymbolCodeCompletionItemInsertHandler): WebSymbolCodeCompletionItem
fun with(name: String = this.name,
offset: Int = this.offset,
completeAfterInsert: Boolean = this.completeAfterInsert,
completeAfterChars: Set<Char> = this.completeAfterChars,
displayName: String? = this.displayName,
symbol: WebSymbol? = this.symbol,
priority: WebSymbol.Priority? = this.priority,
proximity: Int? = this.proximity,
apiStatus: WebSymbolApiStatus = this.apiStatus,
icon: Icon? = this.icon,
typeText: String? = this.typeText,
tailText: String? = this.tailText): WebSymbolCodeCompletionItem
fun with(
name: String = this.name,
offset: Int = this.offset,
completeAfterInsert: Boolean = this.completeAfterInsert,
completeAfterChars: Set<Char> = this.completeAfterChars,
displayName: String? = this.displayName,
symbol: WebSymbol? = this.symbol,
priority: WebSymbol.Priority? = this.priority,
proximity: Int? = this.proximity,
apiStatus: WebSymbolApiStatus = this.apiStatus,
icon: Icon? = this.icon,
typeText: String? = null,
tailText: String? = this.tailText,
): WebSymbolCodeCompletionItem
companion object {
@ApiStatus.Internal
fun create(
name: String,
offset: Int = 0,
completeAfterInsert: Boolean = false,
completeAfterChars: Set<Char>? = null,
displayName: String? = null,
symbol: WebSymbol? = null,
priority: WebSymbol.Priority? = null,
proximity: Int? = null,
apiStatus: WebSymbolApiStatus? = null,
aliases: Set<String>? = null,
icon: Icon? = null,
typeText: String? = null,
tailText: String? = null,
insertHandler: WebSymbolCodeCompletionItemInsertHandler? = null,
): WebSymbolCodeCompletionItem =
create(name, offset, symbol) {
completeAfterInsert(completeAfterInsert)
completeAfterChars?.let { completeAfterChars(it) }
displayName(displayName)
priority?.let { priority(it) }
proximity?.let { proximity(it) }
apiStatus?.let { apiStatus(it) }
aliases?.let { aliases(it) }
icon?.let { icon(it) }
typeText?.let { typeText(it) }
tailText?.let { tailText(it) }
insertHandler?.let { insertHandler(it) }
}
@JvmStatic
fun create(name: String,
offset: Int = 0,
completeAfterInsert: Boolean = false,
completeAfterChars: Set<Char> = emptySet(),
displayName: String? = null,
symbol: WebSymbol? = null,
priority: WebSymbol.Priority? = symbol?.priority,
proximity: Int? = symbol?.proximity,
apiStatus: WebSymbolApiStatus = symbol?.apiStatus ?: WebSymbolApiStatus.Stable,
aliases: Set<String> = emptySet(),
icon: Icon? = symbol?.let {
it.icon
?: it.origin.defaultIcon
?: WebSymbolDefaultIconProvider.get(it.namespace, it.kind)
},
typeText: String? = null,
tailText: String? = null,
insertHandler: WebSymbolCodeCompletionItemInsertHandler? = null): WebSymbolCodeCompletionItem =
WebSymbolCodeCompletionItemImpl(name, offset, completeAfterInsert, if (!completeAfterInsert) completeAfterChars else emptySet(),
displayName, symbol, priority, proximity,
apiStatus, aliases, icon, typeText, tailText, insertHandler)
fun create(
name: String,
offset: Int = 0,
symbol: WebSymbol? = null,
builder: (WebSymbolCodeCompletionItemBuilder.() -> Unit)? = null,
): WebSymbolCodeCompletionItem =
WebSymbolCodeCompletionItemImpl.BuilderImpl(name, offset, symbol)
.also { builder?.invoke(it) }
.build()
@JvmStatic
fun getPsiElement(lookupElement: LookupElement): PsiElement? =

View File

@@ -0,0 +1,25 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.webSymbols.completion
import com.intellij.webSymbols.WebSymbol
import com.intellij.webSymbols.WebSymbolApiStatus
import javax.swing.Icon
interface WebSymbolCodeCompletionItemBuilder {
fun displayName(value: String?): WebSymbolCodeCompletionItemBuilder
fun offset(value: Int): WebSymbolCodeCompletionItemBuilder
fun icon(value: Icon?): WebSymbolCodeCompletionItemBuilder
fun typeText(value: String?): WebSymbolCodeCompletionItemBuilder
fun typeText(provider: () -> String?): WebSymbolCodeCompletionItemBuilder
fun tailText(value: String?): WebSymbolCodeCompletionItemBuilder
fun completeAfterInsert(value: Boolean): WebSymbolCodeCompletionItemBuilder
fun completeAfterChars(value: Set<Char>): WebSymbolCodeCompletionItemBuilder
fun priority(value: WebSymbol.Priority?): WebSymbolCodeCompletionItemBuilder
fun proximity(value: Int?): WebSymbolCodeCompletionItemBuilder
fun apiStatus(value: WebSymbolApiStatus): WebSymbolCodeCompletionItemBuilder
fun aliases(value: Set<String>): WebSymbolCodeCompletionItemBuilder
fun symbol(value: WebSymbol?): WebSymbolCodeCompletionItemBuilder
fun insertHandler(value: WebSymbolCodeCompletionItemInsertHandler?): WebSymbolCodeCompletionItemBuilder
}

View File

@@ -5,37 +5,48 @@ import com.intellij.codeInsight.completion.*
import com.intellij.codeInsight.lookup.AutoCompletionPolicy
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.codeInsight.lookup.LookupElementPresentation
import com.intellij.codeInsight.lookup.LookupElementRenderer
import com.intellij.psi.PsiElement
import com.intellij.webSymbols.PsiSourcedWebSymbol
import com.intellij.webSymbols.WebSymbol
import com.intellij.webSymbols.WebSymbolApiStatus
import com.intellij.webSymbols.WebSymbolApiStatus.Companion.isDeprecatedOrObsolete
import com.intellij.webSymbols.completion.WebSymbolCodeCompletionItem
import com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemBuilder
import com.intellij.webSymbols.completion.WebSymbolCodeCompletionItemInsertHandler
import com.intellij.webSymbols.impl.scaleToHeight
import com.intellij.webSymbols.query.WebSymbolDefaultIconProvider
import org.jetbrains.annotations.ApiStatus
import javax.swing.Icon
internal data class WebSymbolCodeCompletionItemImpl(override val name: String,
override val offset: Int = 0,
override val completeAfterInsert: Boolean = false,
override val completeAfterChars: Set<Char> = emptySet(),
override val displayName: String? = null,
override val symbol: WebSymbol? = null,
override val priority: WebSymbol.Priority? = null,
override val proximity: Int? = null,
override val apiStatus: WebSymbolApiStatus = WebSymbolApiStatus.Stable,
override val aliases: Set<String> = emptySet(),
override val icon: Icon? = null,
override val typeText: String? = null,
override val tailText: String? = null,
override val insertHandler: WebSymbolCodeCompletionItemInsertHandler? = null,
@get:ApiStatus.Internal
val stopSequencePatternEvaluation: Boolean = false) : WebSymbolCodeCompletionItem {
internal data class WebSymbolCodeCompletionItemImpl(
override val name: String,
override val offset: Int = 0,
override val completeAfterInsert: Boolean = false,
override val completeAfterChars: Set<Char> = emptySet(),
override val displayName: String? = null,
override val symbol: WebSymbol? = null,
override val priority: WebSymbol.Priority? = null,
override val proximity: Int? = null,
override val apiStatus: WebSymbolApiStatus = WebSymbolApiStatus.Stable,
override val aliases: Set<String> = emptySet(),
override val icon: Icon? = null,
val typeTextStatic: String? = null,
val typeTextProvider: (() -> String?)? = null,
override val tailText: String? = null,
override val insertHandler: WebSymbolCodeCompletionItemInsertHandler? = null,
@get:ApiStatus.Internal
val stopSequencePatternEvaluation: Boolean = false,
) : WebSymbolCodeCompletionItem {
override fun addToResult(parameters: CompletionParameters,
result: CompletionResultSet,
baselinePriorityValue: Double) {
override val typeText: String? get() = typeTextProvider?.invoke() ?: typeTextStatic
override fun addToResult(
parameters: CompletionParameters,
result: CompletionResultSet,
baselinePriorityValue: Double,
) {
val completionPrefixMatcher = result.prefixMatcher
val completionPrefix = completionPrefixMatcher.prefix
if (completionPrefix.length < offset ||
@@ -47,7 +58,17 @@ internal data class WebSymbolCodeCompletionItemImpl(override val name: String,
.create(wrapSymbolForDocumentation(symbol, parameters.position)?.createPointer() ?: name, name)
.withLookupStrings(aliases)
.withIcon(icon?.scaleToHeight(16))
.withTypeText(typeText, true)
.withTypeText(typeTextStatic, true)
.let {
if (typeTextProvider != null)
it.withExpensiveRenderer(object : LookupElementRenderer<LookupElement>() {
override fun renderElement(element: LookupElement, presentation: LookupElementPresentation) {
element.renderElement(presentation)
typeTextProvider()?.let { presentation.typeText = it }
}
})
else it
}
.withTailText(tailText, true)
.withBoldness(!deprecatedOrObsolete && priority == WebSymbol.Priority.HIGHEST)
.withStrikeoutness(deprecatedOrObsolete)
@@ -136,7 +157,10 @@ internal data class WebSymbolCodeCompletionItemImpl(override val name: String,
copy(icon = icon)
override fun withTypeText(typeText: String?): WebSymbolCodeCompletionItem =
copy(typeText = typeText)
copy(typeTextStatic = typeText)
override fun withTypeText(typeTextProvider: () -> String?): WebSymbolCodeCompletionItem =
copy(typeTextProvider = typeTextProvider)
override fun withTailText(tailText: String?): WebSymbolCodeCompletionItem =
copy(tailText = tailText)
@@ -150,28 +174,133 @@ internal data class WebSymbolCodeCompletionItemImpl(override val name: String,
override fun withInsertHandlerReplaced(insertHandler: WebSymbolCodeCompletionItemInsertHandler?): WebSymbolCodeCompletionItem =
copy(insertHandler = insertHandler)
override fun withInsertHandlerAdded(insertHandler: InsertHandler<LookupElement>,
priority: WebSymbol.Priority): WebSymbolCodeCompletionItem =
override fun withInsertHandlerAdded(
insertHandler: InsertHandler<LookupElement>,
priority: WebSymbol.Priority,
): WebSymbolCodeCompletionItem =
withInsertHandlerAdded(WebSymbolCodeCompletionItemInsertHandler.adapt(insertHandler, priority))
override fun withInsertHandlerAdded(insertHandler: WebSymbolCodeCompletionItemInsertHandler): WebSymbolCodeCompletionItem =
copy(insertHandler = CompoundInsertHandler.merge(this.insertHandler, insertHandler))
override fun with(name: String,
offset: Int,
completeAfterInsert: Boolean,
completeAfterChars: Set<Char>,
displayName: String?,
symbol: WebSymbol?,
priority: WebSymbol.Priority?,
proximity: Int?,
apiStatus: WebSymbolApiStatus,
icon: Icon?,
typeText: String?,
tailText: String?): WebSymbolCodeCompletionItem =
override fun with(
name: String,
offset: Int,
completeAfterInsert: Boolean,
completeAfterChars: Set<Char>,
displayName: String?,
symbol: WebSymbol?,
priority: WebSymbol.Priority?,
proximity: Int?,
apiStatus: WebSymbolApiStatus,
icon: Icon?,
typeText: String?,
tailText: String?,
): WebSymbolCodeCompletionItem =
copy(name = name, offset = offset, completeAfterInsert = completeAfterInsert,
completeAfterChars = if (!completeAfterInsert) completeAfterChars else emptySet(),
displayName = displayName, symbol = symbol, priority = priority, proximity = proximity,
apiStatus = apiStatus, icon = icon, typeText = typeText, tailText = tailText)
apiStatus = apiStatus, icon = icon, typeTextStatic = typeText ?: typeTextStatic,
tailText = tailText)
class BuilderImpl(
private var name: String,
private var offset: Int = 0,
private var symbol: WebSymbol? = null,
) : WebSymbolCodeCompletionItemBuilder {
private var completeAfterInsert: Boolean = false
private var completeAfterChars: Set<Char> = emptySet()
private var displayName: String? = null
private var priority: WebSymbol.Priority? = symbol?.priority
private var proximity: Int? = symbol?.proximity
private var apiStatus: WebSymbolApiStatus = symbol?.apiStatus ?: WebSymbolApiStatus.Stable
private var aliases: Set<String> = emptySet()
private var icon: Icon? = symbol?.let {
it.icon
?: it.origin.defaultIcon
?: WebSymbolDefaultIconProvider.get(it.namespace, it.kind)
}
private var typeTextStatic: String? = null
private var typeTextProvider: (() -> String?)? = null
private var tailText: String? = null
private var insertHandler: WebSymbolCodeCompletionItemInsertHandler? = null
private var stopSequencePatternEvaluation: Boolean = false
fun build(): WebSymbolCodeCompletionItem = WebSymbolCodeCompletionItemImpl(
name, offset, completeAfterInsert, completeAfterChars, displayName, symbol, priority, proximity,
apiStatus, aliases, icon, typeTextStatic, typeTextProvider, tailText, insertHandler, stopSequencePatternEvaluation)
override fun displayName(value: String?): WebSymbolCodeCompletionItemBuilder {
displayName = value
return this
}
override fun offset(value: Int): WebSymbolCodeCompletionItemBuilder {
offset = value
return this
}
override fun icon(value: Icon?): WebSymbolCodeCompletionItemBuilder {
icon = value
return this
}
override fun typeText(value: String?): WebSymbolCodeCompletionItemBuilder {
typeTextStatic = value
return this
}
override fun typeText(provider: () -> String?): WebSymbolCodeCompletionItemBuilder {
typeTextProvider = provider
return this
}
override fun tailText(value: String?): WebSymbolCodeCompletionItemBuilder {
tailText = value
return this
}
override fun completeAfterInsert(value: Boolean): WebSymbolCodeCompletionItemBuilder {
completeAfterInsert = value
return this
}
override fun completeAfterChars(value: Set<Char>): WebSymbolCodeCompletionItemBuilder {
completeAfterChars = value
return this
}
override fun priority(value: WebSymbol.Priority?): WebSymbolCodeCompletionItemBuilder {
priority = value
return this
}
override fun proximity(value: Int?): WebSymbolCodeCompletionItemBuilder {
proximity = value
return this
}
override fun apiStatus(value: WebSymbolApiStatus): WebSymbolCodeCompletionItemBuilder {
apiStatus = value
return this
}
override fun aliases(value: Set<String>): WebSymbolCodeCompletionItemBuilder {
aliases = value
return this
}
override fun symbol(value: WebSymbol?): WebSymbolCodeCompletionItemBuilder {
symbol = value
return this
}
override fun insertHandler(value: WebSymbolCodeCompletionItemInsertHandler?): WebSymbolCodeCompletionItemBuilder {
insertHandler = value
return this
}
}
}