Skip to content

feat(CompletionProvider): ранжирование кандидатов автодополнения через sortText#4070

Merged
nixel2007 merged 2 commits into
developfrom
claude/completion-sorttext
Jun 12, 2026
Merged

feat(CompletionProvider): ранжирование кандидатов автодополнения через sortText#4070
nixel2007 merged 2 commits into
developfrom
claude/completion-sorttext

Conversation

@nixel2007

@nixel2007 nixel2007 commented Jun 12, 2026

Copy link
Copy Markdown
Member

Проблема

Ни один completion item не получал sortText, поэтому клиент сортировал выдачу по алфавиту (по label). В no-dot completion локальные методы и переменные документа тонули среди сотен глобальных функций, MD-имён и ключевых слов — всё складывалось в один плоский список (CompletionProvider.noDotCompletion).

Решение

Введены префиксные «корзины» sortText по схеме корзина + флаг устаревания + "_" + label (стандартная практика TS LS / rust-analyzer; формат — простые цифровые префиксы):

no-dot completion (меньший префикс — выше в списке):

  • 1_ — локальные переменные и методы документа;
  • 2_ — глобальные функции и контексты (property/enum/library-module);
  • 3_ — классы (в т.ч. после Новый) и квалифицированные MD-имена;
  • 4_ — ключевые слова.

Понижение устаревших: внутри корзины устаревший член получает флаг 1 против 0 у неустаревшего, поэтому уходит вниз даже если его имя лексикографически меньше соседа. Применено к локальным методам и глобальным функциям.

dot-completion: члены типа тоже получают sortText — декларированные/пользовательские поля (1_) ранжируются выше дефолтных членов того же типа (2_), а устаревшие члены опускаются вниз своей корзины. Это сохраняет уже существующий приоритет полей (через putIfAbsent) теперь и в порядке клиента, и единообразно демотирует устаревшие члены.

Правки локальны для мест выдачи item-ов; вспомогательный метод applySortText ставит sortText по корзине и флагу устаревания. Внутри корзины при равном статусе порядок стабилен по label.

Тесты

CompletionProviderTest, попарные сравнения sortText (без завязки на полный порядок):

  • noDotCompletionRanksLocalMethodAboveGlobalFunctionAndKeywordsortText локального метода < глобальной функции;
  • noDotCompletionRanksLocalVariableAboveKeyword — локальная переменная < ключевого слова;
  • noDotCompletionDemotesDeprecatedLocalMethodBelowNonDeprecatedNeighbor — устаревший МетодА > неустаревшего МетодБ, несмотря на меньшее имя.

Тесты сначала падали с NPE на null sortText (фича отсутствует), затем зелёные. Полный класс CompletionProviderTest проходит без регрессий.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Code completion items are now sorted more intelligently to prioritize user-defined fields and local methods ahead of type members, with improved handling of deprecated items.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

CompletionProvider now assigns explicit sortText values to rank completion items by category (type, global, local, keyword) and deprecated status. Dot-completion tracks declared fields for higher priority, and no-dot completion applies bucketed sorting across all item categories.

Changes

Completion Item Sorting by Category and Deprecation

Layer / File(s) Summary
Sorting foundation: bucket constants and helper
src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CompletionProvider.java
Import HashSet, define BUCKET_* constants for categorized completion ranking, and introduce applySortText helper to set sortText with bucket prefix, deprecated flag, and label.
Dot-completion member sorting
src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CompletionProvider.java
Track declared object fields in localFieldNames and apply sortText to dot-completion members, ranking user-defined fields ahead of default type members.
No-dot completion type sorting (afterNew)
src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CompletionProvider.java
Apply bucketed sortText to platform classes, library classes, and configuration module completions in afterNew context.
No-dot completion global and local item sorting
src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CompletionProvider.java
Apply bucketed sortText to global contexts and functions (with deprecated-aware flag), local document methods, local variables, and keywords in no-dot completion.
Test coverage for no-dot completion ranking
src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/CompletionProviderTest.java
Add three ranking validation tests: local method above global function/keyword, local variable above keyword, and deprecated method below non-deprecated neighbor; include sortTextOf helper for assertions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A rabbit hops through completion's dance,
With buckets sorted in perfect stance,
Deprecated flags in twos and zeros bright,
Local fields leap before the type-light,
Now every item knows its rightful place!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introducing sortText-based ranking for autocomplete candidates in CompletionProvider, which directly matches the core functionality across both modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/completion-sorttext

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

Copy link
Copy Markdown
Contributor

Test Results

 3 264 files  ± 0   3 264 suites  ±0   1h 27m 36s ⏱️ - 8m 45s
 3 140 tests + 3   3 125 ✅ + 3  15 💤 ±0  0 ❌ ±0 
18 840 runs  +18  18 750 ✅ +18  90 💤 ±0  0 ❌ ±0 

Results for commit d1b7fb3. ± Comparison against base commit 40faee7.

var members = new LinkedHashMap<String, MemberDescriptor>();
// Имена декларированных полей — для приоритетной корзины sortText: пользовательские
// ключи должны ранжироваться выше дефолтных членов того же типа.
var localFieldNames = new java.util.HashSet<String>();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Импорты

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Исправлено: добавил import java.util.HashSet;, заменил FQN new java.util.HashSet<>() на new HashSet<>() (заодно и в соседней строке с seenFn). Коммит 691ab2c.

@nixel2007
nixel2007 force-pushed the claude/completion-sorttext branch from d1b7fb3 to 691ab2c Compare June 12, 2026 21:36

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/CompletionProviderTest.java (1)

1658-1687: 📐 Maintainability & Code Quality | 💤 Low value

Consider aligning test scope with its name.

The test name mentions AndKeyword, and the comment states the local method should rank above both global function and keyword. However, the test only verifies localMethod < globalFunction without asserting against a keyword. While the ranking is mathematically proven by bucket values (BUCKET_LOCAL=1 < BUCKET_GLOBAL=2 < BUCKET_KEYWORD=4), explicitly testing the keyword case would improve coverage and align the test with its name.

📝 Suggested enhancement

Add an assertion for keyword ranking:

     var items = completionProvider.getCompletion(documentContext, params).getItems();
     var localMethod = sortTextOf(items, "Сообщение");
     var globalFunction = sortTextOf(items, "Сообщить");
+    var keyword = sortTextOf(items, "Сообщение"); // or another keyword with prefix "Сооб" if available

     // then
     assertThat(localMethod)
       .as("sortText локального метода и глобальной функции должны быть проставлены")
       .isNotNull();
     assertThat(globalFunction).isNotNull();
+    assertThat(keyword).isNotNull();
     assertThat(localMethod)
       .as("локальный метод документа ранжируется выше глобальной функции")
       .isLessThan(globalFunction);
+    assertThat(localMethod)
+      .as("локальный метод документа ранжируется выше ключевого слова")
+      .isLessThan(keyword);

Alternatively, rename the test to noDotCompletionRanksLocalMethodAboveGlobalFunction to match the current scope.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/CompletionProviderTest.java`
around lines 1658 - 1687, The test name and comment claim the local method
should rank above both a global function and a keyword, but the test only
asserts localMethod < globalFunction; update the test
noDotCompletionRanksLocalMethodAboveGlobalFunctionAndKeyword to also fetch the
keyword sortText with sortTextOf(items, "<keyword>") (choose a language keyword
that appears in the completion set at the test position) and add assertions that
the keyword sortText is not null and that localMethod isLessThan(keyword) to
align coverage with the test name.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/CompletionProviderTest.java`:
- Around line 1658-1687: The test name and comment claim the local method should
rank above both a global function and a keyword, but the test only asserts
localMethod < globalFunction; update the test
noDotCompletionRanksLocalMethodAboveGlobalFunctionAndKeyword to also fetch the
keyword sortText with sortTextOf(items, "<keyword>") (choose a language keyword
that appears in the completion set at the test position) and add assertions that
the keyword sortText is not null and that localMethod isLessThan(keyword) to
align coverage with the test name.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2dc1e484-a3cb-4727-9eda-4d35624b5587

📥 Commits

Reviewing files that changed from the base of the PR and between e9890a2 and 691ab2c.

📒 Files selected for processing (2)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CompletionProvider.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/CompletionProviderTest.java

@nixel2007
nixel2007 enabled auto-merge June 12, 2026 21:44
@nixel2007
nixel2007 merged commit b91532a into develop Jun 12, 2026
41 checks passed
@nixel2007
nixel2007 deleted the claude/completion-sorttext branch June 12, 2026 22:43
@sonarqubecloud

Copy link
Copy Markdown

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.

1 participant