@@ -10,7 +10,7 @@ const analysis = @import("../analysis.zig");
1010const tracy = @import ("tracy" );
1111
1212const Symbol = struct {
13- name : [] const u8 ,
13+ name_token : Ast.TokenIndex ,
1414 detail : ? []const u8 = null ,
1515 kind : types.SymbolKind ,
1616 loc : offsets.Loc ,
@@ -27,6 +27,26 @@ const Context = struct {
2727 total_symbol_count : * usize ,
2828};
2929
30+ fn tokenNameMaybeQuotes (tree : * const Ast , token : Ast.TokenIndex ) []const u8 {
31+ const token_slice = tree .tokenSlice (token );
32+ switch (tree .tokenTag (token )) {
33+ .identifier = > return token_slice ,
34+ .string_literal = > {
35+ const name = token_slice [1 .. token_slice .len - 1 ];
36+ const trimmed = std .mem .trim (u8 , name , & std .ascii .whitespace );
37+ // LSP spec requires that a symbol name not be empty or consisting only of whitespace,
38+ // don't trim the quotes in that case so there's something to present.
39+ // Leading and trailing whitespace might cause ambiguity depending on how the client shows symbols
40+ // so compensate for that as well
41+ if (name .len == 0 or name .len != trimmed .len )
42+ return token_slice ;
43+
44+ return name ;
45+ },
46+ else = > unreachable ,
47+ }
48+ }
49+
3050fn callback (ctx : * Context , tree : * const Ast , node : Ast.Node.Index ) error {OutOfMemory }! void {
3151 std .debug .assert (node != .root );
3252
@@ -52,7 +72,7 @@ fn callback(ctx: *Context, tree: *const Ast, node: Ast.Node.Index) error{OutOfMe
5272 };
5373
5474 break :blk .{
55- .name = var_decl_name ,
75+ .name_token = var_decl_name_token ,
5676 .detail = null ,
5777 .kind = kind ,
5878 .loc = offsets .nodeToLoc (tree , node ),
@@ -62,10 +82,10 @@ fn callback(ctx: *Context, tree: *const Ast, node: Ast.Node.Index) error{OutOfMe
6282 },
6383
6484 .test_decl = > blk : {
65- const test_name_token , const test_name = ast . testDeclNameAndToken ( tree , node ) orelse break :blk null ;
85+ const test_name_token = tree . nodeData ( node ). opt_token_and_node [ 0 ]. unwrap ( ) orelse break :blk null ;
6686
6787 break :blk .{
68- .name = test_name ,
88+ .name_token = test_name_token ,
6989 .kind = .Method , // there is no SymbolKind that represents a tests
7090 .loc = offsets .nodeToLoc (tree , node ),
7191 .selection_loc = offsets .tokenToLoc (tree , test_name_token ),
@@ -79,7 +99,7 @@ fn callback(ctx: *Context, tree: *const Ast, node: Ast.Node.Index) error{OutOfMe
7999 const name_token = fn_info .name_token orelse break :blk null ;
80100
81101 break :blk .{
82- .name = offsets . identifierTokenToNameSlice ( tree , name_token ) ,
102+ .name_token = name_token ,
83103 .detail = analysis .getFunctionSignature (tree , fn_info ),
84104 .kind = .Function ,
85105 .loc = offsets .nodeToLoc (tree , node ),
@@ -124,10 +144,9 @@ fn callback(ctx: *Context, tree: *const Ast, node: Ast.Node.Index) error{OutOfMe
124144 if (is_struct and container_field .ast .tuple_like ) break :blk null ;
125145
126146 const decl_name_token = container_field .ast .main_token ;
127- const decl_name = offsets .tokenToSlice (tree , decl_name_token );
128147
129148 break :blk .{
130- .name = decl_name ,
149+ .name_token = decl_name_token ,
131150 .detail = ctx .last_var_decl_name ,
132151 .kind = kind ,
133152 .loc = offsets .nodeToLoc (tree , node ),
@@ -185,14 +204,15 @@ fn convertSymbols(
185204 var mappings : std .ArrayList (offsets .multiple .IndexToPositionMapping ) = .empty ;
186205 try mappings .ensureTotalCapacityPrecise (arena , total_symbol_count * 4 );
187206
188- const result = convertSymbolsInternal (from , & symbol_buffer , & mappings );
207+ const result = convertSymbolsInternal (tree , from , & symbol_buffer , & mappings );
189208
190209 offsets .multiple .indexToPositionWithMappings (tree .source , mappings .items , encoding );
191210
192211 return result ;
193212}
194213
195214fn convertSymbolsInternal (
215+ tree : * const Ast ,
196216 from : []const Symbol ,
197217 symbol_buffer : * std .ArrayList (types.DocumentSymbol ),
198218 mappings : * std .ArrayList (offsets .multiple .IndexToPositionMapping ),
@@ -204,13 +224,13 @@ fn convertSymbolsInternal(
204224
205225 for (from , to ) | symbol , * out | {
206226 out .* = .{
207- .name = symbol .name ,
227+ .name = tokenNameMaybeQuotes ( tree , symbol .name_token ) ,
208228 .detail = symbol .detail ,
209229 .kind = symbol .kind ,
210230 // will be set later through the mapping below
211231 .range = undefined ,
212232 .selectionRange = undefined ,
213- .children = convertSymbolsInternal (symbol .children .items , symbol_buffer , mappings ),
233+ .children = convertSymbolsInternal (tree , symbol .children .items , symbol_buffer , mappings ),
214234 };
215235 mappings .appendSliceAssumeCapacity (&.{
216236 .{ .output = & out .range .start , .source_index = symbol .loc .start },
0 commit comments