Conversation
|
@dpoeschl for insight here. David, i remember you trying to do something to get namign styles working for these cases. But htat work was either shelved or abandoned. Can you recall what the issues were there? Just so we can make sure the same issues dont' apply here. Thanks! |
There was a problem hiding this comment.
wait... do we seriously have no VB tests for thsi feature? @dpoeschl ??
There was a problem hiding this comment.
there were no tests... I added them in a different file (and project), but only for locals & parameters
There was a problem hiding this comment.
I know your PR should have no problems here, but can we have some tests that these new local-variable features do not affect members inside tuples. Thanks!
… fake SymbolAnalysisContext
2d0d78c to
18659c7
Compare
|
I did some rebasing magic and then did a force push to remove the dependency on the other PR that added local functions. This PR is now completely independent and can be reviewed and merged independently. |
| Imports Microsoft.CodeAnalysis.Options | ||
| Imports Microsoft.CodeAnalysis.Simplification | ||
|
|
||
| Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.NamingStyles |
There was a problem hiding this comment.
can this not be shared with teh C# side?
There was a problem hiding this comment.
Apart from the language name, it could be. Where can I put the shared code?
There was a problem hiding this comment.
Probaly ServicesTestUtilities/Diagnostics... or thereabouts...
| { | ||
| var diagnostic = TryGetDiagnostic( | ||
| syntaxContext.Compilation, | ||
| syntaxContext.SemanticModel.GetDeclaredSymbol(syntaxContext.Node, syntaxContext.CancellationToken), |
There was a problem hiding this comment.
this feels strange. one of the kinds you register is SyntaxKind.ForEachStatement... but GetDeclaredSymbol does'nt work on a ForEachStatement does it??
There was a problem hiding this comment.
it gives the symbol of the loop variable.. note that there isn't any other node you could get the loop variable from - it's not a VariableDeclaration/Declarator, it only has a single token for the variable name. So ForEachStatement is the right node you need to use.
There was a problem hiding this comment.
oh wow. that makes sense, and makes me so sad we ever allowed pieces of syntax with "identifier name" in them instead of having hte designator work figured out.
|
|
||
| return Diagnostic.Create(descriptor, symbol.Locations.First(), builder.ToImmutable()); | ||
|
|
||
| // Local functions |
| return null; | ||
| } | ||
|
|
||
| var optionSet = await options.GetDocumentOptionSetAsync(location.SourceTree, cancellationToken).ConfigureAwait(false); |
There was a problem hiding this comment.
i'm a littler nervous about this. can we check that we have a source tree first?
There was a problem hiding this comment.
sure (even though I can't think of a scenario where this would occur, so I can't add a test)
| Inherits NamingStyleDiagnosticAnalyzerBase(Of SyntaxKind) | ||
|
|
||
| Private Shared _supportedSyntaxKinds As ImmutableArray(Of SyntaxKind) = | ||
| ImmutableArray.Create(SyntaxKind.ModifiedIdentifier) |
There was a problem hiding this comment.
static should be s_
There was a problem hiding this comment.
actually this should just be a readonly auto-property - I forgot VB had them as well
| SymbolKind.Property, | ||
| SymbolKind.Parameter); | ||
|
|
||
| // HACK: RegisterSymbolAction doesn't work with locals & local functions |
There was a problem hiding this comment.
📝 This isn't a hack. It's a normal use of a stable, public API.
| ImmutableArray.Create( | ||
| SyntaxKind.VariableDeclarator, | ||
| SyntaxKind.ForEachStatement, | ||
| SyntaxKind.SingleVariableDesignation); |
There was a problem hiding this comment.
There was a problem hiding this comment.
context.RegisterSyntaxNodeAction(VariableDeclarationAction, SyntaxKind.VariableDeclaration);`This is handled SyntaxKind.VariableDeclarator.
context.RegisterSyntaxNodeAction(CatchDeclarationAction, SyntaxKind.CatchDeclaration);You're right, I'll fix this, thanks.
context.RegisterSyntaxNodeAction(QueryContinuationAction, SyntaxKind.QueryContinuation);
context.RegisterSyntaxNodeAction(FromClauseAction, SyntaxKind.FromClause);
context.RegisterSyntaxNodeAction(LetClauseAction, SyntaxKind.LetClause);
context.RegisterSyntaxNodeAction(JoinClauseAction, SyntaxKind.JoinClause);
context.RegisterSyntaxNodeAction(JoinIntoClauseAction, SyntaxKind.JoinIntoClause);These are not supported as explained in the tests. They're not actually represented as locals in the symbols. There should later be a design discussion about whether we should pretend that these are in fact locals and do some workarounds to treat IRangeVariableSymbols as ILocalSymbols, or whether we should add yet another option for these. I hope it's not a requirement to sort this out right now.
There was a problem hiding this comment.
I personally don't see a reason to have a separate naming style for range variables and don't think other people would need that either. But I've heard in the other PR that there has been some discussion about extending symbol specifications (to allow them to be used for custom classification I think?) and changing them to blur the distinction between 2 kinds of symbols might hinder that (and it's not a very nice solution). So I'm leaving this for the team to decide. Is it OK to keep those unsupported for now?
| { | ||
| void M() | ||
| { | ||
| const int local1 = 0, LOCAL2 = 0; |
There was a problem hiding this comment.
❓ Where are local constants handled?
There was a problem hiding this comment.
Sorry, I don't understand the question. Modifier checks are done by existing code on the actual symbols (not from syntax). I just added a test to confirm that it works for locals as well. So if you specify you want uppercase local constants, but normal locals camel case, that should work and that's the purpose of this test.
There was a problem hiding this comment.
It is handled here:
There was a problem hiding this comment.
@Neme12 Thanks, that's exactly the answer I was looking for.
💡 Can you add a new test exercising both constant and non-constant locals in the same test? It will show that we don't have an unintentional overlap in the cases.
There was a problem hiding this comment.
Can you add a new test exercising both constant and non-constant locals in the same test?
tests added in 3f32ac5
sharwell
left a comment
There was a problem hiding this comment.
Needs to add missing cases
| // Locals and fields are handled by SupportedSyntaxKinds for now. | ||
| private static readonly ImmutableArray<SymbolKind> _symbolKinds = ImmutableArray.Create( | ||
| SymbolKind.Event, | ||
| SymbolKind.Field, |
There was a problem hiding this comment.
This was now redundant because fields are handled by syntax as well. They have the same syntactic form as locals (both use VariableDeclaratorSyntax)
|
I will review this tonight. If i don't, feel free to ping me. |
|
@sharwell It looks like you changed GetNamingStylePreferencesAsync to use ValueTask and added a PerformanceSensitive attribute. In this PR, I actually deleted that file and made it into a local function so that it doesn't have to take 4 parameters (it has to work with SyntaxNodeAnalysisContext as well as SymbolAnalysisContext). I cannot add the attribute on a local function. Can you please give me advice what I should do here? I suppose I can just change it into a method and pass all those arguments? |
|
I ended up just moving the early return outside of GetNamingStylePreferencesAsync and inlining it directly, therefore GetNamingStylePreferencesAsync now always awaits and it should be OK to keep using Task. |
|
Why is this marked as "NeedWork"? Apart from the merge conflict, I've been waiting for a response. Please tell me what changes I need to do. Thanks |
|
|
||
| // Local functions | ||
|
|
||
| async Task<NamingStylePreferences> GetNamingStylePreferencesAsync() |
There was a problem hiding this comment.
❗️ Make this a method to preserve the PerformanceSensitive attribute
There was a problem hiding this comment.
@sharwell Why is this method still performance sensitive given that the reason for ValueTask was the early return which now happens before this method is called?
There was a problem hiding this comment.
@Neme12 The reason for ValueTask is the call to GetDocumentOptionSetAsync often returns synchronously. The early return was not the common case. Also, changes to the behavior documented in [PerformanceSensitive] requires re-running the scenario in the linked URI to gather before/after data proving that a regression on the indicated metrics did not occur.
There was a problem hiding this comment.
I see, that makes sense. I didn't think of that. Thanks.
|
@jinujoseph For approval to merge. This pull request does not implement the accessibility modification described in #20907, but I do not see any reason why that should block progress of this incremental improvement. |
|
Approved to merged for 15.8.preview2 |
fixes #22440 (comment) / half of #18121
This PR is separate from #26165 and only contains added support for local variables.