EnC - Support top level statements#54102
Conversation
src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs
Outdated
Show resolved
Hide resolved
src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs
Outdated
Show resolved
Hide resolved
src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
Outdated
Show resolved
Hide resolved
src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
Outdated
Show resolved
Hide resolved
| CompilationUnit, | ||
|
|
||
| GlobalStatement, |
There was a problem hiding this comment.
I'm confused by this and the comment on the enum that says:
All descendants of a node whose kind is listed here will be ignored regardless of their labels.
Isn't everything a descendant of CompilationUnit, and GlobalStatement is even a direct child?
There was a problem hiding this comment.
Yes.. as is NamespaceDeclaration, ExternalAliasDirective and UsingDirective. I'm honestly not sure what that last assumption really means - whether nodes are descended into is controlled by the isLeaf output parameter on the GetLabel method, not by the enum directly. Perhaps it doesn't apply any more?
@tmat ?
There was a problem hiding this comment.
I don't remember. Probably stale comment.
|
|
||
| if (declaration is CompilationUnitSyntax unit && unit.ContainsTopLevelStatements()) | ||
| { | ||
| return TextSpan.FromBounds(unit.Members[0].SpanStart, unit.Members.OfType<GlobalStatementSyntax>().Last().Span.End); |
There was a problem hiding this comment.
Just noticed that local functions are parsed as "GlobalStatementSyntax" (I have no idea whether they should be included here or not).
There was a problem hiding this comment.
Not sure what you mean by this comment. Yes, any top level statement is contained within a GlobalStatementSyntax, including local functions. This bit of code is returning the span for the source of the top level statements, so includes local functions, just like the span for a regular method would include local functions.
src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueClosureTests.cs
Show resolved
Hide resolved
src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs
Show resolved
Hide resolved
src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs
Show resolved
Hide resolved
src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs
Outdated
Show resolved
Hide resolved
Thanks, that was my bad. Have updated the condition. |
|
Ping @dotnet/roslyn-compiler for reviews, as feedback has been addressed. |
src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs
Outdated
Show resolved
Hide resolved
src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
Show resolved
Hide resolved
Typo (although not part of this change). In reply to: 875805160 In reply to: 875805160 Refers to: src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs:2594 in 458e9fe. [](commit_id = 458e9fe, deletion_comment = False) |
src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
Show resolved
Hide resolved
src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
Outdated
Show resolved
Hide resolved
src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
Show resolved
Hide resolved
Do we need to allow for Refers to: src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs:1144 in 458e9fe. [](commit_id = 458e9fe, deletion_comment = False) |
|
|
Thanks for the thorough review @cston! |
|
|
||
| var generation0 = EmitBaseline.CreateInitialBaseline( | ||
| md0, | ||
| EmptyLocalsProvider); |
There was a problem hiding this comment.
I was confused about why GetEncMethodDebugInfo is needed in the new test in EditAndContinueClosureTests but not here. Is it because the method we're editing doesn't have any locals?
There was a problem hiding this comment.
Not to pretend I understand it and didn't just copy an existing test, but yes GetEncMethodDebugInfo reads the lambda map and locals map.
src/Compilers/CSharp/Test/Semantic/FlowAnalysis/RegionAnalysisTests.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
Outdated
Show resolved
Hide resolved
| if (node is CompilationUnitSyntax unit) | ||
| { | ||
| // When deleting something from a compilation unit we just report diagnostics for the last global statement | ||
| return unit.Members.OfType<GlobalStatementSyntax>().LastOrDefault()?.Span ?? default; |
There was a problem hiding this comment.
Should there be some kind of assertion here that a global statement is present (since this method is called GetGlobalStatementDiagnosticSpan)?
| // Expressions are ignored but they may contain nodes that should be matched by tree comparer. | ||
| // (e.g. lambdas, declaration expressions). Descending to these nodes is handled in EnumerateChildren. | ||
|
|
||
| case SyntaxKind.NamespaceDeclaration: |
There was a problem hiding this comment.
This will have to be updated when I merge this change into the features/FileScopedNamespaces branch. Just curious, what is the consequence of failing to update this? Is it in perf or correctness?
There was a problem hiding this comment.
There is a checklist for EnC for new language features that Tomas put together, I'll forward it to you.
In general, if a node isn't classified in these switch statements it means its invisible to EnC, so for example for file scoped namespaces we wouldn't report a rude edit if one was changed or added.
|
LGTM. I don't consider any of my comments blocking except maybe #54102 (comment). |
Fixes #44196
I tried to add a test for each type of thing I could of that might be important, but let me know if there is something I missed. This turned out to be generally straight forward, though it would have been lovely if there was a single
GlobalStatementBlocksyntax node under a compilation unit that had everything it except using statements :)