Skip to content

Commit cc4a0d3

Browse files
committed
Emit record labels as "property".
1 parent 6645df7 commit cc4a0d3

File tree

3 files changed

+59
-8
lines changed

3 files changed

+59
-8
lines changed

analysis/src/SemanticTokens.ml

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@ module Token = struct
33

44
(* This needs to stay synced with the same legend in `server.ts` *)
55
(* See https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens *)
6-
type tokenType = Keyword | Variable | Type | JsxTag | Namespace
6+
type tokenType =
7+
| Keyword
8+
| Variable
9+
| Type
10+
| JsxTag
11+
| Namespace
12+
| EnumMember
13+
| Property
14+
715
type tokenModifiers = NoModifier
816

917
let tokenTypeToString = function
@@ -12,13 +20,17 @@ module Token = struct
1220
| Type -> "2"
1321
| JsxTag -> "3"
1422
| Namespace -> "4"
23+
| EnumMember -> "5"
24+
| Property -> "6"
1525

1626
let tokenTypeDebug = function
1727
| Keyword -> "Keyword"
1828
| Variable -> "Variable"
1929
| Type -> "Type"
2030
| JsxTag -> "JsxTag"
2131
| Namespace -> "Namespace"
32+
| EnumMember -> "EnumMember"
33+
| Property -> "Property"
2234

2335
let tokenModifiersToString = function NoModifier -> "0"
2436

@@ -87,8 +99,8 @@ let emitFromLoc ~loc ~type_ emitter =
8799
emitter |> emitFromPos posStart posEnd ~type_
88100

89101
let emitLongident ?(backwards = false) ?(jsx = false)
90-
?(moduleToken = Token.Namespace) ~pos ~lid ~debug emitter =
91-
let variableToken = if jsx then Token.JsxTag else Variable in
102+
?(lowerCaseToken = if jsx then Token.JsxTag else Variable)
103+
?(upperCaseToken = Token.Namespace) ~pos ~lid ~debug emitter =
92104
let rec flatten acc lid =
93105
match lid with
94106
| Longident.Lident txt -> txt :: acc
@@ -100,13 +112,13 @@ let emitLongident ?(backwards = false) ?(jsx = false)
100112
let rec loop pos segments =
101113
match segments with
102114
| [id] when isUppercaseId id || isLowercaseId id ->
103-
let type_ = if isUppercaseId id then moduleToken else variableToken in
115+
let type_ = if isUppercaseId id then upperCaseToken else lowerCaseToken in
104116
if debug then
105117
Printf.printf "Lident: %s %s %s\n" id (posToString pos)
106118
(Token.tokenTypeDebug type_);
107119
emitter |> emitFromPos pos (fst pos, snd pos + String.length id) ~type_
108120
| id :: segments when isUppercaseId id || isLowercaseId id ->
109-
let type_ = if isUppercaseId id then moduleToken else variableToken in
121+
let type_ = if isUppercaseId id then upperCaseToken else lowerCaseToken in
110122
if debug then
111123
Printf.printf "Ldot: %s %s %s\n" id (posToString pos)
112124
(Token.tokenTypeDebug type_);
@@ -142,6 +154,12 @@ let emitType ~id ~debug ~loc emitter =
142154
if debug then Printf.printf "Type: %s %s\n" id (locToString loc);
143155
emitter |> emitFromLoc ~loc ~type_:Token.Type
144156

157+
let emitRecordLabel ~(label : Longident.t Location.loc) ~debug emitter =
158+
emitter
159+
|> emitLongident ~lowerCaseToken:Token.Property
160+
~pos:(Utils.tupleOfLexing label.loc.loc_start)
161+
~lid:label.txt ~debug
162+
145163
let parser ~debug ~emitter ~path =
146164
let processTypeArg (coreType : Parsetree.core_type) =
147165
if debug then Printf.printf "TypeArg: %s\n" (locToString coreType.ptyp_loc)
@@ -167,6 +185,10 @@ let parser ~debug ~emitter ~path =
167185
| Ppat_var {loc; txt = id} ->
168186
if isLowercaseId id then emitter |> emitVariable ~id ~debug ~loc;
169187
Ast_mapper.default_mapper.pat mapper p
188+
| Ppat_record (cases, _) ->
189+
cases
190+
|> List.iter (fun (label, _) -> emitter |> emitRecordLabel ~label ~debug);
191+
Ast_mapper.default_mapper.pat mapper p
170192
| _ -> Ast_mapper.default_mapper.pat mapper p
171193
in
172194
let expr (mapper : Ast_mapper.mapper) (e : Parsetree.expression) =
@@ -212,6 +234,13 @@ let parser ~debug ~emitter ~path =
212234
->
213235
if debug then Printf.printf "BinaryExp: %s\n" (locToString pexp_loc);
214236
Ast_mapper.default_mapper.expr mapper e
237+
| Pexp_record (cases, _) ->
238+
cases
239+
|> List.iter (fun (label, _) -> emitter |> emitRecordLabel ~label ~debug);
240+
Ast_mapper.default_mapper.expr mapper e
241+
| Pexp_field (_, label) | Pexp_setfield (_, label, _) ->
242+
emitter |> emitRecordLabel ~label ~debug;
243+
Ast_mapper.default_mapper.expr mapper e
215244
| _ -> Ast_mapper.default_mapper.expr mapper e
216245
in
217246
let module_expr (mapper : Ast_mapper.mapper) (me : Parsetree.module_expr) =
@@ -242,7 +271,7 @@ let parser ~debug ~emitter ~path =
242271
match mt.pmty_desc with
243272
| Pmty_ident {txt = lid; loc} ->
244273
emitter
245-
|> emitLongident ~moduleToken:Token.Type
274+
|> emitLongident ~upperCaseToken:Token.Type
246275
~pos:(Utils.tupleOfLexing loc.loc_start)
247276
~lid ~debug;
248277
Ast_mapper.default_mapper.module_type mapper mt
@@ -251,7 +280,7 @@ let parser ~debug ~emitter ~path =
251280
let module_type_declaration (mapper : Ast_mapper.mapper)
252281
(mtd : Parsetree.module_type_declaration) =
253282
emitter
254-
|> emitLongident ~moduleToken:Token.Type
283+
|> emitLongident ~upperCaseToken:Token.Type
255284
~pos:(Utils.tupleOfLexing mtd.pmtd_name.loc.loc_start)
256285
~lid:(Longident.Lident mtd.pmtd_name.txt) ~debug;
257286
Ast_mapper.default_mapper.module_type_declaration mapper mtd
@@ -264,11 +293,20 @@ let parser ~debug ~emitter ~path =
264293
~lid:od.popen_lid.txt ~debug;
265294
Ast_mapper.default_mapper.open_description mapper od
266295
in
296+
let label_declaration (mapper : Ast_mapper.mapper)
297+
(ld : Parsetree.label_declaration) =
298+
emitter
299+
|> emitRecordLabel
300+
~label:{loc = ld.pld_name.loc; txt = Longident.Lident ld.pld_name.txt}
301+
~debug;
302+
Ast_mapper.default_mapper.label_declaration mapper ld
303+
in
267304

268305
let mapper =
269306
{
270307
Ast_mapper.default_mapper with
271308
expr;
309+
label_declaration;
272310
module_declaration;
273311
module_binding;
274312
module_expr;

analysis/tests/src/expected/Parser.res.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,14 @@ Type: tt (53,5)->(53,7)
5454
Type: t (53,10)->(53,11)
5555
Lident: T (57,7) Namespace
5656
Type: someRecord (58,7)->(58,17)
57+
Lident: someField (59,4) Property
5758
Type: int (59,15)->(59,18)
59+
Lident: someOtherField (60,4) Property
5860
Type: string (60,20)->(60,26)
61+
Lident: theParam (61,4) Property
5962
Type: someEnum (64,7)->(64,15)
63+
Ldot: T (67,17) Namespace
64+
Lident: someField (67,19) Property
6065
Lident: x (67,15) Variable
6166
Lident: x (67,10) Variable
6267
Lident: foo (67,4) Variable

server/src/server.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,15 @@ function onMessage(msg: m.Message) {
760760
completionProvider: { triggerCharacters: [".", ">", "@", "~", '"'] },
761761
semanticTokensProvider: {
762762
legend: {
763-
tokenTypes: ["keyword", "variable", "type", "jsx-tag", "namespace"],
763+
tokenTypes: [
764+
"keyword",
765+
"variable",
766+
"type",
767+
"jsx-tag",
768+
"namespace",
769+
"enumMember",
770+
"property",
771+
],
764772
tokenModifiers: [],
765773
},
766774
documentSelector: null,

0 commit comments

Comments
 (0)