Skip to content

Commit cabb478

Browse files
authored
Merge pull request rescript-lang#54 from nkrkv/test-world
Tests and fixes in the wild
2 parents c0dea78 + 4c2c14e commit cabb478

File tree

13 files changed

+176
-44
lines changed

13 files changed

+176
-44
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ node_modules/
33
src/*
44
!src/scanner.c
55
log.html
6+
test_wild/

Makefile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,27 @@
11

22
TS=yarn tree-sitter
33

4+
# This is an opinionated list of significant ReScript repos on GitHub
5+
# that are representative and trick-heavy enough to be a subject
6+
# for acceptance testing. The general idea: if `tree-sitter-rescript`
7+
# is 100% legit for this codebase, it should satisfy everyone.
8+
wild_github_repos := rescript-lang/rescript-react \
9+
tinymce/rescript-webapi
10+
11+
wild_sandboxes := $(patsubst %,test_wild/%,$(wild_github_repos))
12+
413
.PHONY: generate
514
generate:
615
$(TS) generate
716

817
.PHONY: test
918
test: generate
1019
$(TS) test
20+
21+
test_wild/%:
22+
@mkdir -p test_wild/
23+
git clone --depth=1 https://github.com/$* ./$@
24+
25+
.PHONY: test_wild
26+
test_wild: $(wild_sandboxes)
27+
$(TS) parse --quiet --stat '$@/**/*.res*'

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ Contributions are welcome. Here’s how you can help:
1919
yarn tree-sitter parse /path/to/your/snippet.res
2020
```
2121

22-
🤩 Add a failing test case for a snippet which is valid ReScript but produces an incorrect syntax tree. Fix the `grammar.js`. Make sure nothing is broken: `make test` shows 100% test success. Open a pull request.
22+
🤩 Add a failing test case for a snippet which is valid ReScript but produces an incorrect syntax tree. Fix the `grammar.js`. Make sure nothing is broken: `make test test_wild` shows 100% test success. Open a pull request.

grammar.js

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ module.exports = grammar({
4040
'coercion_relation',
4141
$.expression,
4242
$.primary_expression,
43+
$.ternary_expression,
44+
$.mutation_expression,
4345
$.function,
4446
$.let_binding,
4547
],
@@ -52,6 +54,9 @@ module.exports = grammar({
5254
[$.unit, $.formal_parameters],
5355
[$.pipe_expression, $.expression],
5456
[$.primary_expression, $._pattern],
57+
[$.primary_expression, $.record_pattern],
58+
[$.primary_expression, $.spread_pattern],
59+
[$.primary_expression, $._literal_pattern],
5560
[$.tuple_pattern, $._formal_parameter],
5661
[$.primary_expression, $._formal_parameter],
5762
[$.primary_expression, $.record_field],
@@ -60,8 +65,6 @@ module.exports = grammar({
6065
[$.list, $.list_pattern],
6166
[$.array, $.array_pattern],
6267
[$.record_field, $.record_pattern],
63-
[$.primary_expression, $.spread_pattern],
64-
[$.primary_expression, $._literal_pattern],
6568
[$.expression_statement, $.ternary_expression],
6669
[$.let_binding, $.ternary_expression],
6770
[$.variant_identifier, $.module_identifier],
@@ -98,9 +101,7 @@ module.exports = grammar({
98101
alias($._decorated_statement, $.decorated),
99102
$.decorator_statement,
100103
$.expression_statement,
101-
$.mutation_statement,
102104
$.declaration,
103-
$.block,
104105
$.open_statement,
105106
$.include_statement,
106107
),
@@ -213,6 +214,7 @@ module.exports = grammar({
213214
optional($.type_parameters),
214215
optional(seq(
215216
'=',
217+
optional('private'),
216218
$._type,
217219
))
218220
),
@@ -364,11 +366,11 @@ module.exports = grammar({
364366
let_binding: $ => seq(
365367
choice('export', 'let'),
366368
optional('rec'),
367-
$._pattern,
369+
choice($._pattern, $.unit),
368370
optional($.type_annotation),
369371
optional(seq(
370372
'=',
371-
choice($.expression, $.block),
373+
$.expression,
372374
)),
373375
),
374376

@@ -382,6 +384,8 @@ module.exports = grammar({
382384
$.binary_expression,
383385
$.coercion_expression,
384386
$.ternary_expression,
387+
$.mutation_expression,
388+
$.block,
385389
),
386390

387391
primary_expression: $ => choice(
@@ -431,10 +435,7 @@ module.exports = grammar({
431435
$._definition_signature
432436
),
433437
'=>',
434-
field('body', choice(
435-
$.expression,
436-
$.block
437-
)),
438+
field('body', $.expression),
438439
)),
439440

440441
record: $ => seq(
@@ -802,6 +803,7 @@ module.exports = grammar({
802803

803804
_jsx_child: $ => choice(
804805
$.value_identifier,
806+
$.value_identifier_path,
805807
$._jsx_element,
806808
$.jsx_fragment,
807809
$.jsx_expression
@@ -862,7 +864,7 @@ module.exports = grammar({
862864
$.jsx_expression,
863865
),
864866

865-
mutation_statement: $ => seq(
867+
mutation_expression: $ => seq(
866868
$._mutation_lvalue,
867869
choice('=', ':='),
868870
$.expression,
@@ -1096,11 +1098,14 @@ module.exports = grammar({
10961098
seq(optional('0'), /[1-9]/, optional(seq(optional('_'), decimal_digits)))
10971099
)
10981100

1099-
const decimal_literal = choice(
1100-
seq(decimal_integer_literal, '.', optional(decimal_digits), optional(exponent_part)),
1101-
seq('.', decimal_digits, optional(exponent_part)),
1102-
seq(decimal_integer_literal, exponent_part),
1103-
seq(decimal_digits),
1101+
const decimal_literal = seq(
1102+
optional(choice('-', '+')),
1103+
choice(
1104+
seq(decimal_integer_literal, '.', optional(decimal_digits), optional(exponent_part)),
1105+
seq('.', decimal_digits, optional(exponent_part)),
1106+
seq(decimal_integer_literal, exponent_part),
1107+
seq(decimal_digits),
1108+
)
11041109
)
11051110

11061111
return token(choice(

queries/highlights.scm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
"let"
9999
"module"
100100
"mutable"
101+
"private"
101102
"rec"
102103
"type"
103104
] @keyword

src/scanner.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ typedef struct ScannerState {
1717
int parens_nesting;
1818
bool in_quotes;
1919
bool in_backticks;
20+
bool eof_reported;
2021
} ScannerState;
2122

2223
void *tree_sitter_rescript_external_scanner_create() {
@@ -152,6 +153,17 @@ bool tree_sitter_rescript_external_scanner_scan(
152153
return true;
153154
}
154155

156+
// If a source file missing EOL at EOF, give the last statement a chance:
157+
// report the statement delimiting EOL at the very end of file. Make sure
158+
// it’s done only once, otherwise the scanner will enter dead-lock because
159+
// we report NEWLINE again and again, no matter the lexer is exhausted
160+
// already.
161+
if (valid_symbols[NEWLINE] && lexer->eof(lexer) && !state->eof_reported) {
162+
lexer->result_symbol = NEWLINE;
163+
state->eof_reported = true;
164+
return true;
165+
}
166+
155167
// Magic ahead!
156168
// We have two types of newline in ReScript. The one which ends the current statement,
157169
// and the one used just for pretty-formatting (e.g. separates variant type values).

test/corpus/expressions.txt

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ keep(
8080
item =>
8181
item->Foo.bar == 5
8282
)
83+
blocky(
84+
1,
85+
{
86+
open Mod
87+
qrux
88+
},
89+
~third={3},
90+
)
8391

8492
---
8593

@@ -124,7 +132,18 @@ keep(
124132
(value_identifier_path
125133
(module_identifier)
126134
(value_identifier)))
127-
right: (number)))))))
135+
right: (number))))))
136+
(expression_statement
137+
(call_expression
138+
function: (value_identifier)
139+
arguments: (arguments
140+
(number)
141+
(block
142+
(open_statement (module_identifier))
143+
(expression_statement (value_identifier)))
144+
(labeled_argument
145+
label: (value_identifier)
146+
value: (block (expression_statement (number))))))))
128147

129148
===========================================
130149
Pipe
@@ -620,6 +639,27 @@ switch parseExn(str) {
620639
(formal_parameters (value_identifier))))
621640
(expression_statement (number))))))
622641

642+
===========================================
643+
Switch block
644+
===========================================
645+
646+
switch { open Mod; foo() } {
647+
| _ => 42
648+
}
649+
650+
---
651+
652+
(source_file
653+
(expression_statement
654+
(switch_expression
655+
(block
656+
(open_statement (module_identifier))
657+
(expression_statement
658+
(call_expression (value_identifier) (arguments))))
659+
(switch_match
660+
(value_identifier)
661+
(expression_statement (number))))))
662+
623663
===========================================
624664
Math operators
625665
===========================================
@@ -887,3 +927,27 @@ try {
887927
(nested_variant_identifier (module_identifier) (module_identifier) (variant_identifier))
888928
(formal_parameters (value_identifier)))
889929
(expression_statement (number))))))
930+
931+
===========================================
932+
Mutation expressions
933+
===========================================
934+
935+
foo["bar"] = qux
936+
foo.bar = qux
937+
foo.bar := qux
938+
939+
---
940+
941+
(source_file
942+
(expression_statement
943+
(mutation_expression
944+
(subscript_expression (value_identifier) (string (string_fragment)))
945+
(value_identifier)))
946+
(expression_statement
947+
(mutation_expression
948+
(member_expression (value_identifier) (property_identifier))
949+
(value_identifier)))
950+
(expression_statement
951+
(mutation_expression
952+
(member_expression (value_identifier) (property_identifier))
953+
(value_identifier))))

test/corpus/functions.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,24 @@ Record pattern
131131
(value_identifier)))
132132
(number))))
133133

134+
===================================================
135+
Ref assignment as body
136+
===================================================
137+
138+
reactRef => myRef := Some(reactRef)
139+
140+
---
141+
142+
(source_file
143+
(expression_statement
144+
(function
145+
(value_identifier)
146+
(mutation_expression
147+
(value_identifier)
148+
(variant
149+
(variant_identifier)
150+
(arguments (value_identifier)))))))
151+
134152
===================================================
135153
Operator precendence
136154
===================================================

test/corpus/jsx.txt

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
Simple JSX elements
33
==============================================
44

5-
<div className="b" tabIndex={1} />;
6-
<Foo.Bar>a <span>b</span> c</Foo.Bar>;
7-
<Foo.Bar.Baz.Baz></Foo.Bar.Baz.Baz>;
5+
<div className="b" tabIndex={1} />
6+
<Foo.Bar>a <span>b</span> c</Foo.Bar>
7+
<Foo.Bar.Baz.Baz></Foo.Bar.Baz.Baz>
8+
<div> React.null </div>
89

910
---
1011

@@ -37,7 +38,12 @@ Simple JSX elements
3738
(nested_jsx_identifier
3839
(nested_jsx_identifier (jsx_identifier) (jsx_identifier))
3940
(jsx_identifier))
40-
(jsx_identifier))))))
41+
(jsx_identifier)))))
42+
(expression_statement
43+
(jsx_element
44+
(jsx_opening_element (jsx_identifier))
45+
(value_identifier_path (module_identifier) (value_identifier))
46+
(jsx_closing_element (jsx_identifier)))))
4147

4248
==============================================
4349
Attribute values
@@ -74,8 +80,8 @@ Attribute values
7480
Anonymous JSX element
7581
==============================================
7682

77-
<></>;
78-
<E><></></E>;
83+
<></>
84+
<E><></></E>
7985

8086
---
8187

test/corpus/let_bindings.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,13 @@ let rec foo = n => foo(n-1)
9393
(binary_expression
9494
(value_identifier)
9595
(number)))))))
96+
97+
============================================
98+
Unit
99+
============================================
100+
101+
let () = noop
102+
103+
---
104+
105+
(source_file (let_binding (unit) (value_identifier)))

0 commit comments

Comments
 (0)