Skip to content

Naming style for locals#26336

Merged
sharwell merged 24 commits intodotnet:masterfrom
Neme12:localNamingStyle
May 9, 2018
Merged

Naming style for locals#26336
sharwell merged 24 commits intodotnet:masterfrom
Neme12:localNamingStyle

Conversation

@Neme12
Copy link
Copy Markdown
Contributor

@Neme12 Neme12 commented Apr 23, 2018

fixes #22440 (comment) / half of #18121
This PR is separate from #26165 and only contains added support for local variables.

image

@Neme12 Neme12 requested a review from a team as a code owner April 23, 2018 15:24
@CyrusNajmabadi
Copy link
Copy Markdown
Contributor

@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!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait... do we seriously have no VB tests for thsi feature? @dpoeschl ??

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Apr 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there were no tests... I added them in a different file (and project), but only for locals & parameters

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added in 3416dc9

@Neme12 Neme12 force-pushed the localNamingStyle branch from 2d0d78c to 18659c7 Compare April 23, 2018 22:01
@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented Apr 23, 2018

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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this not be shared with teh C# side?

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Apr 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from the language name, it could be. Where can I put the shared code?

Copy link
Copy Markdown
Contributor

@CyrusNajmabadi CyrusNajmabadi Apr 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probaly ServicesTestUtilities/Diagnostics... or thereabouts...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 543e6f7

{
var diagnostic = TryGetDiagnostic(
syntaxContext.Compilation,
syntaxContext.SemanticModel.GetDeclaredSymbol(syntaxContext.Node, syntaxContext.CancellationToken),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this feels strange. one of the kinds you register is SyntaxKind.ForEachStatement... but GetDeclaredSymbol does'nt work on a ForEachStatement does it??

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes it does

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Apr 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you.

return null;
}

var optionSet = await options.GetDocumentOptionSetAsync(location.SourceTree, cancellationToken).ConfigureAwait(false);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm a littler nervous about this. can we check that we have a source tree first?

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Apr 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure (even though I can't think of a scenario where this would occur, so I can't add a test)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 926a468

Inherits NamingStyleDiagnosticAnalyzerBase(Of SyntaxKind)

Private Shared _supportedSyntaxKinds As ImmutableArray(Of SyntaxKind) =
ImmutableArray.Create(SyntaxKind.ModifiedIdentifier)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static should be s_

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Apr 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually this should just be a readonly auto-property - I forgot VB had them as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved in 926a468

@jcouv jcouv added Area-IDE Community The pull request was submitted by a contributor who is not a Microsoft employee. labels Apr 23, 2018
@jcouv jcouv added this to the 15.8 milestone Apr 23, 2018
SymbolKind.Property,
SymbolKind.Parameter);

// HACK: RegisterSymbolAction doesn't work with locals & local functions
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 This isn't a hack. It's a normal use of a stable, public API.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 559efdf

ImmutableArray.Create(
SyntaxKind.VariableDeclarator,
SyntaxKind.ForEachStatement,
SyntaxKind.SingleVariableDesignation);
Copy link
Copy Markdown
Contributor

@sharwell sharwell Apr 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Apr 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Apr 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

catch clause added in 09d2e08

{
void M()
{
const int local1 = 0, LOCAL2 = 0;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Where are local constants handled?

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Apr 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Apr 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is handled here:

if (Modifier.IsConst)
{
if ((kind == SymbolKind.Field && ((IFieldSymbol)symbol).IsConst) ||
(kind == SymbolKind.Local && ((ILocalSymbol)symbol).IsConst))
{
return true;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Apr 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a new test exercising both constant and non-constant locals in the same test?

tests added in 3f32ac5

Copy link
Copy Markdown
Contributor

@sharwell sharwell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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,
Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 Apr 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was now redundant because fields are handled by syntax as well. They have the same syntactic form as locals (both use VariableDeclaratorSyntax)

@CyrusNajmabadi
Copy link
Copy Markdown
Contributor

I will review this tonight. If i don't, feel free to ping me.

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented May 4, 2018

@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?

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented May 4, 2018

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.

@Neme12
Copy link
Copy Markdown
Contributor Author

Neme12 commented May 4, 2018

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

Copy link
Copy Markdown
Contributor

@sharwell sharwell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good aside from the performance sensitive method and ensuring #20907 reaches a design conclusion (not necessarily implementation) before shipping more changes.


// Local functions

async Task<NamingStylePreferences> GetNamingStylePreferencesAsync()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❗️ Make this a method to preserve the PerformanceSensitive attribute

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 May 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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?

Copy link
Copy Markdown
Contributor

@sharwell sharwell May 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Copy link
Copy Markdown
Contributor Author

@Neme12 Neme12 May 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, that makes sense. I didn't think of that. Thanks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in df39892

@sharwell
Copy link
Copy Markdown
Contributor

sharwell commented May 4, 2018

@Neme12 We should reach a conclusion on the related design issue #20907 Monday 7 April which would allow this to proceed.

@sharwell sharwell self-assigned this May 7, 2018
@sharwell
Copy link
Copy Markdown
Contributor

sharwell commented May 9, 2018

@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.

@jinujoseph
Copy link
Copy Markdown
Contributor

Approved to merged for 15.8.preview2

@sharwell sharwell merged commit dfe02b6 into dotnet:master May 9, 2018
@Neme12 Neme12 deleted the localNamingStyle branch May 9, 2018 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Approved to merge Area-IDE Community The pull request was submitted by a contributor who is not a Microsoft employee.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Naming codestyles should handle local functions

5 participants