Skip to content

Add semantic classification for records#47960

Merged
allisonchou merged 23 commits intodotnet:masterfrom
allisonchou:RecordsClassifications2
Oct 23, 2020
Merged

Add semantic classification for records#47960
allisonchou merged 23 commits intodotnet:masterfrom
allisonchou:RecordsClassifications2

Conversation

@allisonchou
Copy link
Contributor

@allisonchou allisonchou commented Sep 22, 2020

Fixes #46985
The default color for records is the default color for classes.

https://devdiv.visualstudio.com/DevDiv/_git/VSLanguageServerClient/pullrequest/276802 will be needed to support record colorization in LSP.

@allisonchou
Copy link
Contributor Author

@CyrusNajmabadi Are there areas missing here? Colorization still doesn't seem to be working properly in some cases.

I feel like this line will have to change to take in a SemanticModel so we can call GetSymbolInfo, but I think that will involve a significant amount of changes, so just want to check that this is the right move beforehand.

/// <summary>
/// Compares two <see cref="ISymbol"/> instances, ignoring all options
/// </summary>
public static readonly SymbolEqualityComparer IgnoreAll = new SymbolEqualityComparer(TypeCompareKind.AllIgnoreOptions);
Copy link
Contributor

Choose a reason for hiding this comment

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

@CyrusNajmabadi
Copy link
Contributor

I feel like this line will have to change to take in a SemanticModel so we can call GetSymbolInfo,

Nope: that's syntactic. You can determine what's going on just by checking the SyntaxKind of the containing node. IN this case syntaxKind.RecordDeclaration.


IMethodSymbol candidate = null;

// TO-DO: Change hard-coded '<Clone>$' to WellKnownMemberNames.CloneMethodName once it is made public
Copy link
Contributor

Choose a reason for hiding this comment

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

this.DisplayName = EditorFeaturesResources.User_Types_Records;
this.ForegroundColor = Color.FromRgb(0x2B, 0x91, 0xAF);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

i assume this is the color for classes. i"m on the fence if i want a different color here :) might be fun to call out records as the snazzy newnews. @mikadumont for thoughts. We can possibly pick one of the safe colors we found for regexes. that would a different PR though :)

Copy link
Contributor

Choose a reason for hiding this comment

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

@JoeRobich Do you need to do anything for advanced classification for this?

Copy link
Contributor

Choose a reason for hiding this comment

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

question still applies. @JoeRobich

Copy link
Member

Choose a reason for hiding this comment

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

@CyrusNajmabadi What do you mean by advanced classification?

Copy link
Contributor

Choose a reason for hiding this comment

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

whatever this stuff is:

image

:)

Copy link
Member

Choose a reason for hiding this comment

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

Nope. Since we are inheriting the ClassName color, there is no need to add entries to the ColorScheme files. When we decide a custom color is required we can add the entries at that time.

Copy link
Contributor

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

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

small tweaks.

@JoeRobich
Copy link
Member

One question we may want to ask ourselves is whether we want the Record classification to inherit the Class color if no custom Record color is defined. This is handled by the BaseClassification attribute on the ClassificationTypeDefinition. You then wouldn't have to set a Foreground color in the EditorFormatDefintion for the User - Record Name or define colors in the ColorScheme files, since it would be inherited.

Here are some things that will make this more complete. You can use this earlier PR as a guide - #31231

For classification within the Editor:

  • Will need entries for each theme in the VisualStudio2017 and VisualStudio2019 ColorScheme files (here).

For classification within QuickInfo and SignatureHelp:

  • Will need SymbolDisplayPart entry for Record (here)
  • Will need TextTags entriy for Record (here)
  • Will need to update mapping between all the different classification, part, tag types (here, here, and here)
  • Will need to update the SymbolDisplayVisitor and tests (here)

Adding a RecordName to SymbolDisplayPartKind will mean parts of Rolsyn that act on SymbolDisplayPartKind.ClassName will need to be updated such as https://github.com/dotnet/roslyn/blob/master/src/Features/Core/Portable/CodeLens/CodeLensReferencesService.cs#L258

…igure out why parameterized record test isn't working
@allisonchou
Copy link
Contributor Author

Marking the PR as ready to review. For now, I've taken Joey's suggestion to make the default record color the same color as classes, although this can change in a follow-up PR if we decide to go with a different color.

@allisonchou allisonchou marked this pull request as ready for review September 23, 2020 21:39
@allisonchou allisonchou requested review from a team as code owners September 23, 2020 21:39
@allisonchou allisonchou requested a review from a team September 23, 2020 21:39
@CyrusNajmabadi
Copy link
Contributor

CyrusNajmabadi commented Oct 19, 2020

@allisonchou @AlekseyTs here's what i think makes sense:

  1. in VB .IsRecord is never true. VB has no concept of this special sort of C# type, and think so of them entirely as normal classes.
  2. As such, if you take a record from metadata, import in VB, and display using C#'s display logic, you would see that just as class X not record X.
  3. For C#, both for source and metadata we would expect to see .IsRecord be true for the things we consider records :) so obviously record Foo in source would have this be true. If this is compiled to metadata and reimported, it should stay true. The c# symbol display logic for these types would show them a record X.... The VB symbol display logic for this would just be Class X...

For all IDE features, i would want us only to use .IsRecord and never look for things like a special 'Clone' mehtod

@allisonchou is this something you can pick back up?

@333fred
Copy link
Member

333fred commented Oct 19, 2020

Hmm. I was about to argue that I disagree with 1, but then I realized we don't import function pointer types in VB, we just mark them as unsupported by the language, which is an observable difference between C# compilations and VB compilations. In light of that, I think I'm fine with this behavior, though I do feel like someone is going to report a bug on us for it eventually.

@CyrusNajmabadi
Copy link
Contributor

though I do feel like someone is going to report a bug on us for it eventually.

Sure. But a reasoned and consistent position is fine to fall back on. :)

@allisonchou
Copy link
Contributor Author

@CyrusNajmabadi Thanks Cyrus! I've updated the code so that VB .IsRecord always returns false.
It's actually the same code as a previous iteration of this PR, I just had to update the failing test.

@allisonchou
Copy link
Contributor Author

@dotnet/roslyn-compiler After taking Cyrus' suggestion, I believe this PR is now once again ready for review.

@allisonchou
Copy link
Contributor Author

@dotnet/roslyn-compiler Would it be possible to get another look at this PR from the compiler side?

@CyrusNajmabadi
Copy link
Contributor

@jcouv @AlekseyTs @333fred can you ptal at this IDE unblocker PR. Thanks!

@333fred
Copy link
Member

333fred commented Oct 22, 2020

We should have some explicit tests using the IsRecord API directly. It's fine to do this by going through some of the tests in RecordTests and adding single asserts for that property, but we definitely want direct tests of the API, not just through SymbolDisplay.

@333fred
Copy link
Member

333fred commented Oct 22, 2020

Done review pass (commit 20) #Closed

Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

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

Changes under Compilers LGTM (iteration 22).

Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

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

Compiler changes LGTM (commit 22)

@allisonchou allisonchou merged commit 2421055 into dotnet:master Oct 23, 2020
@ghost ghost added this to the Next milestone Oct 23, 2020
@allisonchou allisonchou deleted the RecordsClassifications2 branch October 23, 2020 20:09
@allisonchou
Copy link
Contributor Author

Thanks everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom record constructors are highlighted as struct

8 participants