Repository navigation
Parse F# 6 index syntax xs[i] as an index_expression - #249
Open
pcshrosbree wants to merge 1 commit into
Open
pcshrosbree wants to merge 1 commit into
pcshrosbree wants to merge 1 commit into
Conversation
Fixes ionide#242. Since F# 6 a '[' touching the expression before it is an index (FSC's LexFilter turns it into HIGH_PRECEDENCE_BRACK_APP), while `f [i]` with a space applies f to a list. The grammar gave both the same application_expression with a list_expression argument. index_expression gains a second form: a touching '[' (token.immediate, with no lexical prec so the longer `[|` and `[]` tokens still win), with a body scoped like a list's so it may span lines. `f[]` stays an application to the empty list, through a touching-empty-list form that lives only in the application argument slot. This changes the expected trees of 12 existing tests that encoded `xs[i]` as an application; each new tree is an index_expression and error-free. No corpus file parses worse; two parse better.
Author
|
This PR is one of a set; #255 maps them all, with their dependencies and merge order. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #242.
Since F# 6,
xs[i]with the[touching the expression is an index. FSC'sLexFilterturns that[intoHIGH_PRECEDENCE_BRACK_APP, and its checker treats an adjacent list as an index.f [i]with a space appliesfto a list. The grammar gave both the sameapplication_expressionwith alist_expressionargument, while the olderxs.[i]got anindex_expression.This is a syntactic reading. FSC resolves an adjacent
[by type, which a parser cannot see. I ran these throughdotnet fsi:(xs)[1],f(10)[1]andxss[1][0]index.fs[0][7]with a function infs[0], and(f)[5], apply, with no diagnostic.f[1; 2]with a functionfapplies, with the informational FS3365 asking for a space.index_expressionis right for the common case and is what the issue asks for first. The issue's alternative, an application marked as adjacent, would avoid asserting an index where the receiver is a function. I can switch to it if you prefer.Change
index_expressiongains a second form: an expression followed by a touching[(token.immediate), then the index or slice, then]. Its body is scoped like a list's (_paren_indent…_dedent), so it may span lines, asys[+ an indentedlet+]does in an existing test.[has no lexical precedence. Tree-sitter ranks lexical precedence above match length, so any precedence would let it beat the longer[|and[]tokens:f[|1|](an application, as in FSC) would lex asf[+|1|], andnull : string[]would lose its array type. Against a list's[of the same length, the earlier-defined rule wins.f[]stays an application to the empty list. FCS parses it so, and there is nothing to index with. A touching[immediately followed by]is an emptylist_expression. That form lives only in_low_prec_app's argument slot: inlist_expressionitself it would also claim every([and[[at an expression start, and it did when I tried.Tests
New tests in
test/corpus/expr.txt:xs[1],g [1; 2],g xs[0](the index binds tighter than the application),xs[0][1],m["k"],(xs)[0];g[|1|],TreeNode[],[Seq[]; x]. This test passes onmaintoo.A third new test covers an under-indented index body (
xs[/1 +/2/]followed by a declaration). That pins the list-style scope: with a plain indent scope, the body breaks.Every input parses without diagnostics in FCS (
Fantomas.FCS7.0.5). FCS marks the first bracket in each case as an atomic application, but it leaves the outer one non-atomic in(xs)[0],f(x)[0]andxs[0][1]. The compiler still indexes there, as thefsiruns above show.Known limits
[.f (* c *)[0]becomes an index. The immediate token sees no whitespace once the comment extra is consumed.f[1; 2]. It becomes an index whose body is asequential_expression, where FSC (with FS3365) appliesfto a two-element list.xs[^1]remains an ERROR, as onmain.12 existing tests change their expected trees. Each recorded
xs[i]as an application ofxsto a list:dot expression((A[1]).B)index expression(test[test])index list expressionsandindex single list expressions([2; 3; 4][1])array list expressionsandarray single list expressions([|2; 3; 4|][1])call function from list of functions(fs[0] 0)index list with value declaration(a multi-line index body)match expression 3 rules(basePath[1])list index with slice ranges(xs[..1]and others)short for expression in computation expressionand itslet thenvariant (vars[key])In each, the application of a list becomes an
index_expression, and every new tree is error-free.Corpus
check:baseline: nothing parses worse.ProjectGeneration.fsgoes from 1 to 0 error nodes andE_productioncoverage03.fsfrom 10 to 6.check:invalid: all recorded errors are still found.parser.cgrows 4.0%.