-
Notifications
You must be signed in to change notification settings - Fork 830
Parser: Update OBLOCKSEP token passing #18921
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
Conversation
|
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.
There are many incorrect nodes in the test tree dumps. @edgarfgp Could you please fix the implementation, so the tests produce correct data?
tests/service/data/SyntaxTree/Expression/Record - Anon 12.fs.bsl
Outdated
Show resolved
Hide resolved
tests/service/data/SyntaxTree/Expression/Record - Anon 06.fs.bsl
Outdated
Show resolved
Hide resolved
6eea60c to
9f9c0ec
Compare
a2f929b to
fcc7b41
Compare
auduchinok
left a comment
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.
This is really good now. It's now possible to rely on the separator info when processing the tree, and all the cases with fake tree nodes are cleared up. Thanks @edgarfgp!
d19dc1c to
8315a15
Compare
| "let r = {AAA = 5}" | ||
| "let b = {r with }" | ||
| ] | ||
| AssertCtrlSpaceCompleteContains code "{r " [] ["AAA"] |
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.
Humm. This will enabled completion before the with keyword. To fix this we can do some range calculations in ServiceParseTreeWalk.fs and update the completion context for records or capture the with range in the tree and then use it.
8315a15 to
7a291f2
Compare
src/Compiler/pars.fsy
Outdated
| (Some($1, BlockSeparator.Offside(rhs parseState 2, None)), l) } | ||
| (Some($1, $5), l) } |
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.
This change looks suspicious. Previously we would capture the with range and store it as a separator. That didn't look correct because of how the separator field was reused for a different thing, but it could be the place where the code completion relied on. We can add a new field to the trivia and store the with range there.
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.
This is where we've started assuming that with was an offside separator: https://github.com/dotnet/fsharp/pull/18899/files#diff-e4c6a418b5f63918e99d3b27f209771a966fb6c7dbadf25cf5d3bb4b7b7d7bd7L5746 and then in this PR we've stopped keeping all non-semi and non-comma ones. A simpler possible fix is to rollback the copyInfo changes in the records and keep a with range there to use it from the code completion.
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.
Why is this comment marked as resolved? We still capture a different thing here, compared to pre-#18899, don't we?
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.
Yes, everything that was BlockSeparator.Offside now should be None.
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.
But isn't it exactly the thing that the code completion relied on?
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.
It clearly wasn't a separator in the new terminology but it was named that way before this terminology was introduced in the tree. It captured the with keyword range and other places could use it, so it was a different kind of separator between the expression and the field updates, and that's where the name came from.
It just was a mistake to start storing with range as if it was a semicolon/comma in the recent PRs, which happened because of the unfortunate naming clash.
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.
So your point is that we should not capture this as separator at all in this case ?
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.
My point is it seems it was captured for a reason before and now it's lost. Even though it was also called a separator, it served a different purpose: it wasn't an offside separator, but the range of with keyword (that now we can store in the record expression trivia), and it seems it's exactly what the code completion could rely on.
| let notHasRecordField (fieldName:string) (symbolUses: FSharpSymbolUse list) = | ||
| symbolUses | ||
| |> List.exists (fun symbolUse -> | ||
| match symbolUse.Symbol with | ||
| | :? FSharpField as field -> field.DisplayName = fieldName | ||
| | _ -> false | ||
| ) | ||
| |> fun exists -> Assert.False(exists, $"Field {fieldName} should not be found.") |
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.
Please use hasRecordField and not.
| let rangeOfBlockSeparator (id: Ident) = | ||
| let idEnd = id.idRange.End | ||
| let blockSeparatorStartCol = idEnd.Column | ||
| let blockSeparatorEndCol = blockSeparatorStartCol + 4 |
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.
Where does 4 magic constant come from? If we assume that a separator is ; or , then it can't be 4 characters long.
If this is a with keyword range, it should not be calculated from the id, it's job of the parser to preserve it correctly, like it was before.
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.
This was how it was originally. See https://github.com/dotnet/fsharp/pull/18899/files#diff-1e790bba80026c421a964cb1d8be0297aff37a0a3dbe7cbf954b54f6e3544e40L93-L100. But I think in this case we do not have a separator we can use range0 ?
7a291f2 to
aa7bd57
Compare
acefecd to
ffdaa6e
Compare
src/Compiler/pars.fsy
Outdated
| { let l = List.rev $4 | ||
| let l = rebindRanges $3 l $5 | ||
| (Some($1, $5), l) } | ||
| (Some($1, None), l) } |
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.
The captured info is still different here.
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.
No. this should be None as previously was BlockSeparator.Offside
| copyInfo: (SynExpr * BlockSeparator) option * | ||
| copyInfo: (SynExpr * BlockSeparator option) option * |
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.
This place still looks very wrong. We've stored the with keyword range before #18899 here, and now we store an optional semicolon or comma. Why do we expect a ;/, separator instead of the with in the tree? Where do we expect them to come from? Do we allow some new syntax? Or is it just dead code now? Why don't we update all the service code accordingly and try to process semicolons in places where they can never be at all where previously we processed with keywords?
|
This PR seems to add lots of new logic on top of mistakes made in #18899, most importantly treating The previous implementation would call @edgarfgp @T-Gro I propose we revert #18899, so this work could be started from scratch with better understanding of what the original code did instead of covering the mistakes with more new code. I believe that would allow us to have less diff as well. We can also use If not reverting, let's make a fresh branch starting from pre-#18899 and modeling the tree with the minimal diff, clearly stating what we consider a separator and updating the service code accordingly, and only then process with subsequent changes. |
|
@auduchinok Yeah let’s revert the previous PR and leave things as were before. Feel free to raise a new PR with your suggested changes. |
Description
Continuation of #18899
Checklist