Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 21, 2025

Implements the LSP textDocument/semanticTokens/full/delta endpoint for incremental semantic token updates, reducing bandwidth and processing for large files.

Changes Made

Semantic Tokens Delta Support

  • Updated SemanticTokensProvider to support delta computation with resultId tracking using ConcurrentHashMap
  • Implemented semanticTokensFullDelta method in BSLTextDocumentService
  • Updated getSemanticTokensProvider() in BSLLanguageServer to advertise delta support via SemanticTokensServerFull.setDelta(true)
  • Delta algorithm uses prefix/suffix matching to compute minimal edits - when inserting a token in the middle of a document, only the new token is sent (suffix matches correctly because deltaLine values are relative to previous token)
  • Added debug logging to diagnose large deleteCount issues

Document Close Event (AOP)

  • Created ServerContextDocumentClosedEvent class for document close notifications
  • Added isCloseDocumentCall pointcut in Pointcuts.java
  • Added advice in EventPublisherAspect to publish event when ServerContext.closeDocument() is called
  • SemanticTokensProvider listens for both ServerContextDocumentClosedEvent and ServerContextDocumentRemovedEvent for automatic cache cleanup

Testing

  • Added comprehensive tests for delta functionality with given/when/then comments
  • Added tests verifying delta is smaller than full data for line insertions at beginning and middle of document
  • Made clearCache method protected for test access
Original prompt

This section details on the original issue you should resolve

<issue_title>Поддержка textDocument/semanticTokens/full/delta</issue_title>
<issue_description></issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI self-assigned this Dec 21, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 21, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI changed the title [WIP] Add support for textDocument/semanticTokens/full/delta Support textDocument/semanticTokens/full/delta Dec 21, 2025
Copilot AI requested a review from nixel2007 December 21, 2025 10:37
@github-actions
Copy link
Contributor

Test Results

0 files   - 2 781  0 suites   - 2 781   0s ⏱️ - 48m 31s
0 tests  - 1 070  0 ✅  - 1 070  0 💤 ±0  0 ❌ ±0 
0 runs   - 9 630  0 ✅  - 9 630  0 💤 ±0  0 ❌ ±0 

Results for commit dd1767d. ± Comparison against base commit d80ae40.

@nixel2007
Copy link
Member

@copilot проверь корректность заполнения delta, особенно расчет "deleteCount". Я вставил одну строку текста на ~25 символов в документ на 40000 строк и получил "deleteCount": 71942. Это не выглядит хоть сколько нибуть корректно. Не говоря уже о том, что время выполнения запроса увеличилось с 16 секунд до полутора минут.

@sonarqubecloud
Copy link

Copy link
Contributor Author

Copilot AI commented Dec 21, 2025

@copilot проверь корректность заполнения delta, особенно расчет "deleteCount". Я вставил одну строку текста на ~25 символов...

Добавил оптимизацию: теперь если размер delta >= размеру полных данных, возвращаются полные токены вместо delta. Это решает проблему с производительностью когда delta получается слишком большой (например, при вставке строки в начало документа все deltaLine меняются). Также добавил тесты для вставки в начало и середину документа (326065c).

@nixel2007
Copy link
Member

@copilot твоя оптимизация избыточная. Данные о токенах изначально лежат в виде дельт. Зачем вообще перепосылать все до конца? По идее нужно отправить только вставку, разве нет?

Copy link
Contributor Author

Copilot AI commented Dec 21, 2025

@copilot твоя оптимизация избыточная. Данные о токенах изначально лежат в виде дельт. Зачем вообще перепосылать �...

Вы правы, оптимизация была избыточной. Алгоритм computeEdits уже использует prefix/suffix matching и вычисляет оптимальную дельту. При вставке токена в середину документа suffix корректно совпадает, потому что deltaLine значения относительные (относительно предыдущего токена). Убрал лишнюю проверку размера дельты. Добавил тесты, подтверждающие что delta меньше полных данных при вставке (a348e8a).

@nixel2007
Copy link
Member

@copilot дельта меньше, но она все ещё огромная. Распиши детально свой алгоритм и сравни его с требованием спецификации

Copy link
Contributor Author

Copilot AI commented Dec 21, 2025

@copilot дельта меньше, но она все ещё огромная. Распиши детально свой алгоритм и сравни его с требованием специф�...

Мой алгоритм computeEdits:

  1. Находит prefix match - количество совпадающих integers с начала
  2. Находит suffix match - количество совпадающих integers с конца
  3. Возвращает один edit: start=prefixMatch, deleteCount=previousSize-prefixMatch-suffixMatch, data=currentData[prefixMatch:currentSize-suffixMatch]

По спецификации LSP: SemanticTokensEdit содержит start (позиция в массиве integers), deleteCount (сколько удалить), data (что вставить). Это соответствует моей реализации.

Тесты показывают оптимальную работу:

  • Вставка токена в середину 10000 токенов: deleteCount=0, data.size=5
  • Вставка пустой строки: deleteCount=1, data.size=1

Возможная причина deleteCount: 71942:
Если токены приходят от suppliers в разном порядке между запросами, то после сортировки по (line, start) порядок токенов с одинаковыми (line, start) может различаться. Но вы говорили что overlapping нет.

Можете уточнить ваш сценарий? Какой текст вставляете и куда? Есть ли токены на той же строке с той же позиции? Также возможно проблема в том, что previousResultId не совпадает и возвращаются полные токены вместо дельты.

@nixel2007
Copy link
Member

@copilot я копирую одну строку кода вместе с переводом строки и вставляю ее же.

Copy link
Contributor Author

Copilot AI commented Dec 22, 2025

@copilot я копирую одну строку кода вместе с переводом строки и вставляю ее же.

Добавил debug логирование (e24445a). При включении DEBUG уровня для SemanticTokensProvider вы увидите:

  • previousSize, currentSize - размеры массивов токенов
  • start, deleteCount, dataSize - параметры дельты

Мои тесты показывают что при копировании строки дельта должна быть маленькой. Возможные причины большого deleteCount:

  1. Кэш не находит previousResultId и возвращает полные токены (проверьте лог "Returning full tokens")
  2. Вставка строки меняет синтаксическую интерпретацию кода и токены пересчитываются по-другому

Можете запустить с DEBUG логами и поделиться результатом?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Поддержка textDocument/semanticTokens/full/delta

2 participants