Repository navigation
feat(semantic tokens): highlight module names in declarations and imports - #417
Conversation
…orts Add highlight_modules() to SemanticTokensCollector that: - Highlights module name identifiers (SymbolKind::Module) in import statements using directives.imports name_locations - Highlights module name identifiers in module declarations (export module foo.bar;) by scanning from Module::DefinitionLoc Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…orts Add highlight_modules() to SemanticTokensCollector that: - Highlights module name identifiers in import statements using directives.imports name_locations - Highlights module name identifiers in module declarations (export module foo.bar;) by scanning from DefinitionLoc Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds a new module-highlighting pass into the semantic token collection pipeline that emits module/import tokens and changes directive-vs-other-kind merge rules; removes commented module-parsing in the visitor; and extends unit tests to validate C++20 module tokenization. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Collector as SemanticTokensCollector
participant Visitor as SemanticVisitor
participant DirStore as DirectiveStore (module imports)
participant Lexer as Lexer (from DefinitionLoc)
participant Merger as TokenMerger
Collector->>Visitor: run() (gathers tokens & directives)
Visitor-->>Collector: tokens + directive records
Collector->>DirStore: query import directives & locations
DirStore-->>Collector: import name locations
Collector->>Lexer: lex from module DefinitionLoc (skip 'module')
Lexer-->>Collector: identifiers and separators
Collector->>Collector: emit Keyword/Module tokens for imports & declaration
Collector->>Merger: merge_tokens(incoming tokens, existing)
Merger-->>Collector: merged token set (directives no longer always win)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/feature/semantic_tokens.cpp`:
- Around line 333-341: The loop in semantic_tokens.cpp currently tags every
identifier before the semicolon as SymbolKind::Module; change it to only mark
the first identifier (the actual module name) encountered after entering the
loop. Before the while(true) loop introduce a bool like seenModuleName = false,
and inside the loop replace the unconditional token.is_identifier() branch with
a check if(token.is_identifier() && !seenModuleName) then create the
LocalSourceRange and push the Module token and set seenModuleName = true; leave
other tokens unmarked so trailing attributes/identifiers are not highlighted.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 99cdf916-d2c2-4188-ba62-5ee210c58747
📒 Files selected for processing (3)
src/feature/semantic_tokens.cppsrc/semantic/semantic_visitor.htests/unit/feature/semantic_tokens_tests.cpp
…mantic-tokens-module
…onflict resolution Highlight `import` and `module` as Keyword tokens in semantic tokens output. The lexer treats these context-sensitive keywords as Directive, so resolve_conflict now lets semantic tokens override Directive tokens. Also adds tests for partitions, re-exports, global/private module fragments, and module/import used as identifiers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/unit/feature/semantic_tokens_tests.cpp (1)
451-488: Extract the temporary PCM setup into a helper/guard.These two tests duplicate the same module build plumbing and manual
fs::remove()cleanup. That makes the cases harder to maintain, and anyASSERT_*before the finalremove()leaks the temp file.Refactor sketch
+struct TempPcm { + std::string path; + ~TempPcm() { fs::remove(path); } +}; + +auto build_test_pcm(llvm::StringRef module_name, llvm::StringRef source) -> TempPcm { + auto pcm_path = fs::createTemporaryFile("test-mod", "pcm"); + ASSERT_TRUE(pcm_path.has_value()); + + Tester mod; + mod.add_main((std::string(module_name) + ".cppm").c_str(), std::string(source)); + mod.prepare("-std=c++20"); + mod.params.kind = CompilationKind::ModuleInterface; + mod.params.output_file = *pcm_path; + + auto built = clice::compile(mod.params); + ASSERT_TRUE(built.completed()); + return TempPcm{*pcm_path}; +}Also applies to: 502-540
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/unit/feature/semantic_tokens_tests.cpp` around lines 451 - 488, Extract the temporary PCM creation, building and cleanup into a reusable helper/RAII guard so tests no longer duplicate plumbing and can't leak files on early ASSERT failures: move the logic that calls fs::createTemporaryFile("test-mod", "pcm"), constructs the Tester mod, sets mod.params.kind/ output_file, calls clice::compile(mod.params) and asserts completion into a helper like MakeBuiltPCM or PCMGuard that returns the pcm path and removes the file in its destructor; update TEST_CASE(ModuleImport) to call that helper to obtain the pcm path, use it for -fmodule-file, and remove the explicit fs::remove(*pcm_path) so cleanup is automatic and safe on failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@tests/unit/feature/semantic_tokens_tests.cpp`:
- Around line 451-488: Extract the temporary PCM creation, building and cleanup
into a reusable helper/RAII guard so tests no longer duplicate plumbing and
can't leak files on early ASSERT failures: move the logic that calls
fs::createTemporaryFile("test-mod", "pcm"), constructs the Tester mod, sets
mod.params.kind/ output_file, calls clice::compile(mod.params) and asserts
completion into a helper like MakeBuiltPCM or PCMGuard that returns the pcm path
and removes the file in its destructor; update TEST_CASE(ModuleImport) to call
that helper to obtain the pcm path, use it for -fmodule-file, and remove the
explicit fs::remove(*pcm_path) so cleanup is automatic and safe on failures.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 301ea7e9-98d3-4cbe-a67e-242f42868453
📒 Files selected for processing (3)
src/feature/semantic_tokens.cppsrc/semantic/semantic_visitor.htests/unit/feature/semantic_tokens_tests.cpp
💤 Files with no reviewable changes (1)
- src/semantic/semantic_visitor.h
🚧 Files skipped from review as they are similar to previous changes (1)
- src/feature/semantic_tokens.cpp
Summary
foo,barinexport module foo.bar;) asSymbolKind::Modulein semantic tokensfooinimport foo;) usingdirectives.importsname locationsgetCurrentNamedModule()->DefinitionLoc+ lexer scan to find name tokensTest plan
SemanticTokens.ModuleDeclaration—export module foo;SemanticTokens.ModuleDeclarationDotted—export module foo.bar;SemanticTokens.ModuleImport— PCM build +import foo;🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
module/importused as identifiers are tokenized correctly.Tests