Skip to content

Commit b58a31c

Browse files
authored
Add [export] type function and read/write modifiers on types (#18)
* Allow `read` or `write` keywords in type properties * Add `type-function` pattern * Update Luau.tmLanguage and Luau.tmLanguage.json * Include `#function-definition` * Update Luau.tmLanguage and Luau.tmLanguage.json * Fix type functions * Update Luau.tmLanguage and Luau.tmLanguage.json * Add tests for type functions and `read`/`write` modifiers --------- Co-authored-by: Matheus <[email protected]>
1 parent d548548 commit b58a31c

7 files changed

+530
-7
lines changed

Luau.YAML-tmLanguage

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ patterns:
2323
- include: "#comment"
2424
- include: "#local-declaration"
2525
- include: "#for-loop"
26+
- include: "#type-function"
2627
- include: "#type-alias-declaration"
2728
- include: "#keyword"
2829
- include: "#language_constant"
@@ -315,6 +316,42 @@ repository:
315316
# - match: ","
316317
# name: punctuation.separator.generics.luau
317318

319+
type-function:
320+
# TODO: don't match start of line, it's not really correct. but we need to make sure we handle appropraitely if we remove ^
321+
begin: "^\\b(?:(export)\\s+)?(type)\\s+(function)\\b"
322+
beginCaptures:
323+
"1": { name: storage.modifier.visibility.luau }
324+
"2": { name: storage.type.luau }
325+
"3": { name: keyword.control.luau }
326+
end: "(?<=[\\)\\-{}\\[\\]\"'])"
327+
name: meta.function.luau
328+
patterns:
329+
- include: "#comment"
330+
- include: "#generics-declaration"
331+
- begin: "(\\()"
332+
beginCaptures:
333+
"1": { name: punctuation.definition.parameters.begin.luau }
334+
end: "(\\))"
335+
endCaptures:
336+
"1": { name: punctuation.definition.parameters.end.luau }
337+
name: meta.parameter.luau
338+
patterns:
339+
- include: "#comment"
340+
- match: "\\.\\.\\."
341+
name: variable.parameter.function.varargs.luau
342+
- match: "{{identifier}}"
343+
name: variable.parameter.function.luau
344+
- match: ","
345+
name: punctuation.separator.arguments.luau
346+
- begin: ":"
347+
beginCaptures:
348+
"0": { name: keyword.operator.type.luau }
349+
end: "(?=[\\),])"
350+
patterns:
351+
- include: "#type_literal"
352+
- match: "\\b({{identifier}})\\b"
353+
name: entity.name.type.luau
354+
318355
type-alias-declaration:
319356
# TODO: don't match start of line, it's not really correct. but we need to make sure we handle appropraitely if we remove ^
320357
begin: "^\\b(?:(export)\\s+)?(type)\\b"
@@ -384,10 +421,11 @@ repository:
384421
end: "\\]" # TODO: do we need to match the ':' afterwards?
385422
patterns:
386423
- include: "#type_literal"
387-
- match: "\\b({{identifier}})\\b(:)"
424+
- match: "\\b(?:(read|write)\\s+)?({{identifier}})\\b(:)"
388425
captures:
389-
"1": { name: variable.property.luau }
390-
"2": { name: keyword.operator.type.luau }
426+
"1": { name: storage.modifier.access.luau }
427+
"2": { name: variable.property.luau }
428+
"3": { name: keyword.operator.type.luau }
391429
- include: "#type_literal"
392430
- match: "[,;]"
393431
name: punctuation.separator.fields.type.luau

Luau.tmLanguage

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
<key>include</key>
4747
<string>#for-loop</string>
4848
</dict>
49+
<dict>
50+
<key>include</key>
51+
<string>#type-function</string>
52+
</dict>
4953
<dict>
5054
<key>include</key>
5155
<string>#type-alias-declaration</string>
@@ -873,6 +877,120 @@
873877
</dict>
874878
</array>
875879
</dict>
880+
<key>type-function</key>
881+
<dict>
882+
<key>begin</key>
883+
<string>^\b(?:(export)\s+)?(type)\s+(function)\b</string>
884+
<key>beginCaptures</key>
885+
<dict>
886+
<key>1</key>
887+
<dict>
888+
<key>name</key>
889+
<string>storage.modifier.visibility.luau</string>
890+
</dict>
891+
<key>2</key>
892+
<dict>
893+
<key>name</key>
894+
<string>storage.type.luau</string>
895+
</dict>
896+
<key>3</key>
897+
<dict>
898+
<key>name</key>
899+
<string>keyword.control.luau</string>
900+
</dict>
901+
</dict>
902+
<key>end</key>
903+
<string>(?&lt;=[\)\-{}\[\]"'])</string>
904+
<key>name</key>
905+
<string>meta.function.luau</string>
906+
<key>patterns</key>
907+
<array>
908+
<dict>
909+
<key>include</key>
910+
<string>#comment</string>
911+
</dict>
912+
<dict>
913+
<key>include</key>
914+
<string>#generics-declaration</string>
915+
</dict>
916+
<dict>
917+
<key>begin</key>
918+
<string>(\()</string>
919+
<key>beginCaptures</key>
920+
<dict>
921+
<key>1</key>
922+
<dict>
923+
<key>name</key>
924+
<string>punctuation.definition.parameters.begin.luau</string>
925+
</dict>
926+
</dict>
927+
<key>end</key>
928+
<string>(\))</string>
929+
<key>endCaptures</key>
930+
<dict>
931+
<key>1</key>
932+
<dict>
933+
<key>name</key>
934+
<string>punctuation.definition.parameters.end.luau</string>
935+
</dict>
936+
</dict>
937+
<key>name</key>
938+
<string>meta.parameter.luau</string>
939+
<key>patterns</key>
940+
<array>
941+
<dict>
942+
<key>include</key>
943+
<string>#comment</string>
944+
</dict>
945+
<dict>
946+
<key>match</key>
947+
<string>\.\.\.</string>
948+
<key>name</key>
949+
<string>variable.parameter.function.varargs.luau</string>
950+
</dict>
951+
<dict>
952+
<key>match</key>
953+
<string>[a-zA-Z_][a-zA-Z0-9_]*</string>
954+
<key>name</key>
955+
<string>variable.parameter.function.luau</string>
956+
</dict>
957+
<dict>
958+
<key>match</key>
959+
<string>,</string>
960+
<key>name</key>
961+
<string>punctuation.separator.arguments.luau</string>
962+
</dict>
963+
<dict>
964+
<key>begin</key>
965+
<string>:</string>
966+
<key>beginCaptures</key>
967+
<dict>
968+
<key>0</key>
969+
<dict>
970+
<key>name</key>
971+
<string>keyword.operator.type.luau</string>
972+
</dict>
973+
</dict>
974+
<key>end</key>
975+
<string>(?=[\),])</string>
976+
<key>patterns</key>
977+
<array>
978+
<dict>
979+
<key>include</key>
980+
<string>#type_literal</string>
981+
</dict>
982+
</array>
983+
</dict>
984+
</array>
985+
</dict>
986+
<dict>
987+
<key>match</key>
988+
<string>\b([a-zA-Z_][a-zA-Z0-9_]*)\b</string>
989+
<key>name</key>
990+
<string>entity.name.type.luau</string>
991+
</dict>
992+
</array>
993+
</dict>
876994
<key>type-alias-declaration</key>
877995
<dict>
878996
<key>begin</key>
@@ -1085,15 +1203,20 @@
10851203
</dict>
10861204
<dict>
10871205
<key>match</key>
1088-
<string>\b([a-zA-Z_][a-zA-Z0-9_]*)\b(:)</string>
1206+
<string>\b(?:(read|write)\s+)?([a-zA-Z_][a-zA-Z0-9_]*)\b(:)</string>
10891207
<key>captures</key>
10901208
<dict>
10911209
<key>1</key>
10921210
<dict>
10931211
<key>name</key>
1094-
<string>variable.property.luau</string>
1212+
<string>storage.modifier.access.luau</string>
10951213
</dict>
10961214
<key>2</key>
1215+
<dict>
1216+
<key>name</key>
1217+
<string>variable.property.luau</string>
1218+
</dict>
1219+
<key>3</key>
10971220
<dict>
10981221
<key>name</key>
10991222
<string>keyword.operator.type.luau</string>

Luau.tmLanguage.json

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
{
3232
"include": "#for-loop"
3333
},
34+
{
35+
"include": "#type-function"
36+
},
3437
{
3538
"include": "#type-alias-declaration"
3639
},
@@ -576,6 +579,80 @@
576579
}
577580
]
578581
},
582+
"type-function": {
583+
"begin": "^\\b(?:(export)\\s+)?(type)\\s+(function)\\b",
584+
"beginCaptures": {
585+
"1": {
586+
"name": "storage.modifier.visibility.luau"
587+
},
588+
"2": {
589+
"name": "storage.type.luau"
590+
},
591+
"3": {
592+
"name": "keyword.control.luau"
593+
}
594+
},
595+
"end": "(?<=[\\)\\-{}\\[\\]\"'])",
596+
"name": "meta.function.luau",
597+
"patterns": [
598+
{
599+
"include": "#comment"
600+
},
601+
{
602+
"include": "#generics-declaration"
603+
},
604+
{
605+
"begin": "(\\()",
606+
"beginCaptures": {
607+
"1": {
608+
"name": "punctuation.definition.parameters.begin.luau"
609+
}
610+
},
611+
"end": "(\\))",
612+
"endCaptures": {
613+
"1": {
614+
"name": "punctuation.definition.parameters.end.luau"
615+
}
616+
},
617+
"name": "meta.parameter.luau",
618+
"patterns": [
619+
{
620+
"include": "#comment"
621+
},
622+
{
623+
"match": "\\.\\.\\.",
624+
"name": "variable.parameter.function.varargs.luau"
625+
},
626+
{
627+
"match": "[a-zA-Z_][a-zA-Z0-9_]*",
628+
"name": "variable.parameter.function.luau"
629+
},
630+
{
631+
"match": ",",
632+
"name": "punctuation.separator.arguments.luau"
633+
},
634+
{
635+
"begin": ":",
636+
"beginCaptures": {
637+
"0": {
638+
"name": "keyword.operator.type.luau"
639+
}
640+
},
641+
"end": "(?=[\\),])",
642+
"patterns": [
643+
{
644+
"include": "#type_literal"
645+
}
646+
]
647+
}
648+
]
649+
},
650+
{
651+
"match": "\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b",
652+
"name": "entity.name.type.luau"
653+
}
654+
]
655+
},
579656
"type-alias-declaration": {
580657
"begin": "^\\b(?:(export)\\s+)?(type)\\b",
581658
"end": "(?=\\s*$)|(?=\\s*;)",
@@ -714,12 +791,15 @@
714791
]
715792
},
716793
{
717-
"match": "\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b(:)",
794+
"match": "\\b(?:(read|write)\\s+)?([a-zA-Z_][a-zA-Z0-9_]*)\\b(:)",
718795
"captures": {
719796
"1": {
720-
"name": "variable.property.luau"
797+
"name": "storage.modifier.access.luau"
721798
},
722799
"2": {
800+
"name": "variable.property.luau"
801+
},
802+
"3": {
723803
"name": "keyword.operator.type.luau"
724804
}
725805
}

0 commit comments

Comments
 (0)