Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/convert name of #45806

Merged
merged 164 commits into from
Aug 3, 2020
Merged

Feature/convert name of #45806

merged 164 commits into from
Aug 3, 2020

Conversation

m-redding
Copy link
Contributor

@m-redding m-redding commented Jul 8, 2020

CC: @JavierMatosD @sigmachirality

This feature offers an analyzer and code fix for issue #44162

It reports diagnostics and offers refactorings for relevant instances of typeof(SomeType).Name, to be changed to nameof(SomeType). It does not offer the refactoring on generic types because they are not semantically equivalent. In cases of system type keywords (int, string, etc), the code fix changes the keyword to the System.Type, because they are semantically equivalent, and the nameof() method does not accept keyword arguments.

See the attached document for more information.
convertNameOfSpec.docx

JavierMatosD and others added 30 commits June 23, 2020 15:04
WIP Analyzer, just bare bones diagnostic
Changed how ConvertNameOfAsync in the CodeFixeProvider finds the identifier name of the typeof expression
- Removed unused using statements
- Cleaned up ConvertNameOf method
@jmarolf
Copy link
Contributor

jmarolf commented Jul 23, 2020

Yes, I do. If we think this is a scenario that should be supported, we should change compiler to handle it.

The compiler handles it today. If a user uses the compiler APIs on a release build (which would be nearly everyone) the compiler handles this case just fine. Its only on debug builds that this is not accepted. If this is not valid then the compiler should throw an error in release builds instead of using Debug.Assert which does nothing to stop users from giving this to the compiler and getting valid results.

@jmarolf
Copy link
Contributor

jmarolf commented Jul 23, 2020

I guess my general question is: Do we think it is correct and good for the compiler to accept some syntax trees on a Release build but not a Debug build (of the compiler)?

@AlekseyTs
Copy link
Contributor

The compiler handles it today. If a user uses the compiler APIs on a release build (which would be nearly everyone) the compiler handles this case just fine.

What does it mean "just fine"? Doesn't crash? That is not sufficient to be fine. It looks to me that the scenario is not handled, i.e. the name is not extracted from the syntax.

@AlekseyTs
Copy link
Contributor

Why do you need to feed an invalid syntax to the compiler?

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jul 23, 2020

Do we think it is correct and good for the compiler to accept some syntax trees on a Release build but not a Debug build (of the compiler)?

We give ourselves a lot of flexibility in dealing with syntax trees that would never be produced by a parser.

@jmarolf
Copy link
Contributor

jmarolf commented Jul 23, 2020

cc: @CyrusNajmabadi as he has more knowledge than me on the SyntaxEditor api.

This is the code that created an invalid syntax node according to the VB compiler:

public void ConvertTypeOfToNameOf(SemanticModel semanticModel, SyntaxEditor editor, SyntaxNode nodeToReplace)
{
    var symbolType = GetSymbolType(semanticModel, nodeToReplace);
    var typeExpression = editor.Generator.TypeExpression(symbolType);
    var nameOfSyntax = editor.Generator.NameOfExpression(typeExpression);
    editor.ReplaceNode(nodeToReplace, nameOfSyntax);
}

Seems likely that this is a bug in the syntax editor then. I'll revert the feature work for VB and we can figure out how to create a nameof syntax in a safe way.

@jmarolf jmarolf dismissed AlekseyTs’s stale review July 24, 2020 01:10

I've removed the compiler change

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

Auto-approval


protected override Diagnostic LanguageReportDiagnostic(Location location, DiagnosticDescriptor cSharpDescriptor, DiagnosticDescriptor visualBasicDescriptor, CompilationOptions options)
{
return DiagnosticHelper.Create(visualBasicDescriptor,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why VB descriptor in C# implementation?

nameof(AnalyzersResources.Convert_gettype_to_nameof), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)))
{
var csharpMessage = new LocalizableResourceString(nameof(AnalyzersResources.Convert_typeof_to_nameof), AnalyzersResources.ResourceManager, typeof(AnalyzersResources));
CSharpDescriptor = CreateDescriptorWithId(DescriptorId, csharpMessage, csharpMessage);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are language specific messages and descriptors being created in language agnostic layer? This seems wrong, the sub-type should have all language specific code and abstract type should have no mention of language specific types, objects or resource strings.

var csharpMessage = new LocalizableResourceString(nameof(AnalyzersResources.Convert_typeof_to_nameof), AnalyzersResources.ResourceManager, typeof(AnalyzersResources));
CSharpDescriptor = CreateDescriptorWithId(DescriptorId, csharpMessage, csharpMessage);
}
internal DiagnosticDescriptor VBDescriptor => Descriptor;
Copy link
Contributor

Choose a reason for hiding this comment

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

Both this and below property must be removed.

{
}

protected override string GetCodeFixTitle(string visualbasic, string csharp)
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be changed so this fixer sub-type returns the correct resource string instead of base type being aware about supported languages.

@jmarolf jmarolf merged commit 7b2d501 into master Aug 3, 2020
@ghost ghost added this to the Next milestone Aug 3, 2020
@mavasani
Copy link
Contributor

mavasani commented Aug 3, 2020

Yay! Great job @m-redding @sigmachirality @JavierMatosD!

@RikkiGibson RikkiGibson modified the milestones: Next, 16.8.P2 Aug 11, 2020
@jmarolf jmarolf deleted the feature/convertNameOf branch August 18, 2021 23:20
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.

10 participants