| 487 | } |
| 488 | |
| 489 | void MessageHandler::textDocument_semanticTokensRange(SemanticTokensRangeParams ¶m, ReplyOnce &reply) { |
| 490 | int file_id; |
| 491 | auto [file, wf] = findOrFail(param.textDocument.uri.getPath(), reply, &file_id); |
| 492 | if (!wf) |
| 493 | return; |
| 494 | |
| 495 | auto grouped_symbols = computeSemanticTokens(db, wf, *file); |
| 496 | std::vector<std::pair<Occur, CclsSemanticHighlightSymbol *>> scratch; |
| 497 | for (auto &entry : grouped_symbols) { |
| 498 | for (auto &occur : entry.second.lsOccurs) |
| 499 | scratch.emplace_back(occur, &entry.second); |
| 500 | entry.second.lsOccurs.clear(); |
| 501 | } |
| 502 | std::sort(scratch.begin(), scratch.end(), [](auto &l, auto &r) { return l.first.range < r.first.range; }); |
| 503 | |
| 504 | SemanticTokensPartialResult result; |
| 505 | int line = 0, column = 0; |
| 506 | for (auto &entry : scratch) { |
| 507 | lsRange &r = entry.first.range; |
| 508 | CclsSemanticHighlightSymbol &symbol = *entry.second; |
| 509 | if (r.start.line != line) |
| 510 | column = 0; |
| 511 | result.data.push_back(r.start.line - line); |
| 512 | line = r.start.line; |
| 513 | result.data.push_back(r.start.character - column); |
| 514 | column = r.start.character; |
| 515 | result.data.push_back(r.end.character - r.start.character); |
| 516 | |
| 517 | int tokenType = (int)symbol.kind, modifier = 0; |
| 518 | if (tokenType == (int)SymbolKind::StaticMethod) { |
| 519 | tokenType = (int)SymbolKind::Method; |
| 520 | modifier |= 1 << (int)TokenModifier::Static; |
| 521 | } else if (tokenType >= (int)SymbolKind::FirstExtension) { |
| 522 | tokenType += (int)SymbolKind::FirstNonStandard - (int)SymbolKind::FirstExtension; |
| 523 | } |
| 524 | |
| 525 | // Set modifiers. |
| 526 | if (entry.first.role & Role::Declaration) |
| 527 | modifier |= 1 << (int)TokenModifier::Declaration; |
| 528 | if (entry.first.role & Role::Definition) |
| 529 | modifier |= 1 << (int)TokenModifier::Definition; |
| 530 | if (entry.first.role & Role::Read) |
| 531 | modifier |= 1 << (int)TokenModifier::Read; |
| 532 | if (entry.first.role & Role::Write) |
| 533 | modifier |= 1 << (int)TokenModifier::Write; |
| 534 | if (symbol.storage == SC_Static) |
| 535 | modifier |= 1 << (int)TokenModifier::Static; |
| 536 | |
| 537 | if (llvm::is_contained({SymbolKind::Constructor, SymbolKind::Field, SymbolKind::Method, SymbolKind::StaticMethod}, |
| 538 | symbol.kind)) |
| 539 | modifier |= 1 << (int)TokenModifier::ClassScope; |
| 540 | else if (llvm::is_contained({SymbolKind::File, SymbolKind::Namespace}, symbol.parentKind)) |
| 541 | modifier |= 1 << (int)TokenModifier::NamespaceScope; |
| 542 | else if (llvm::is_contained( |
| 543 | {SymbolKind::Constructor, SymbolKind::Function, SymbolKind::Method, SymbolKind::StaticMethod}, |
| 544 | symbol.parentKind)) |
| 545 | modifier |= 1 << (int)TokenModifier::FunctionScope; |
| 546 |
nothing calls this directly
no test coverage detected