Skip to content

Commit 9f67a58

Browse files
committed
Add support for bounds on type parameters
1 parent 65a4ee3 commit 9f67a58

File tree

4 files changed

+53985
-52523
lines changed

4 files changed

+53985
-52523
lines changed

corpus/types.txt

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,67 @@ class Function1[-T1, +R]
103103
(type_parameters
104104
(contravariant_type_parameter (identifier))
105105
(covariant_type_parameter (identifier)))))
106+
107+
108+
==================================
109+
Upper bound
110+
==================================
111+
112+
class A[B <: C]
113+
114+
---
115+
116+
(compilation_unit
117+
(class_definition
118+
(identifier)
119+
(type_parameters
120+
(identifier)
121+
(upper_bound (type_identifier)))))
122+
123+
==================================
124+
Lower bound
125+
==================================
126+
127+
class A[B >: C]
128+
129+
---
130+
131+
(compilation_unit
132+
(class_definition
133+
(identifier)
134+
(type_parameters
135+
(identifier)
136+
(lower_bound (type_identifier)))))
137+
138+
==================================
139+
View bound
140+
==================================
141+
142+
143+
class A[B <% C <% D]
144+
145+
---
146+
147+
(compilation_unit
148+
(class_definition
149+
(identifier)
150+
(type_parameters
151+
(identifier)
152+
(view_bound (type_identifier))
153+
(view_bound (type_identifier)))))
154+
155+
==================================
156+
Context bound
157+
==================================
158+
159+
class A[B : C : D]
160+
161+
---
162+
163+
(compilation_unit
164+
(class_definition
165+
(identifier)
166+
(type_parameters
167+
(identifier)
168+
(context_bound (type_identifier))
169+
(context_bound (type_identifier)))))

grammar.js

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,29 +135,51 @@ module.exports = grammar({
135135
$.template_body
136136
),
137137

138+
// The EBNF makes a distinction between function type parameters and other
139+
// type parameters as you can't specify variance on function type
140+
// parameters. This isn't important to the structure of the AST so we don't
141+
// make that distinction.
138142
type_parameters: $ => seq(
139143
'[',
140-
commaSep1($._type_parameter),
144+
commaSep1($._variant_type_parameter),
141145
']'
142146
),
143147

144-
_type_parameter: $ => choice(
145-
'_',
146-
$.covariant_type_parameter,
147-
$.contravariant_type_parameter,
148-
$.identifier // invariant type parameter
148+
_variant_type_parameter: $ => seq(
149+
choice(
150+
$.covariant_type_parameter,
151+
$.contravariant_type_parameter,
152+
$._type_parameter // invariant type parameter
153+
)
149154
),
150155

151156
covariant_type_parameter: $ => seq(
152157
'+',
153-
$.identifier
158+
$._type_parameter
154159
),
155160

156161
contravariant_type_parameter: $ => seq(
157162
'-',
158-
$.identifier
163+
$._type_parameter,
159164
),
160165

166+
_type_parameter: $ => seq(
167+
choice($.wildcard, $.identifier),
168+
optional($.type_parameters),
169+
optional($.upper_bound),
170+
optional($.lower_bound),
171+
optional(repeat($.view_bound)),
172+
optional(repeat($.context_bound)),
173+
),
174+
175+
upper_bound: $ => seq('<:', $._type),
176+
177+
lower_bound: $ => seq('>:', $._type),
178+
179+
view_bound: $ => seq('<%', $._type),
180+
181+
context_bound: $ => seq(':', $._type),
182+
161183
template_body: $ => seq(
162184
'{',
163185
repeat($._definition),

src/grammar.json

Lines changed: 151 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@
492492
"members": [
493493
{
494494
"type": "SYMBOL",
495-
"name": "_type_parameter"
495+
"name": "_variant_type_parameter"
496496
},
497497
{
498498
"type": "REPEAT",
@@ -505,7 +505,7 @@
505505
},
506506
{
507507
"type": "SYMBOL",
508-
"name": "_type_parameter"
508+
"name": "_variant_type_parameter"
509509
}
510510
]
511511
}
@@ -518,50 +518,187 @@
518518
}
519519
]
520520
},
521-
"_type_parameter": {
522-
"type": "CHOICE",
521+
"_variant_type_parameter": {
522+
"type": "SEQ",
523+
"members": [
524+
{
525+
"type": "CHOICE",
526+
"members": [
527+
{
528+
"type": "SYMBOL",
529+
"name": "covariant_type_parameter"
530+
},
531+
{
532+
"type": "SYMBOL",
533+
"name": "contravariant_type_parameter"
534+
},
535+
{
536+
"type": "SYMBOL",
537+
"name": "_type_parameter"
538+
}
539+
]
540+
}
541+
]
542+
},
543+
"covariant_type_parameter": {
544+
"type": "SEQ",
523545
"members": [
524546
{
525547
"type": "STRING",
526-
"value": "_"
548+
"value": "+"
527549
},
528550
{
529551
"type": "SYMBOL",
530-
"name": "covariant_type_parameter"
552+
"name": "_type_parameter"
553+
}
554+
]
555+
},
556+
"contravariant_type_parameter": {
557+
"type": "SEQ",
558+
"members": [
559+
{
560+
"type": "STRING",
561+
"value": "-"
531562
},
532563
{
533564
"type": "SYMBOL",
534-
"name": "contravariant_type_parameter"
565+
"name": "_type_parameter"
566+
}
567+
]
568+
},
569+
"_type_parameter": {
570+
"type": "SEQ",
571+
"members": [
572+
{
573+
"type": "CHOICE",
574+
"members": [
575+
{
576+
"type": "SYMBOL",
577+
"name": "wildcard"
578+
},
579+
{
580+
"type": "SYMBOL",
581+
"name": "identifier"
582+
}
583+
]
584+
},
585+
{
586+
"type": "CHOICE",
587+
"members": [
588+
{
589+
"type": "SYMBOL",
590+
"name": "type_parameters"
591+
},
592+
{
593+
"type": "BLANK"
594+
}
595+
]
596+
},
597+
{
598+
"type": "CHOICE",
599+
"members": [
600+
{
601+
"type": "SYMBOL",
602+
"name": "upper_bound"
603+
},
604+
{
605+
"type": "BLANK"
606+
}
607+
]
608+
},
609+
{
610+
"type": "CHOICE",
611+
"members": [
612+
{
613+
"type": "SYMBOL",
614+
"name": "lower_bound"
615+
},
616+
{
617+
"type": "BLANK"
618+
}
619+
]
620+
},
621+
{
622+
"type": "CHOICE",
623+
"members": [
624+
{
625+
"type": "REPEAT",
626+
"content": {
627+
"type": "SYMBOL",
628+
"name": "view_bound"
629+
}
630+
},
631+
{
632+
"type": "BLANK"
633+
}
634+
]
635+
},
636+
{
637+
"type": "CHOICE",
638+
"members": [
639+
{
640+
"type": "REPEAT",
641+
"content": {
642+
"type": "SYMBOL",
643+
"name": "context_bound"
644+
}
645+
},
646+
{
647+
"type": "BLANK"
648+
}
649+
]
650+
}
651+
]
652+
},
653+
"upper_bound": {
654+
"type": "SEQ",
655+
"members": [
656+
{
657+
"type": "STRING",
658+
"value": "<:"
535659
},
536660
{
537661
"type": "SYMBOL",
538-
"name": "identifier"
662+
"name": "_type"
539663
}
540664
]
541665
},
542-
"covariant_type_parameter": {
666+
"lower_bound": {
543667
"type": "SEQ",
544668
"members": [
545669
{
546670
"type": "STRING",
547-
"value": "+"
671+
"value": ">:"
548672
},
549673
{
550674
"type": "SYMBOL",
551-
"name": "identifier"
675+
"name": "_type"
552676
}
553677
]
554678
},
555-
"contravariant_type_parameter": {
679+
"view_bound": {
556680
"type": "SEQ",
557681
"members": [
558682
{
559683
"type": "STRING",
560-
"value": "-"
684+
"value": "<%"
561685
},
562686
{
563687
"type": "SYMBOL",
564-
"name": "identifier"
688+
"name": "_type"
689+
}
690+
]
691+
},
692+
"context_bound": {
693+
"type": "SEQ",
694+
"members": [
695+
{
696+
"type": "STRING",
697+
"value": ":"
698+
},
699+
{
700+
"type": "SYMBOL",
701+
"name": "_type"
565702
}
566703
]
567704
},

0 commit comments

Comments
 (0)