mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IJPL-252099 measure the accepted range against the frontend item pattern
Accepting a completion could leave the leading typed characters in the document (`de` + `default=` -> `dedefault=`). While a fresh request is in flight the frontend keeps the popup populated from an older request's items, re-matched against the prefix typed since (seedStaleAndSwap), and swaps them out via a restart once the fresh results land. Accepting before that restart commits an item whose backend matcher is shorter than the document prefix, and the race cannot be closed -- the user may accept at any instant -- so the accept itself has to be correct. The replaced range comes from the mirror arranger's itemPattern, which LookupArranger composes as registeredMatcherPrefix + myAdditionalPrefix. On the mirror those halves sync from different sources: the matcher from the request that produced the item, the additional prefix refreshed from the lookup on every arranger swap (refreshUi -> checkReused -> prefixChanged). Composing them is wrong in both directions -- too short while the matcher lags, and too long once the matcher is extended to the full prefix, which then swallows a space of the indent. ItemSelected therefore carries the frontend lookup's own pattern, the one string the frontend actually measured against. It is optional so a client/host version skew degrades to the previous behaviour. The mirror pins it for the committed item and returns it verbatim from itemPattern rather than rebuilding it; the matcher is still re-registered so case correction agrees with the pattern, but it no longer influences the range. An item that does not match the reported pattern is not inserted at all -- a missing completion is recoverable, a mangled one is not. The added distributed test has not been seen green: locally the lookup is torn down before its assertions by unrelated focus and completion-phase events, so it needs a CI run. (cherry picked from commit 5a9e3e26e59487027f28284dd8e3eecb2d890c55) GitOrigin-RevId: fdb36d633cfca8d7de708f8f16824110ea9c1672
This commit is contained in:
committed by
intellij-monorepo-bot
parent
cee3a88548
commit
3f3348b08a
@@ -49,17 +49,28 @@ sealed interface RpcLookupElementEvent {
|
||||
* older request when this event is handled (IJPL-252099 — the frontend swaps a stale-seeded request for a fresh one
|
||||
* right before the accept). Resolving against the arranger's own session instead would fail to find the item and
|
||||
* insert one carrying a shorter prefix matcher, leaving the leading typed characters in the document.
|
||||
*
|
||||
* [itemPattern] is the prefix the *frontend* lookup matched the chosen element against
|
||||
* (`Lookup.itemPattern`), and it is the authoritative measure of the range the insertion must replace: the frontend
|
||||
* owns the lookup, so it owns the lookup start offset. It can be **longer** than the matcher the backend stored for
|
||||
* the item — a stale-seeded placeholder shows an older request's items re-matched against the prefix typed since
|
||||
* (`FrontendCompletionRequestSessionImpl.seedStaleAndSwap`), and accepting one before the swap-restart lands would
|
||||
* otherwise measure the replaced range against the older, shorter matcher and duplicate the leading typed characters
|
||||
* (IJPL-252099). `null` means "no pattern reported" (nothing chosen, or an older frontend), in which case the backend
|
||||
* keeps using the item's own matcher.
|
||||
*/
|
||||
@Serializable
|
||||
data class ItemSelected(
|
||||
val projectId: ProjectId,
|
||||
val requestId: RpcCompletionRequestId,
|
||||
val selectedItemId: RpcCompletionItemId? = null,
|
||||
val itemPattern: String? = null,
|
||||
) : RpcLookupElementEvent {
|
||||
override fun toString(): String = buildToString("ItemSelected") {
|
||||
field("projectId", projectId)
|
||||
field("requestId", requestId)
|
||||
fieldWithNullDefault("selectedItemId", selectedItemId)
|
||||
fieldWithNullDefault("itemPattern", itemPattern)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user