-
Notifications
You must be signed in to change notification settings - Fork 61
Type parameter variance #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
cc7a8c1
6ba021e
6d30212
a481a6b
7265c8f
c92323d
65a4ee3
9f67a58
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package a.b | ||
| package c { | ||
| object A | ||
| } | ||
| package c { | ||
| package object d { | ||
| val hello: String = "there" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| class Function1[-T1, +R] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,7 @@ module.exports = grammar({ | |
|
|
||
| _definition: $ => choice( | ||
| $.package_clause, | ||
| $.package_object, | ||
| $.class_definition, | ||
| $.import_declaration, | ||
| $.object_definition, | ||
|
|
@@ -54,11 +55,30 @@ module.exports = grammar({ | |
|
|
||
| package_clause: $ => seq( | ||
| 'package', | ||
| choice($.identifier, $.stable_identifier) | ||
| $.package_identifier, | ||
| // This is slightly more permissive than the EBNF in that it allows any | ||
| // kind of delcaration inside of the package blocks. As we're more | ||
| // concerned with the structure rather than the validity of the program | ||
| // we'll allow it. | ||
| optional($.template_body) | ||
| ), | ||
|
|
||
| package_identifier: $ => sep1( | ||
| '.', $.identifier | ||
| ), | ||
|
|
||
| package_object: $ => seq( | ||
| 'package', | ||
| 'object', | ||
| $._object_definition | ||
| ), | ||
|
|
||
| import_declaration: $ => seq( | ||
| 'import', | ||
| sep1(',', $._import_expression) | ||
| ), | ||
|
|
||
| _import_expression: $ => seq( | ||
| choice($.stable_identifier, $.identifier), | ||
| optional(seq( | ||
| '.', | ||
|
|
@@ -87,8 +107,13 @@ module.exports = grammar({ | |
| object_definition: $ => seq( | ||
| optional('case'), | ||
| 'object', | ||
| $._object_definition | ||
| ), | ||
|
|
||
| _object_definition: $ => seq( | ||
| $.identifier, | ||
| $.template_body | ||
| optional($.extends_clause), | ||
| optional($.template_body), | ||
| ), | ||
|
|
||
| class_definition: $ => seq( | ||
|
|
@@ -110,17 +135,51 @@ module.exports = grammar({ | |
| $.template_body | ||
| ), | ||
|
|
||
| // The EBNF makes a distinction between function type parameters and other | ||
| // type parameters as you can't specify variance on function type | ||
| // parameters. This isn't important to the structure of the AST so we don't | ||
| // make that distinction. | ||
| type_parameters: $ => seq( | ||
| '[', | ||
| commaSep1($._type_parameter), | ||
| commaSep1($._variant_type_parameter), | ||
| ']' | ||
| ), | ||
|
|
||
| _type_parameter: $ => choice( | ||
| '_', | ||
| $.identifier | ||
| _variant_type_parameter: $ => seq( | ||
| choice( | ||
| $.covariant_type_parameter, | ||
| $.contravariant_type_parameter, | ||
| $._type_parameter // invariant type parameter | ||
| ) | ||
| ), | ||
|
|
||
| covariant_type_parameter: $ => seq( | ||
| '+', | ||
| $._type_parameter | ||
| ), | ||
|
|
||
| contravariant_type_parameter: $ => seq( | ||
| '-', | ||
| $._type_parameter, | ||
| ), | ||
|
|
||
| _type_parameter: $ => seq( | ||
| choice($.wildcard, $.identifier), | ||
| optional($.type_parameters), | ||
| optional($.upper_bound), | ||
| optional($.lower_bound), | ||
| optional(repeat($.view_bound)), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| optional(repeat($.context_bound)), | ||
| ), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that I'm seeing how much structure there is to type parameters, I think we should tweak their structure so that there is always a visible syntax node corresponding to each parameter (as opposed to the Maybe something like this: Does that make sense? We could have a hidden helper rule called
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maxbrunsfeld Definitely. I'll create a separate issue for this so we don't forget :) |
||
|
|
||
| upper_bound: $ => seq('<:', $._type), | ||
|
|
||
| lower_bound: $ => seq('>:', $._type), | ||
|
|
||
| view_bound: $ => seq('<%', $._type), | ||
|
|
||
| context_bound: $ => seq(':', $._type), | ||
|
|
||
| template_body: $ => seq( | ||
| '{', | ||
| repeat($._definition), | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious about the possibility of a
type_parametersnode within a type parameter. What does it mean when a type parameter has its own parameters? I think we should add a test for this case as well.