Problem
-------
Compound type with refinement (structural type with a parent)
doesn't parse.
Solution
--------
This adds support for it.
It collides with context bounds `A: B: C`, so the precedence is set to
-1.
Problem
-------
Self-types are not parsed in braceless trait definitions:
```scala
trait A:
this: B =>
````
Solution
-------
Move existing `$.self_type` rule in trait definition into indented scope.
Rebalance `$.self_type` precedence.
Without explicit precedence it looses to `$.call_expression` in
```scala
trait A {
self: B =>
def f = ""
}
```
With static precedence instead of dynamic it leads to errors in
definitions like:
```scala
class A
x: Int // this should be $.ascription_expression
enum B:
case C
```
Problem
-------
`val` definitions with multiple identifiers are not supported.
Solution
--------
This implements `identifiers`, which acts like a pattern.
Problem
-------
Annotations on Scala 3 enums and their cases are not supported, e.g.
```scala
@A enum E:
@A("") @B case A
```
Solution
-------
Allow annotations in enum definitions
Problem
-------
Nested block comments are not parsed, e.g.
```
/* /* */ */
```
Solution
-------
Leave $.comment for single-line comments.
Introduce $.block_comment for block-comments.
Make $.block_comment out of several tokens to be able to detect nested
block comments
Problem
-------
By-name parameters in class definitions were not supported:
```
class A(a: => B)
```
Solution
-------
Support by-name parameters by changing the rule describing class
parameter type from `$._type` to `$._param_type`
Problem
-------
The grammar assumes upper type bound to go before lower type bound.
Although, in Scala it's the opposite:
```
TypeBounds ::= [‘>:’ Type] [‘<:’ Type]
```
Solution
-------
Swap type bounds' order in the grammar
Problem
-------
Catch-clause is not parsed when case is on the same line as 'catch':
```
try a catch b: C => d
```
Solution
-------
Intoduce `$._expr_case_clause` alternative to the catch-clause
Problem
-------
Scala 3 introduced using clauses to function call expressions:
```scala
f(using A)
```
The grammar did not allow that
Solution
-------
Add `choice` between regular and using-clause argument lists in
`$.arguments`
Problem
-------
Addition of optional `$.derives_clause` to the `$.class_definition` blowed its
states from ~500 to ~700 and doubled maximum memory usage during
generation. I've noticed, that the same addition of `$.derives_clause` to
the `$.object_definition` did not result in an increase of states. The
reason for this seems to be hidden in a separate rule
`$._object_definition`, that matches everything after the 'object' keyword
Solution
-------
Introduce `$._class_definition`, that matches everything after the
'class' keyword. This restrains the state machine blow when adding
support for `$.derives_clause`
Problem
-------
Derives clause is only defined for enums, but not for classes and
objects
Solution
-------
Include optional `$.derives_clause` in class and object definitions
Problem
-------
Guards in case clauses are thought to be lambda expressions sometimes,
e.g. in
```scala
{case a if b => c}
```
This happens, because `$.lambda_expression` has a higher parsing
precedence than `$._simple_expression`
Solution
-------
Avoid using numeric parsing precedence for `$.lambda_expression`.
Resolve specific conflicts instead
Problem
-------
`$.parameters` required each param to have a name, so `using` clauses like
`def x(using X =:= X)` failed to parse
Solution
-------
Introduce `$._using_parameters_clause`, which allows anonymous parameters
Problem
-------
Currently pattern match with guard doesn't parse.
Solution
--------
This implements it by creating an intermediate node called `_case_pattern` with right associativity.
_The problem_
Currently when you come across string interpolation you don't get any
special highlighting for the actual interpolator meaning:
```scala
ivy"com.lihaoyi::os-lib:0.9.0"
```
I all colored the same.
_The Solution_
The pr makes 2 changes.
- The `identifier` we use for the interpolator now becomes a field for
no reason other than I thought it'd be nice to just give it a name
- A hightlight query that captures it and assigns it to `function.call`.
Problem
-------
1. class constructor should accept annotation, but it doesn't.
2. Apparently Scala 3 does allow zero, one, or multiple parameter list
to an annotation, and differentiated between the class parameter by
its lack of type ascription.
Solution
--------
1. Add optional annotation for constructor. At this point, we can at
least parse the code with annotation on the ctor.
2. Unfortunatley, however, tree-sitter doesn't make enough lookahead to
distinguish postfix expr or ascription expression `(x: Int)`,
for now the class parameters will end up being parsed as arguments to
the annotation.
Problem
-------
1. In Scala 3, extends clause can be comma separated.
2. In Scala 2 or 3 extends clause can ctor with parameters:
`class D with E(x) with F(y)`.
Solution
--------
`extends` is now followed by *constructor applications* separated by
either `with` or `,` as opposed to treating them as a compound type.
Problem
-------
1. Currently `//` ends up matching `operator_identier`
2. There's also a bug in regex.
Solution
--------
1. Implement a workaround to avoid `//`.
2. Escape `-`, copying from the identifier regex.
Fixes https://github.com/tree-sitter/tree-sitter-scala/issues/127
Problem
-------
Currently our grammar does not support the fewer braces syntax,
which basically lets us pass the last argument as a block after `:`.
Solution
--------
This implements fewer braces support for call_expression,
infix_expression, with and without the lambda start.
Problem
-------
Current grammar accepts expression immeidately after `new`,
which is not correct, and doesn't work for Scala 3 syntax.
Solution
--------
This fixes it by actually using `$.template_body`.
It does create a tricky conflict between `new A: <block>`
construct and `new A: <type>`.
To deal with that, we are using `prec.dynamic`.
Problem
-------
When Neovim encounters an unknown node type in the highlight query it
not only not highlight, but it displays confusing error message to the
buffer.
Solution
--------
For now, we should create a dummy node.
Problem
-------
stable_identifier ends up matching to things like `a.*`
so it can't be used for the import path since we want
`*` to be parsed as `import_wildcard`
Solution
--------
Make our own import path using a chain of `identifier`.
Problem
-------
The `identifier` token is hacked together, so we never quite get the
parsing right.
Solution
--------
My friend Ethan Atkins at some point experimented with generating
tree-sitter grammar out of EBNF (https://github.com/eatkins/tree-sitter-ebnf-generator/tree/master/examples/scala)
and his identifier, as far as I know is spec-correct.
We simplified the regex a bit to fit into the tree-sitter's unsigned
short int count, but it should be comparable.
Problem
-------
Currently operator-like identifiers are not part of the simple
expression, so you can't call `::(123)`.
Solution
--------
This includes `$.operator_identifier` into `_simple_expression`,
and further improves the expression hierarchy.
Note that this removes test on double-prefix-expression.
It's not allowed in Scala spec to have double-prefix.
Problem
-------
Current grammar doesn't handle a common givens pattern:
```
given Context = ctx
```
Solution
--------
This fixes it by denoting name etc optional.
Problem
-------
Currently we use `$.expression` everywhere even though it often
requires much narrower set of expressions.
Solution
--------
Now that we've gained some memory budget, this adds
`_simple_expression`, mirroring the EBNF, and adjusts
`infix_expression` etc to use narrower choice of expression tokens.
With this change, the smoke test for Scala 2 library jumps to 95%.
Problem
-------
Memory usage already regressed a bit to 15GB.
```
$ /usr/bin/time -f "%P %M" node_modules/.bin/tree-sitter generate
99% 15625000
```
Running
```
$ node_modules/.bin/tree-sitter generate --report-states-for-rule compilation_unit
given_definition 4434
type_definition 2538
function_definition 2322
```
show that `given_definition` might be the culprit.
Solution
--------
Apply the same `class_constructor` trick to `given_definition`, enum,
`function_definition`, `function_declaration`, bringing down the memory
usage down to one (1) GB.
```
$ /usr/bin/time -f "%P %M" node_modules/.bin/tree-sitter generate
99% 1078896
```
Problem
-------
Currently codegen uses 34GB, which is more than my desktop can handle.
ahlinc kindly let us know about `--report-states-for-rule` flag to try
the identify some choke points.
To my surprise `class_definition` uses 3728 states.
Solution
--------
This adds intermediate node called `_class_constructor`, which is right
associated to deal with the modifiers, but now `class_definition` can
be left associated.
After this change:
```
$ /usr/bin/time -f "%M" node_modules/.bin/tree-sitter generate
11723152
```
This brings down memory usage to 11GB.
Problem
-------
Given something like
class A:
def a() =
()
def a() = 1
the scanner only outdents once, so it fails to parse the above.
Solution
--------
Track `last_indentation_size` in the payload to indicate last
outdent (default: -1). If it's not -1 that means there was an outdent.
This then checks if the last_indentation_size qualified for another
outdent.
Problem
-------
Currently Scala 3 optional braces syntax does not work.
Specifically, in this PR I want to address decls/defns not
properly grouped under the right owner in part 1.
Solution
--------
1. This brings in indent/outdent impl by keynmol
2. Introduce `_indentable_expression`.
This allows us to limit where indent/outdent shows up without
confusing tree-sitter too much. To start, val/def/var defn
and if-expressions are given indentable expression.
Problem
-------
Currently Scala 3 optional braces syntax does not work.
Solution
--------
This implements initial attempt on dealing with colon
instead of braces.
Note that this does not implement any indent/outdent tracking
so the second `val` onwards will not be added in `template_body`
but it should improve the highlighting a bit.
Fix call expression to allow block as arguments (#21)
Update for comprehension to handle patterns
Fix for comprehension to detect assignment as an enumerator
Add access modifiers
Update trait, object and class parameter to support modifiers
Update scanner to support `with` on a new line
Update function definition/declaration to support operator naming
Update field expression to support operators as methods
Co-authored-by: Stevan Milic <stevan.milic@tradecore.com>
* Fix typo
* Rework literals part of grammar
Introduce hierarchy of literals as it is done in Scala language grammar.
Move existing literal types into hierarcy under `literal` parent.
Add and extend literals for integer and floating point numbers.
Add test cases for integer and floating point numbers in corpus.
Adjust existing test cases to changes.
Also fixes#24
* Apply review comments
Hide `literal` node from appearing in s-expressions and increasing
amount of states.
Update test cases according to grammar change.
* Add automatic changes
Add tree-sitter dependency update by npm.
Add atomatic changes in parser and grammar from building the parser.
* This adds in support for boolean, character, and symbol literals.
Previously we would just handle boolean literals and character literals
as identifiers, and wouldn't handle symbol literals.
* Fix CI
* Add supertypes
* Support multi-line case clauses
* Allow definitions in case clauses, expressions in class/object bodies
* Add annotations, infix patterns, implicit parameters
* Add tree-sitter CLI declaration to package.json
* Add annotations on type parameters
* Add type annotations, type projections; fix compound types
* Fix operator_identifier regexp
* Add tuple types and repeated parameter types
* Give infix_pattern higher precedence than capture_pattern
* Make infix_type nestable
* Allow body-less trait_definition
* Allow omitting parens when function_type's input is a single type
* Put all alternatives function_type's parameters under parameter_types
* Give alternative_pattern lower precedence than typed_pattern
* Remove parenthesized_pattern
* Allow empty body in case_clause
* Regenerate parser