Parsing for Parameter Nullchecking#35826
Parsing for Parameter Nullchecking#35826fayrose merged 52 commits intodotnet:features/param-nullcheckingfrom
Conversation
This reverts commit 8a94ac7.
|
In commit b567a0d you made a large number of white space changes that appear to be unintended. Would you be able to revert that commit? |
This reverts commit 5c7612b.
|
Do we have a tracking bug to update the "add null check" IDE feature to use this if the language version is high enough? We should also have a feature that looks for null-param checking code and offers to convert to this form. |
…into param-nullchecking
src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs
Outdated
Show resolved
Hide resolved
| public void TestAnonymousDelegateNullChecking() | ||
| { | ||
| UsingTree(@" | ||
| delegate void Del(int x!); |
There was a problem hiding this comment.
this should likely be an error right? you shouldnt' be allowed to place these on delegate-decls or interface/abstract methods right?
There was a problem hiding this comment.
Note: if these are not allowed, i would put the check for this not in hte parser.
There was a problem hiding this comment.
Will create interface/abstract tests and take a look at delegates
There was a problem hiding this comment.
Note: just to make sure we're on hte same page, even if this is not allowed by the language, the checks should not be in the parser. That will make parsing of these guys even more context sensitive, which adds complexity and makes incremental parsing harder/more-dangerous. So we should allow parsing of these, but then give a nice error later on (i.e. when making the actual parameter symbols) if these are not allowed for teh current sort of construct.
Another case: extern methods.
There was a problem hiding this comment.
if you are already writing tests for abstract methods and interface methods then please go ahead, but I would approve the PR without them as I know you'll get to them when you do the semantic side of this feature.
When PRing to feature branches please feel free to handle suggestions for additions with // PROTOTYPE comments, as long as the implementation is correct for the scenarios you've tested so far.
RikkiGibson
left a comment
There was a problem hiding this comment.
Looks good. All I see remaining is:
- Mark PROTOTYPE or fix diagnostics produced in
TestNullCheckedSingleParamNoSpaces - Mark PROTOTYPE the places where TryEatToken could be used, to update after master gets merged into the feature branch
| /// <summary> | ||
| /// Looks up a localized string similar to The attribute [EnumeratorCancellation] cannot be used on multiple parameters. | ||
| /// </summary> | ||
| internal static string ERR_MultipleEnumeratorCancellationAttributes { |
There was a problem hiding this comment.
Feels odd that this diff is in here. Maybe merging in latest master and rebuilding will clean it up.
src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs
Outdated
Show resolved
Hide resolved
| else | ||
| { | ||
| var name = this.ParseIdentifierToken(); | ||
| var exclamation = this.CurrentToken.Kind == SyntaxKind.ExclamationToken ? this.EatToken(SyntaxKind.ExclamationToken) : null; |
There was a problem hiding this comment.
Perhaps a prototype comment for this and similar checks which can be resolved after you merge master into the feature branch.
|
Might be good to squash when you merge due to the number of commits. |
|
Overall, things look good. But i would attempt to unify the pattern you use for handling incorrect tokens. Note: i do not mean you need to extract a common method to handle them, simply that the codepaths should look and feel similar, since they're effectively doing the same thing. |
|
LGTM (commit 48). The comment I left about leading trivia can be addressed via prototype for now if you determine I was correct. |
| [Fact] | ||
| public void TestOptParamMethodDeclarationWithNullValidationNoSpaces() | ||
| { | ||
| UsingStatement(@"void M(string name!=null) { }", expectedErrors: new DiagnosticDescription[] |
There was a problem hiding this comment.
!= [](start = 47, length = 2)
We should also add more tests around trivia before/after this node so we make sure that we're preserving. Can be added in a follow up PR to not hold this initial one up.
| arrow = AddTrailingSkippedSyntax(arrow, gt); | ||
| AddLeadingSkippedSyntax(arrow, notEq.GetLeadingTrivia()); | ||
| exclamation = AddLeadingSkippedSyntax(arrow, SyntaxFactory.MissingToken(SyntaxKind.ExclamationToken)); | ||
| exclamation = SyntaxFactory.MissingToken(SyntaxKind.ExclamationToken); |
There was a problem hiding this comment.
👍 Hopefully, all the construction/shuffling of the raw information is clear here for you :) I try to keep a mental model of all the nodes and what's going on with them, which helps make certain things stand out as looking "wrong". i.e. we had the 'arrow' nodes appearing in two places. on the 'arrow' local itself, but also as leading skipped syntax for the exclamation. This violated the strict invariants of the tree.
Thanks!
| N(SyntaxKind.Parameter); | ||
| { | ||
| N(SyntaxKind.IdentifierToken, "x"); | ||
| N(SyntaxKind.ExclamationToken); |
There was a problem hiding this comment.
do our parsing tests actually validate that tree invariants are preserved? we should do that so that we catch cases where we are either missing data in the tree, or we have duplicated data.
Note: such a change can come in a later PR.
However, it is very important as literally every layer above is written with the assumption that the compiler is absolutely guaranteeing these tree invariants. So we have to be careful to abide by them, otherwise the whole system above will fall over :)
There was a problem hiding this comment.
I believe there is a string equality assert that ensures the tree is correct (bc I kept running into that failing for a bit), but not 100% sure what you're referring to.
There was a problem hiding this comment.
That's likely what i'm referring to. Note: if that assert fails, we def should never be checking in (to master). To me, that specific assert is a hard blocker as it means we're not abiding by a core invariant that everything else needs in order to function properly.
Thanks!
There was a problem hiding this comment.
To be clear: merging into feature branch: totally ok. Merging into master with it possible to hit that assert (either inside our outside of tests): Def not ok. Thanks! :)
There was a problem hiding this comment.
Yeah all tests would fail if that assert is hit; currently all passing :)
There was a problem hiding this comment.
Or at least the no-space test would fail.
Contains parsing for general case, lambda case and lambda case with multiple parameters, as well as initial test cases.
Relates to #36024 (test plan)