Skip to content

Commit 0ad76a9

Browse files
committed
support for first class modules
1 parent 4282bfa commit 0ad76a9

File tree

7 files changed

+160
-34
lines changed

7 files changed

+160
-34
lines changed

grammar.js

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ module.exports = grammar({
166166
'module',
167167
optional('rec'),
168168
optional('type'),
169-
field('name', $.module_identifier),
169+
field('name', choice($.module_identifier, $._type_identifier)),
170170
optional(seq(
171171
':',
172172
field('signature', choice($.block, $.module_expression, $.functor)),
@@ -182,8 +182,11 @@ module.exports = grammar({
182182
$.module_expression,
183183
$.functor,
184184
$.extension_expression,
185+
$.module_unpack,
185186
),
186187

188+
module_unpack: $ => seq('unpack', $.call_arguments),
189+
187190
functor: $ => seq(
188191
field('parameters', $.functor_parameters),
189192
optional(field('return_module_type', $.module_type_annotation)),
@@ -276,6 +279,17 @@ module.exports = grammar({
276279
$.object_type,
277280
$.generic_type,
278281
$.unit_type,
282+
$.module_type,
283+
),
284+
285+
module_type: $ => seq(
286+
'module',
287+
'(',
288+
choice($.module_identifier, $._type_identifier),
289+
optional(
290+
seq('with', sep1('and', seq('type', $._type_identifier, '=', $._type_identifier)))
291+
),
292+
')'
279293
),
280294

281295
tuple_type: $ => prec.dynamic(-1, seq(
@@ -428,6 +442,7 @@ module.exports = grammar({
428442
$.record_pattern,
429443
$.array_pattern,
430444
$.list_pattern,
445+
$.module_unpack_pattern,
431446
$.unit
432447
),
433448

@@ -474,7 +489,7 @@ module.exports = grammar({
474489
$.pipe_expression,
475490
$.subscript_expression,
476491
$.member_expression,
477-
$.module_destructuring_expression,
492+
$.module_pack_expression,
478493
$.extension_expression,
479494
),
480495

@@ -700,8 +715,17 @@ module.exports = grammar({
700715
),
701716
)),
702717

703-
module_destructuring_expression: $ => seq(
704-
'module', '(', choice($.module_identifier, $.module_identifier_path), ')'
718+
module_pack_expression: $ => seq(
719+
'module', '(',
720+
choice(
721+
seq(
722+
field('name', choice($.module_identifier, $.module_identifier_path)),
723+
optional(field('signature', seq(':', $.module_identifier))),
724+
optional(field('definition', seq('(', $.module_unpack, ')')))
725+
),
726+
seq(field('definition', $.block), ':', field('signature', $.module_identifier))
727+
),
728+
')'
705729
),
706730

707731
call_arguments: $ => seq(
@@ -770,7 +794,7 @@ module.exports = grammar({
770794

771795
type_parameter: $ => seq(
772796
'type',
773-
$.type_identifier,
797+
repeat($.type_identifier),
774798
),
775799

776800
_labeled_parameter_default_value: $ => seq(
@@ -884,6 +908,10 @@ module.exports = grammar({
884908
choice($.value_identifier, $.list_pattern, $.array_pattern),
885909
),
886910

911+
module_unpack_pattern: $ => seq(
912+
'module', '(', $.module_identifier, ')',
913+
),
914+
887915
_jsx_element: $ => choice($.jsx_element, $.jsx_self_closing_element),
888916

889917
jsx_element: $ => seq(

queries/highlights.scm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@
7575

7676
(function parameter: (value_identifier) @parameter)
7777

78+
("unpack") @function.builtin
79+
7880
; Meta
7981
;-----
8082

test/corpus/let_bindings.txt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,55 @@ let test = (. ~attr) => ()
247247
(labeled_parameter
248248
(value_identifier))))
249249
(unit))))
250+
251+
===========================================
252+
Destructuring module
253+
===========================================
254+
255+
256+
let {foo, bar} = module(User)
257+
let {baz, _} = module(User.Inner)
258+
259+
---
260+
261+
(source_file
262+
(let_binding
263+
(record_pattern
264+
(value_identifier)
265+
(value_identifier))
266+
(module_pack_expression (module_identifier)))
267+
268+
(let_binding
269+
(record_pattern
270+
(value_identifier)
271+
(value_identifier))
272+
(module_pack_expression
273+
(module_identifier_path
274+
(module_identifier)
275+
(module_identifier)))))
276+
277+
===========================================
278+
Packing module
279+
===========================================
280+
281+
let foo = module(Bar)
282+
283+
---
284+
285+
(source_file
286+
(let_binding
287+
(value_identifier)
288+
(module_pack_expression (module_identifier))))
289+
290+
===========================================
291+
Unpacking module
292+
===========================================
293+
294+
let module(Bar) = foo
295+
296+
---
297+
298+
(source_file
299+
(let_binding
300+
(module_unpack_pattern (module_identifier))
301+
(value_identifier)))

test/corpus/modules.txt

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,6 @@ open! Foo.Bar
1212
(open_statement
1313
(module_identifier_path (module_identifier) (module_identifier))))
1414

15-
===========================================
16-
Module destructuring
17-
===========================================
18-
19-
20-
let {foo, bar} = module(User)
21-
let {baz, _} = module(User.Inner)
22-
23-
---
24-
25-
(source_file
26-
(let_binding
27-
(record_pattern
28-
(value_identifier)
29-
(value_identifier))
30-
(module_destructuring_expression (module_identifier)))
31-
32-
(let_binding
33-
(record_pattern
34-
(value_identifier)
35-
(value_identifier))
36-
(module_destructuring_expression
37-
(module_identifier_path
38-
(module_identifier)
39-
(module_identifier)))))
40-
4115
===========================================
4216
Include
4317
===========================================
@@ -156,6 +130,7 @@ Module types
156130

157131
module type S1 = { type t }
158132
module type S2 = module type of MyModule.Submod
133+
module type t
159134

160135
---
161136

@@ -165,7 +140,38 @@ module type S2 = module type of MyModule.Submod
165140
(block (type_declaration (type_identifier))))
166141
(module_declaration
167142
(module_identifier)
168-
(module_type_of (module_identifier_path (module_identifier) (module_identifier)))))
143+
(module_type_of (module_identifier_path (module_identifier) (module_identifier))))
144+
(module_declaration (type_identifier)))
145+
146+
===========================================
147+
First Class module
148+
===========================================
149+
150+
module(LightTheme)
151+
module(A: A)
152+
module(
153+
{
154+
type t
155+
let foo = "Hello"
156+
}: X
157+
)
158+
159+
---
160+
161+
(source_file
162+
(expression_statement
163+
(module_pack_expression (module_identifier)))
164+
(expression_statement
165+
(module_pack_expression (module_identifier) (module_identifier)))
166+
(expression_statement
167+
(module_pack_expression
168+
(block
169+
(type_declaration (type_identifier))
170+
(let_binding
171+
(value_identifier)
172+
(string (string_fragment))))
173+
(module_identifier))))
174+
169175

170176
===========================================
171177
Functor definition

test/corpus/type_declarations.txt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ type t =
136136
| @live("t.D") D
137137
| B(anotherType)
138138
| C({foo: int, bar: string})
139+
| D(module(Foo))
140+
| D(module(Bar.t))
139141

140142
---
141143

@@ -156,8 +158,16 @@ type t =
156158
(record_type_field
157159
(property_identifier) (type_annotation (type_identifier)))
158160
(record_type_field
159-
(property_identifier) (type_annotation (type_identifier)))
160-
))))))
161+
(property_identifier) (type_annotation (type_identifier))))))
162+
(variant_declaration
163+
(variant_identifier)
164+
(variant_parameters
165+
(module_type (module_identifier))))
166+
(variant_declaration
167+
(variant_identifier)
168+
(variant_parameters
169+
(module_type
170+
(type_identifier_path (module_identifier) (type_identifier))))))))
161171

162172
===========================================
163173
Annotated variant

test/highlight/modules.res

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,29 @@ module Belt = {
2222
// ^ keyword
2323
// ^ operator
2424
}
25+
26+
let a = module(
27+
// ^ keyword
28+
{
29+
type t
30+
let hello = "Hello"
31+
}: X
32+
// ^ namespace
33+
)
34+
35+
module B = unpack(a)
36+
// ^ function.builtin
37+
38+
module type A = {
39+
type t = int
40+
let value: t
41+
}
42+
43+
module A: A = {
44+
type t = int
45+
let value: t = 42
46+
}
47+
48+
let packedA = module(A: A)
49+
// ^ namespace
50+
// ^ namespace

test/highlight/type_declarations.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ type rec t =
88
// ^ type
99
| Terminal
1010
// ^ constant
11+
| Component(module(Foo.t))
12+
// ^ keyword
1113

1214
type obj = {
1315
"x": int,

0 commit comments

Comments
 (0)