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

WIP Base Analyzer #45595

Merged

Conversation

m-redding
Copy link
Contributor

This analyzer generally covers all cases as discussed in the specification. It needs to be tested on a more robust set of test cases in order to address additional bugs.

@m-redding m-redding requested a review from a team as a code owner July 1, 2020 20:15
@@ -34,15 +35,15 @@ public CSharpConvertNameOfDiagnosticAnalyzer()

protected override void InitializeWorker(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeSyntaxAction, SyntaxKind.TypeOfExpression);
context.RegisterOperationAction(AnalyzeTypeOfAction, OperationKind.TypeOf);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice! I was going to suggest switching to IOperation.

}

private void AnalyzeSyntaxAction(SyntaxNodeAnalysisContext syntaxContext)
private void AnalyzeTypeOfAction(OperationAnalysisContext typeofOp)
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: We avoid abbreviated names for locals.

Suggested change
private void AnalyzeTypeOfAction(OperationAnalysisContext typeofOp)
private void AnalyzeTypeOfAction(OperationAnalysisContext context)

// We know that it is a typeof() instance, but we only want to offer the fix if it is a .Name access
var parent = node.Parent;
if (!(node.Parent.IsKind(SyntaxKind.SimpleMemberAccessExpression) && parent.IsNameMemberAccess()))
Copy link
Contributor

@mavasani mavasani Jul 1, 2020

Choose a reason for hiding this comment

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

Can we avoid walking the syntax parent and instead look at IOperation.Parent of the operation node? That should be an IPropertyReferenceOperation with it's property symbol named FullName for us to continue analysis. This will help you avoid calling IsNameMemberAccess as well and should be faster.

return false;
}

private static bool ArgumentIsPrimitive(IOperation op)
Copy link
Contributor

Choose a reason for hiding this comment

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

A better way to check for primitive type is something like: https://github.com/dotnet/roslyn-analyzers/blob/f15404b312295e7cee16fb40b4c8d3f91f10f087/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DoNotLockOnObjectsWithWeakIdentity.cs#L124-L144

Maybe you can invoke the below method on ITypeSymbol.SpecialType and check if the returned predefined type is not None?

public static PredefinedType ToPredefinedType(this SpecialType specialType)


// Current case can be effectively changed to a nameof instance so report a diagnostic
var location = Location.Create(syntaxTree, parent.Span);
var additionalLocations = ImmutableArray.Create(node.GetLocation());

syntaxContext.ReportDiagnostic(DiagnosticHelper.Create(
typeofOp.ReportDiagnostic(DiagnosticHelper.Create(
Descriptor,
location,
ReportDiagnostic.Hidden,
Copy link
Contributor

Choose a reason for hiding this comment

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

Unless you plan to add a code style option for this analyzer, you can directly invoke Diagnostic.Create(Descriptor, location) here.

if (ArgumentIsGeneric(typeofOp.Operation) || ArgumentIsPrimitive(typeofOp.Operation))
{
return;
}

// Current case can be effectively changed to a nameof instance so report a diagnostic
var location = Location.Create(syntaxTree, parent.Span);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
var location = Location.Create(syntaxTree, parent.Span);
var location = parent.GetLocation();

if (ArgumentIsGeneric(typeofOp.Operation) || ArgumentIsPrimitive(typeofOp.Operation))
{
return;
}

// Current case can be effectively changed to a nameof instance so report a diagnostic
var location = Location.Create(syntaxTree, parent.Span);
var additionalLocations = ImmutableArray.Create(node.GetLocation());
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can avoid adding any additionalLocations here.

Suggested change
var additionalLocations = ImmutableArray.Create(node.GetLocation());

@m-redding m-redding merged commit cf1042c into dotnet:feature/convertNameOf Jul 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants