Skip to content

Commit 51e2a58

Browse files
committed
Get things working somewhat. Super hacky and could probably panic
1 parent 9d73672 commit 51e2a58

File tree

9 files changed

+1891
-55
lines changed

9 files changed

+1891
-55
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ opt-level = 0
3030
opt-level = 0
3131

3232
[patch.'crates-io']
33-
lsp-types = { path = "../languageserver-types", features = ["proposed"] }
33+
lsp-types = { git = "https://github.com/kjeremy/languageserver-types", branch="semantic-tokens", features = ["proposed"] }
3434
# rowan = { path = "../rowan" }
3535

3636
[patch.'https://github.com/rust-lang/chalk.git']

crates/ra_ide/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub use crate::{
7575
runnables::{Runnable, RunnableKind, TestId},
7676
source_change::{FileSystemEdit, SourceChange, SourceFileEdit},
7777
ssr::SsrError,
78-
syntax_highlighting::HighlightedRange,
78+
syntax_highlighting::{tags, HighlightedRange},
7979
};
8080

8181
pub use hir::Documentation;

crates/ra_ide/src/syntax_highlighting.rs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,32 @@ use crate::{
1717
};
1818

1919
pub mod tags {
20-
pub(crate) const FIELD: &str = "field";
21-
pub(crate) const FUNCTION: &str = "function";
22-
pub(crate) const MODULE: &str = "module";
23-
pub(crate) const CONSTANT: &str = "constant";
24-
pub(crate) const MACRO: &str = "macro";
25-
26-
pub(crate) const VARIABLE: &str = "variable";
27-
pub(crate) const VARIABLE_MUT: &str = "variable.mut";
28-
29-
pub(crate) const TYPE: &str = "type";
30-
pub(crate) const TYPE_BUILTIN: &str = "type.builtin";
31-
pub(crate) const TYPE_SELF: &str = "type.self";
32-
pub(crate) const TYPE_PARAM: &str = "type.param";
33-
pub(crate) const TYPE_LIFETIME: &str = "type.lifetime";
34-
35-
pub(crate) const LITERAL_BYTE: &str = "literal.byte";
36-
pub(crate) const LITERAL_NUMERIC: &str = "literal.numeric";
37-
pub(crate) const LITERAL_CHAR: &str = "literal.char";
38-
39-
pub(crate) const LITERAL_COMMENT: &str = "comment";
40-
pub(crate) const LITERAL_STRING: &str = "string";
41-
pub(crate) const LITERAL_ATTRIBUTE: &str = "attribute";
42-
43-
pub(crate) const KEYWORD: &str = "keyword";
44-
pub(crate) const KEYWORD_UNSAFE: &str = "keyword.unsafe";
45-
pub(crate) const KEYWORD_CONTROL: &str = "keyword.control";
20+
pub const FIELD: &str = "field";
21+
pub const FUNCTION: &str = "function";
22+
pub const MODULE: &str = "module";
23+
pub const CONSTANT: &str = "constant";
24+
pub const MACRO: &str = "macro";
25+
26+
pub const VARIABLE: &str = "variable";
27+
pub const VARIABLE_MUT: &str = "variable.mut";
28+
29+
pub const TYPE: &str = "type";
30+
pub const TYPE_BUILTIN: &str = "type.builtin";
31+
pub const TYPE_SELF: &str = "type.self";
32+
pub const TYPE_PARAM: &str = "type.param";
33+
pub const TYPE_LIFETIME: &str = "type.lifetime";
34+
35+
pub const LITERAL_BYTE: &str = "literal.byte";
36+
pub const LITERAL_NUMERIC: &str = "literal.numeric";
37+
pub const LITERAL_CHAR: &str = "literal.char";
38+
39+
pub const LITERAL_COMMENT: &str = "comment";
40+
pub const LITERAL_STRING: &str = "string";
41+
pub const LITERAL_ATTRIBUTE: &str = "attribute";
42+
43+
pub const KEYWORD: &str = "keyword";
44+
pub const KEYWORD_UNSAFE: &str = "keyword.unsafe";
45+
pub const KEYWORD_CONTROL: &str = "keyword.control";
4646
}
4747

4848
#[derive(Debug)]

crates/rust-analyzer/src/conv.rs

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
use lsp_types::{
55
self, CreateFile, DiagnosticSeverity, DocumentChangeOperation, DocumentChanges, Documentation,
66
Location, LocationLink, MarkupContent, MarkupKind, Position, Range, RenameFile, ResourceOp,
7-
SymbolKind, TextDocumentEdit, TextDocumentIdentifier, TextDocumentItem,
8-
TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkspaceEdit,
7+
SemanticTokenModifier, SemanticTokenType, SemanticTokensLegend, SymbolKind, TextDocumentEdit,
8+
TextDocumentIdentifier, TextDocumentItem, TextDocumentPositionParams, Url,
9+
VersionedTextDocumentIdentifier, WorkspaceEdit,
910
};
1011
use ra_ide::{
11-
translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition,
12+
tags, translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition,
1213
FileRange, FileSystemEdit, Fold, FoldKind, InsertTextFormat, LineCol, LineIndex,
1314
NavigationTarget, RangeInfo, ReferenceAccess, Severity, SourceChange, SourceFileEdit,
1415
};
@@ -302,6 +303,104 @@ impl ConvWith<&FoldConvCtx<'_>> for Fold {
302303
}
303304
}
304305

306+
impl ConvWith<&WorldSnapshot> for &'static str {
307+
type Output = (SemanticTokenType, Vec<SemanticTokenModifier>);
308+
309+
fn conv_with(self, _world: &WorldSnapshot) -> (SemanticTokenType, Vec<SemanticTokenModifier>) {
310+
match self {
311+
tags::FIELD => (SemanticTokenType::MEMBER, vec![]),
312+
tags::FUNCTION => (SemanticTokenType::FUNCTION, vec![]),
313+
tags::MODULE => (SemanticTokenType::NAMESPACE, vec![]),
314+
tags::CONSTANT => (
315+
SemanticTokenType::VARIABLE,
316+
vec![SemanticTokenModifier::STATIC, SemanticTokenModifier::READONLY],
317+
),
318+
tags::MACRO => (SemanticTokenType::MACRO, vec![]),
319+
320+
tags::VARIABLE => (SemanticTokenType::VARIABLE, vec![SemanticTokenModifier::READONLY]),
321+
tags::VARIABLE_MUT => (SemanticTokenType::VARIABLE, vec![]),
322+
323+
tags::TYPE => (SemanticTokenType::TYPE, vec![]),
324+
tags::TYPE_BUILTIN => (SemanticTokenType::TYPE, vec![]),
325+
tags::TYPE_SELF => (SemanticTokenType::TYPE, vec![SemanticTokenModifier::REFERENCE]),
326+
tags::TYPE_PARAM => (SemanticTokenType::TYPE_PARAMETER, vec![]),
327+
tags::TYPE_LIFETIME => {
328+
(SemanticTokenType::LABEL, vec![SemanticTokenModifier::REFERENCE])
329+
}
330+
331+
tags::LITERAL_BYTE => (SemanticTokenType::NUMBER, vec![]),
332+
tags::LITERAL_NUMERIC => (SemanticTokenType::NUMBER, vec![]),
333+
tags::LITERAL_CHAR => (SemanticTokenType::NUMBER, vec![]),
334+
335+
tags::LITERAL_COMMENT => {
336+
(SemanticTokenType::COMMENT, vec![SemanticTokenModifier::DOCUMENTATION])
337+
}
338+
tags::LITERAL_STRING => (SemanticTokenType::STRING, vec![]),
339+
tags::LITERAL_ATTRIBUTE => (SemanticTokenType::KEYWORD, vec![]),
340+
341+
tags::KEYWORD => (SemanticTokenType::KEYWORD, vec![]),
342+
tags::KEYWORD_UNSAFE => (SemanticTokenType::KEYWORD, vec![]),
343+
tags::KEYWORD_CONTROL => (SemanticTokenType::KEYWORD, vec![]),
344+
_ => panic!("Unknown"),
345+
}
346+
}
347+
}
348+
349+
impl ConvWith<&WorldSnapshot> for (SemanticTokenType, Vec<SemanticTokenModifier>) {
350+
type Output = (u32, u32);
351+
352+
fn conv_with(self, _world: &WorldSnapshot) -> (u32, u32) {
353+
// Should we be matching against a token legend held in world or maybe this should just be a const somewhere?
354+
// This is just a HACK and copy of what we return in server caps.
355+
let legend = SemanticTokensLegend {
356+
token_types: vec![
357+
SemanticTokenType::COMMENT,
358+
SemanticTokenType::KEYWORD,
359+
SemanticTokenType::STRING,
360+
SemanticTokenType::NUMBER,
361+
SemanticTokenType::REGEXP,
362+
SemanticTokenType::OPERATOR,
363+
SemanticTokenType::NAMESPACE,
364+
SemanticTokenType::TYPE,
365+
SemanticTokenType::STRUCT,
366+
SemanticTokenType::CLASS,
367+
SemanticTokenType::INTERFACE,
368+
SemanticTokenType::ENUM,
369+
SemanticTokenType::TYPE_PARAMETER,
370+
SemanticTokenType::FUNCTION,
371+
SemanticTokenType::MEMBER,
372+
SemanticTokenType::PROPERTY,
373+
SemanticTokenType::MACRO,
374+
SemanticTokenType::VARIABLE,
375+
SemanticTokenType::PARAMETER,
376+
SemanticTokenType::LABEL,
377+
],
378+
token_modifiers: vec![
379+
SemanticTokenModifier::DOCUMENTATION,
380+
SemanticTokenModifier::DECLARATION,
381+
SemanticTokenModifier::DEFINITION,
382+
SemanticTokenModifier::REFERENCE,
383+
SemanticTokenModifier::STATIC,
384+
SemanticTokenModifier::ABSTRACT,
385+
SemanticTokenModifier::DEPRECATED,
386+
SemanticTokenModifier::ASYNC,
387+
SemanticTokenModifier::VOLATILE,
388+
SemanticTokenModifier::READONLY,
389+
],
390+
};
391+
392+
// IndexMap for tokens and modifiers?
393+
let token_index = legend.token_types.iter().position(|it| *it == self.0).unwrap();
394+
let mut token_modifier_bitset = 0;
395+
for modifier in self.1.iter() {
396+
token_modifier_bitset |=
397+
legend.token_modifiers.iter().position(|it| it == modifier).unwrap();
398+
}
399+
400+
(token_index as u32, token_modifier_bitset as u32)
401+
}
402+
}
403+
305404
impl<T: ConvWith<CTX>, CTX> ConvWith<CTX> for Option<T> {
306405
type Output = Option<T::Output>;
307406

crates/rust-analyzer/src/main_loop/handlers.rs

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use lsp_types::{
1717
Diagnostic, DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange,
1818
FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, MarkupKind, Position,
1919
PrepareRenameResponse, Range, RenameParams, SemanticToken, SemanticTokenModifier,
20-
SemanticTokenType, SemanticTokensParams, SemanticTokensResult, SymbolInformation,
21-
TextDocumentIdentifier, TextEdit, WorkspaceEdit,
20+
SemanticTokenType, SemanticTokens, SemanticTokensParams, SemanticTokensResult,
21+
SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit,
2222
};
2323
use ra_ide::{
2424
AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind,
@@ -1078,23 +1078,19 @@ pub fn handle_semantic_tokens(
10781078

10791079
let file_id = params.text_document.try_conv_with(&world)?;
10801080
let line_index = world.analysis().file_line_index(file_id)?;
1081-
/*
1082-
let res = world
1083-
.analysis()
1084-
.highlight(file_id)?
1085-
.into_iter().map(|h| Decoration {
1086-
range: h.range.conv_with(&line_index),
1087-
tag: h.tag,
1088-
binding_hash: h.binding_hash.map(|x| x.to_string()),
1089-
})
1090-
.collect();
10911081

1092-
let tokens = SemanticTokens {
1093-
data: data,
1094-
.. SemanticTokens::default()
1095-
};
1096-
*/
1097-
Ok(None)
1082+
let mut builder = SemanticTokensBuilder::default();
1083+
1084+
for h in world.analysis().highlight(file_id)?.into_iter() {
1085+
let type_and_modifiers: (SemanticTokenType, Vec<SemanticTokenModifier>) =
1086+
h.tag.conv_with(&world);
1087+
let (token_type, token_modifiers) = type_and_modifiers.conv_with(&world);
1088+
builder.push(h.range.conv_with(&line_index), token_type, token_modifiers);
1089+
}
1090+
1091+
let tokens = SemanticTokens { data: builder.build(), ..Default::default() };
1092+
1093+
Ok(Some(tokens.into()))
10981094
}
10991095

11001096
#[derive(Default)]
@@ -1108,8 +1104,8 @@ impl SemanticTokensBuilder {
11081104
pub fn push(
11091105
&mut self,
11101106
range: Range,
1111-
token_type: SemanticTokenType,
1112-
modifiers: &[SemanticTokenModifier],
1107+
token_index: u32, //SemanticTokenType,
1108+
modifier_bitset: u32, //&[SemanticTokenModifier],
11131109
) {
11141110
let mut push_line = range.start.line as u32;
11151111
let mut push_char = range.start.character as u32;
@@ -1128,8 +1124,8 @@ impl SemanticTokensBuilder {
11281124
delta_line: push_line,
11291125
delta_start: push_char,
11301126
length: token_len as u32,
1131-
token_type: 0, // TODO
1132-
token_modifiers_bitset: 0, // TODO
1127+
token_type: token_index,
1128+
token_modifiers_bitset: modifier_bitset,
11331129
};
11341130

11351131
self.data.push(token);

editors/code/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"engines": {
1919
"vscode": "^1.42.0"
2020
},
21+
"enableProposedApi": true,
2122
"scripts": {
2223
"vscode:prepublish": "tsc && rollup -c",
2324
"package": "vsce package -o rust-analyzer.vsix",

editors/code/src/client.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import * as lc from 'vscode-languageclient';
22
import * as vscode from 'vscode';
33

44
import { Config } from './config';
5-
import { CallHierarchyFeature } from 'vscode-languageclient/lib/callHierarchy.proposed';
5+
import { ensureServerBinary } from './installation/server';
6+
//import { CallHierarchyFeature } from 'vscode-languageclient/lib/callHierarchy.proposed';
67

78
export async function createClient(config: Config, serverPath: string): Promise<lc.LanguageClient> {
89
// '.' Is the fallback if no folder is open
@@ -82,6 +83,7 @@ export async function createClient(config: Config, serverPath: string): Promise<
8283
// To turn on all proposed features use: res.registerProposedFeatures();
8384
// Here we want to just enable CallHierarchyFeature since it is available on stable.
8485
// Note that while the CallHierarchyFeature is stable the LSP protocol is not.
85-
res.registerFeature(new CallHierarchyFeature(res));
86+
//res.registerFeature(new CallHierarchyFeature(res));
87+
res.registerProposedFeatures();
8688
return res;
8789
}

0 commit comments

Comments
 (0)