Skip to content

Commit 2140178

Browse files
committed
Merge branch 'semantic-highlighting' of github.com:zth/rescript-vscode into semantic-highlighting
2 parents d4ceba1 + a91494f commit 2140178

File tree

4 files changed

+105
-10
lines changed

4 files changed

+105
-10
lines changed

analysis/src/SemanticTokens.ml

Lines changed: 66 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,18 @@ 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+
163+
let emitVariant ~(name : Longident.t Location.loc) ~debug emitter =
164+
emitter
165+
|> emitLongident ~upperCaseToken:Token.EnumMember
166+
~pos:(Utils.tupleOfLexing name.loc.loc_start)
167+
~lid:name.txt ~debug
168+
145169
let parser ~debug ~emitter ~path =
146170
let processTypeArg (coreType : Parsetree.core_type) =
147171
if debug then Printf.printf "TypeArg: %s\n" (locToString coreType.ptyp_loc)
@@ -167,6 +191,13 @@ let parser ~debug ~emitter ~path =
167191
| Ppat_var {loc; txt = id} ->
168192
if isLowercaseId id then emitter |> emitVariable ~id ~debug ~loc;
169193
Ast_mapper.default_mapper.pat mapper p
194+
| Ppat_record (cases, _) ->
195+
cases
196+
|> List.iter (fun (label, _) -> emitter |> emitRecordLabel ~label ~debug);
197+
Ast_mapper.default_mapper.pat mapper p
198+
| Ppat_construct (name, _) ->
199+
emitter |> emitVariant ~name ~debug;
200+
Ast_mapper.default_mapper.pat mapper p
170201
| _ -> Ast_mapper.default_mapper.pat mapper p
171202
in
172203
let expr (mapper : Ast_mapper.mapper) (e : Parsetree.expression) =
@@ -212,6 +243,16 @@ let parser ~debug ~emitter ~path =
212243
->
213244
if debug then Printf.printf "BinaryExp: %s\n" (locToString pexp_loc);
214245
Ast_mapper.default_mapper.expr mapper e
246+
| Pexp_record (cases, _) ->
247+
cases
248+
|> List.iter (fun (label, _) -> emitter |> emitRecordLabel ~label ~debug);
249+
Ast_mapper.default_mapper.expr mapper e
250+
| Pexp_field (_, label) | Pexp_setfield (_, label, _) ->
251+
emitter |> emitRecordLabel ~label ~debug;
252+
Ast_mapper.default_mapper.expr mapper e
253+
| Pexp_construct (name, _) ->
254+
emitter |> emitVariant ~name ~debug;
255+
Ast_mapper.default_mapper.expr mapper e
215256
| _ -> Ast_mapper.default_mapper.expr mapper e
216257
in
217258
let module_expr (mapper : Ast_mapper.mapper) (me : Parsetree.module_expr) =
@@ -242,7 +283,7 @@ let parser ~debug ~emitter ~path =
242283
match mt.pmty_desc with
243284
| Pmty_ident {txt = lid; loc} ->
244285
emitter
245-
|> emitLongident ~moduleToken:Token.Type
286+
|> emitLongident ~upperCaseToken:Token.Type
246287
~pos:(Utils.tupleOfLexing loc.loc_start)
247288
~lid ~debug;
248289
Ast_mapper.default_mapper.module_type mapper mt
@@ -251,7 +292,7 @@ let parser ~debug ~emitter ~path =
251292
let module_type_declaration (mapper : Ast_mapper.mapper)
252293
(mtd : Parsetree.module_type_declaration) =
253294
emitter
254-
|> emitLongident ~moduleToken:Token.Type
295+
|> emitLongident ~upperCaseToken:Token.Type
255296
~pos:(Utils.tupleOfLexing mtd.pmtd_name.loc.loc_start)
256297
~lid:(Longident.Lident mtd.pmtd_name.txt) ~debug;
257298
Ast_mapper.default_mapper.module_type_declaration mapper mtd
@@ -264,11 +305,29 @@ let parser ~debug ~emitter ~path =
264305
~lid:od.popen_lid.txt ~debug;
265306
Ast_mapper.default_mapper.open_description mapper od
266307
in
308+
let label_declaration (mapper : Ast_mapper.mapper)
309+
(ld : Parsetree.label_declaration) =
310+
emitter
311+
|> emitRecordLabel
312+
~label:{loc = ld.pld_name.loc; txt = Longident.Lident ld.pld_name.txt}
313+
~debug;
314+
Ast_mapper.default_mapper.label_declaration mapper ld
315+
in
316+
let constructor_declaration (mapper : Ast_mapper.mapper)
317+
(cd : Parsetree.constructor_declaration) =
318+
emitter
319+
|> emitVariant
320+
~name:{loc = cd.pcd_name.loc; txt = Longident.Lident cd.pcd_name.txt}
321+
~debug;
322+
Ast_mapper.default_mapper.constructor_declaration mapper cd
323+
in
267324

268325
let mapper =
269326
{
270327
Ast_mapper.default_mapper with
328+
constructor_declaration;
271329
expr;
330+
label_declaration;
272331
module_declaration;
273332
module_binding;
274333
module_expr;

analysis/tests/src/Parser.res

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,16 @@ open XX.YY
5353

5454
type tt = t
5555

56-
// ^par
56+
// ^par
57+
58+
module T = {
59+
type someRecord<'typeParameter> = {
60+
someField: int,
61+
someOtherField: string,
62+
theParam: 'typeParameter,
63+
}
64+
65+
type someEnum = A | B | C
66+
}
67+
68+
let foo = x => x.T.someField

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Parse tests/src/Parser.res
2-
structure items:15 diagnostics:0
2+
structure items:17 diagnostics:0
33
Lident: M (0,7) Namespace
44
Lident: C (1,9) Namespace
55
Lident: Component (1,13) Namespace
@@ -52,4 +52,20 @@ Ldot: XX (51,5) Namespace
5252
Lident: YY (51,8) Namespace
5353
Type: tt (53,5)->(53,7)
5454
Type: t (53,10)->(53,11)
55+
Lident: T (57,7) Namespace
56+
Type: someRecord (58,7)->(58,17)
57+
Lident: someField (59,4) Property
58+
Type: int (59,15)->(59,18)
59+
Lident: someOtherField (60,4) Property
60+
Type: string (60,20)->(60,26)
61+
Lident: theParam (61,4) Property
62+
Type: someEnum (64,7)->(64,15)
63+
Lident: A (64,18) EnumMember
64+
Lident: B (64,22) EnumMember
65+
Lident: C (64,26) EnumMember
66+
Ldot: T (67,17) Namespace
67+
Lident: someField (67,19) Property
68+
Lident: x (67,15) Variable
69+
Lident: x (67,10) Variable
70+
Lident: foo (67,4) Variable
5571

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)