Added member classification API support for C##24100
Added member classification API support for C##24100mkrueger wants to merge 10 commits intodotnet:masterfrom mkrueger:master
Conversation
Pilchie
left a comment
There was a problem hiding this comment.
Will need to update PublicAPI.Unshipped.txt, tests, etc.
There was a problem hiding this comment.
Should we do local/parameter as well, since we're here?
There was a problem hiding this comment.
Should const/non-const/enum fields get their own classifications? I personally think so.
There was a problem hiding this comment.
Added locals, parameters, const, enum fields.
There was a problem hiding this comment.
paging @DustinCampbell . I think the primary concern we had here (and why we didn't do this earlier), is that we wanted flexibility to be able to classify things at a veyr fine grained level. For example someone could want a set of classifications for "private static method" vs "public instance method". I was prototyping being able to do this using the SymbolSpecification stuff @dpoeschl introduced for naming. However, the primary blocker was that it would need a revamp of fonts/colors in VS to support this, even if we did have it at the data layer.
There was a problem hiding this comment.
@CyrusNajmabadi for context, we wanted to add these to the API so that VS 4 Mac doesn't lose the support they already had, even if VS doesn't make use of it right away.
There was a problem hiding this comment.
Classification types are a hierarchy, so this shouldn't block future work to have more detailed classifications.
There was a problem hiding this comment.
I think the concern was more that this was part of our public API. So we wanted to get the public API shape right around classification. But i agree that such a desire should not block pretty simple stuff that could be done now. I just want Dustin involved so he's aware of what's going on and doesn't have any strong objections himself.
There was a problem hiding this comment.
Thanks @CyrusNajmabadi! Sorry for the delay (I've been OOF sick).
I'm generally OK with this. There are a lot of pivots we could consider here (read-only fields, different colors for different accessibility, etc., etc.), but I don't think that should block this. After all, we'd probably want to introduce more pivots for types as well and that's a similar concern.
There was a problem hiding this comment.
should we have different classification for method vs extension method? I personally think so.
There was a problem hiding this comment.
I like the idea to have extension methods in a different classification
|
Ah, for future recollection: one other issue i had with using SymbolSpecifications for this purpose was that we have customers that want classification that would not even fall under that bucket. For example, being able to classify individual keywords differently. While this sounds like it could be strange, the use cases actually made sense. For example, there were some customers that wanted to classify flow-control keywords differently, to help draw attention to them. Right now, such a concept is not expressible with SymbolSpecification (though it could be augmented to support this in the future). |
|
In older versions of our syntax definition we had different colors for different keywords - at least there was the possibility to do so. I removed that feature because no one really used it and made the color styles too colorful - but in any case that's not something that is implemented in the name classification. |
DustinCampbell
left a comment
There was a problem hiding this comment.
There are a few changes I'd like to request:
-
As written, this change will only classify member references. However, to match what we do with type declarations, another change needs to happen to classify member declarations. This is done in the syntactic classifier here: https://github.com/dotnet/roslyn/blob/master/src/Workspaces/CSharp/Portable/Classification/ClassificationHelpers.cs#L106-L146.
-
Tests!
-
Consider making the change for VB as well.
|
Should be a discussion starting point for what we minimally need. ATM I've issues to build roslyn on my system will take me a while to set up the environment for it. But ty for the GetClassificationForIdentifier - I'll look what I can do :). |
Added classification for c# methods, events, fields and properties.
|
@mkrueger can you fix up commits so that it only shows your change? |
|
Tests still missing - I can't compile roslyn on my machine so this is still only a discussion PR. If anyone could help me:
and
I Installed vs.net 2017 enterprise and checked everything in the visual studio installer. 4.6.1 facade assemblies are installed in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6.1 My dotnet info is:
Without compiling + testing it's not possible to verify the correctness. However we made some good discussion points. I added enum/constants and extension methods. |
| return false; | ||
| } | ||
|
|
||
| static string GetClassificationForField(IFieldSymbol fieldSymbol) |
There was a problem hiding this comment.
Please use explicit accessibility modifier here.
Added some helper functions for testing the new classification names as well.
The usage test is failing - needs investigation.
|
Classification tests should work. The extension method usage test fails for an unknown reason. However it's difficult for me to debug that test - vs.net runs for a very long time not hitting the breakpoint there :/. All other classifications I added are already covered by various unit tests. There are some other tests failing - but it looks like it's caused by my system language so I don't know if that is connected to my changes in any way. Would be nice if someone could help us out in there. |
| { | ||
| private UserTypesFieldsFormatDefinition() | ||
| { | ||
| this.DisplayName = EditorFeaturesResources.User_Types_Fields; |
There was a problem hiding this comment.
This should probably be User_Members_Fields as Fields are not Types.
There was a problem hiding this comment.
Hrmm.. although, then these would be sorted separately in teh fonts/colors dialog. So probably best to leave like this.
There was a problem hiding this comment.
Y that's what I thought - User_Types is a bit unfortunate but fits 80 - however type in that case is no type in a programming language just a user defined type of things to classify.
| @@ -1,5 +1,6 @@ | |||
| // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | |||
|
|
|||
| using System.Linq; | |||
There was a problem hiding this comment.
classification is super perf sensitive and is called a bunch. We've avoided linq here because of that.
| { | ||
| // TODO: Add proper extension method check - I'm sure there is some syntax based check somewhere burried in roslyn but I couldn't find it. | ||
| bool isExtensionMethod = | ||
| (methodDeclaration.Parent as TypeDeclarationSyntax)?.Modifiers.Any(m => m.IsKind(SyntaxKind.StaticKeyword)) == true && |
There was a problem hiding this comment.
SyntaxTokenList already has a .Any overload that just takes a SyntaxKind. So no need to use the lambda version.
There was a problem hiding this comment.
All you have to do is check the modifiers of the first parameter. That's sufficient. "this" is only legal on extension methods, so it's fine to assume that if you see 'this' on the first parameter, then ti's an extension method.
There was a problem hiding this comment.
Is there any way checking that ? there must be something to check that but I didn't find it.
| switch (varDecl.Parent) | ||
| { | ||
| case FieldDeclarationSyntax fieldDeclaration: | ||
| return fieldDeclaration.Modifiers.Any(m => m.IsKind(SyntaxKind.ConstKeyword)) ? ClassificationTypeNames.ConstantName : ClassificationTypeNames.FieldName; |
There was a problem hiding this comment.
don't use lambda overload. don't use linq. wrap long line. align ? and : of ternary on next line.
| case EventDeclarationSyntax eventDeclarationSyntax: | ||
| return ClassificationTypeNames.EventName; | ||
| } | ||
| return ClassificationTypeNames.Identifier; |
There was a problem hiding this comment.
i would have everything fall out and generate .LocalName
| { | ||
| if (fieldSymbol.ContainingType.IsEnumType()) | ||
| return ClassificationTypeNames.EnumFieldName; | ||
| return ClassificationTypeNames.ConstantName; |
There was a problem hiding this comment.
curlies always required. But just replace this with a return ... ? ... : ...
|
I didn't see any code for VB here. |
|
I don't plan adding VB - anyways I need help with that change because I don't know enough about the VS.NET side - it surely breaks highlighting there ? |
As requested by the PR.
| bool isExtensionMethod = | ||
| (methodDeclaration.Parent as TypeDeclarationSyntax)?.Modifiers.Any(SyntaxKind.StaticKeyword) == true && | ||
| methodDeclaration.Modifiers.Any(SyntaxKind.StaticKeyword) && | ||
| methodDeclaration.ParameterList.Parameters.FirstOrDefault()?.Modifiers.Any(SyntaxKind.ThisKeyword) == true; |
There was a problem hiding this comment.
basically, my point is this: just check the parameter. you don't need the other checks as they're superfluous.
There was a problem hiding this comment.
Is there an extension method check somewhere ?
There was a problem hiding this comment.
not that i know of.
Someone will need to :) Are you coordinating with @dotnet/roslyn-ide so that it gets these additions as well? |
|
tagging @jinujoseph |
|
@dotnet/roslyn-ide - not yet. This PR should be more a discussion starting point what VS4Mac needs and what can be done to improve semantic highlighting. I already got some feedback and added some classifications VS4MAC didn't have. So we need to look & discuss at things - we won't be able to really change that once it's implemented. |
|
@mkrueger : The failing tests look like they're related to the new classifications. |
|
Since I reviewed this change, it looks like EditorFormatDefinitions have been added. Unless I'm mistaken, this will make the new classification types appear in the Fonts and Colors dialog in Visual Studio, but I believe the intent here was to update the API. If we want to take this PR as is, we need to do some further design work. Calling @kuhlenh! |
|
The failing tests are caused by the IClassificationTypeRegistryService from VS.NET that doesn't recognize the new tag names. |
translation. It may make sense to add new SymbolDisplayPartKinds matching the new classification type names.
|
Offline: I'll add VB support after this goes in. |
| case ClassificationTypeNames.MethodName: | ||
| case ClassificationTypeNames.PropertyName: | ||
| case ClassificationTypeNames.EventName: | ||
| return SymbolDisplayPartKind.Text; // TODO: Add more SymbolDisplayPartKinds |
DustinCampbell
left a comment
There was a problem hiding this comment.
Looks good @mkrueger! I'll add VB support in a follow-up PR.
| const Microsoft.CodeAnalysis.Classification.ClassificationTypeNames.LocalName = "local name" -> string | ||
| const Microsoft.CodeAnalysis.Classification.ClassificationTypeNames.ParameterName = "parameter name" -> string | ||
| const Microsoft.CodeAnalysis.Classification.ClassificationTypeNames.MethodName = "method name" -> string | ||
| const Microsoft.CodeAnalysis.Classification.ClassificationTypeNames.ExtensionMethodName = "extension method name" -> string |
There was a problem hiding this comment.
Any idea how we would expand this for extension everything?
There was a problem hiding this comment.
No idea what you mean with that - I can need the classification type names that get added so I made them public.
| return true; | ||
| case IParameterSymbol parameterSymbol: | ||
| if (parameterSymbol.IsImplicitlyDeclared && parameterSymbol.Name == "value") | ||
| break; |
There was a problem hiding this comment.
break should be surrounded by {}.
| Punctuation.CloseCurly); | ||
| } | ||
|
|
||
| /* [Fact, Trait(Traits.Feature, Traits.Features.Classification)] |
There was a problem hiding this comment.
Why the skip here? Can we get a proper Skip attribute applied if there's some tracking bug?
| { | ||
| foreach (var classifiedSpan in list) | ||
| { | ||
| var classificationType = typeMap.GetClassificationType(classifiedSpan.ClassificationType) ?? typeMap.GetClassificationType(ClassificationTypeNames.Identifier); |
There was a problem hiding this comment.
Any reason we can't just explicitly check for the types we know we added but didn't define formation definitions for yet? Might be easier than a fallback that means we'll forget to add a format definition, and things magically kinda work?
EditorFormatDefinition is at least documented as supporting UserVisible(false) as metadata on it, which might mean it's not shown in the UI. That might be cleaner than the "just return identifier" hack, or set us up for betterness in other places. |
|
@mkrueger @DustinCampbell: is master the branch you want here? If you want this in 15.7 we'll have to rebase it. |
|
We verified over email that 15.7 is what we want. Once @mkrueger rebases onto dev15.7.x and CI passes, I think we're good to merge. Then I'll follow up with some other fixes and VB support. I'm hoping we can get it all wrapped up tomorrow. |
|
I tidied up the PR a bit and rebased it onto dev15.7.x : #24931 |
Added classification for c# methods, events, fields and properties.
VB.NET is missing and unit tests. I've atm problems compiling/running the tests on my system. So do not merge it - it's untested.
But that's basically what we need in Visual Studio 4 Mac. It should be a base for discussion about classification enhancements.
esp. for making a difference between properties, events and fields this is useful.