Skip to content

Conversation

@mavasani
Copy link
Contributor

...created through CodeAction.Create factory methods

It only took 7 years, but...
Fixes #4919

Currently, we always use the CodeAction's full type name to generate the telemetry ID to log for applied code actions. This is reasonable for special CodeActions that sub-type the CodeAction type and have custom logic. However, majority of fixers and refactorings do not need special CodeAction sub-type and can/should use the CodeAction.Create factory methods to create the code actions to register. Until now, these providers were forced to create a dummy nested type (generally named MyCodeAction) and use it to allow telemetry to capture the outer type's full type name.

With this change, we now keep track of whether a CodeAction was created with a factory method or not. If it was created with a factory method, then we use the registering fixer/refactoring provider's full type name for telemetry. Otherwise, we use the CodeAction's full type name. Additionally, we also append the EquivalenceKey in the telemetry ID in both the cases, which should allow multiple code actions registered by the same fixer/refactoring to be differentiated.

NOTE: I will create a follow-up PRs in both Roslyn and Roslyn-Analyzers repos to delete all the stub MyCodeAction types once this goes in.

…ted through CodeAction.Create factory methods

Fixes dotnet#4919
Currently, we always use the CodeAction's full type name to generate the telemetry ID to log for applied code actions. This is reasonable for special CodeActions that sub-type the CodeAction type and have custom logic. However, majority of fixers and refactorings do not need special CodeAction sub-type and can/should use the CodeAction.Create factory methods to create the code actions to register. Until now, these providers were forced to create a dummy nested type (generally named MyCodeAction) and use it to allow telemetry to capture the outer type's full type name.

With this change, we now keep track of whether a CodeAction was created with a factory method or not. If it was created with a factory method, then we use the registering fixer/refactoring provider's full type name for telemetry. Otherwise, we use the CodeAction's full type name. Additionally, we also append the EquivalenceKey in the telemetry ID in both the cases, which should allow multiple code actions registered by the same fixer/refactoring to be differentiated.

NOTE: I will create a follow-up PRs in both Roslyn and Roslyn-Analyzers repos to delete all the stub MyCodeAction types once this goes in.
@mavasani mavasani added this to the 17.3 milestone Mar 30, 2022
@mavasani mavasani requested a review from jmarolf March 30, 2022 11:46
@mavasani mavasani requested review from a team as code owners March 30, 2022 11:46
@mavasani mavasani requested a review from a team March 30, 2022 11:46
@Youssef1313
Copy link
Member

NOTE: I will create a follow-up PRs in both Roslyn and Roslyn-Analyzers repos to delete all the stub MyCodeAction types once this goes in.

Should this really be done for roslyn-analyzers if Microsoft.CodeAnalysis packages isn't updated to latest?

@mavasani
Copy link
Contributor Author

Should this really be done for roslyn-analyzers if Microsoft.CodeAnalysis packages isn't updated to latest?

I don’t believe anyone is actively looking at CodeFixer telemetry to be affected if we have a small intermediate period without useful telemetry. So I think we should be fine. Also note that the analyzer package itself doesn’t need to move to reference newer MS.CA packages as there are no public API changes here.

@CyrusNajmabadi
Copy link
Member

Will this mean we can get rid of all our 'MyCideAction' subclasses?

@Youssef1313
Copy link
Member

Will this mean we can get rid of all our 'MyCideAction' subclasses?

For 99.99% of the cases yes (per my understanding). The 0.01% are cases like this where the subclass does something useful:

private sealed class MyCodeAction : CodeAction.SolutionChangeAction
{
private readonly Func<CodeActionPurpose, CancellationToken, Task<Solution>> _createChangedSolution;
public MyCodeAction(Func<CodeActionPurpose, CancellationToken, Task<Solution>> createChangedSolution)
: base(
CSharpFeaturesResources.Enable_nullable_reference_types_in_project,
cancellationToken => createChangedSolution(CodeActionPurpose.Apply, cancellationToken),
nameof(CSharpFeaturesResources.Enable_nullable_reference_types_in_project))
{
_createChangedSolution = createChangedSolution;
}
protected override async Task<IEnumerable<CodeActionOperation>> ComputePreviewOperationsAsync(CancellationToken cancellationToken)
{
var changedSolution = await _createChangedSolution(CodeActionPurpose.Preview, cancellationToken).ConfigureAwait(false);
if (changedSolution is null)
return Array.Empty<CodeActionOperation>();
return new CodeActionOperation[] { new ApplyChangesOperation(changedSolution) };
}
}

@mavasani
Copy link
Contributor Author

Yes, agree with @Youssef1313

@CyrusNajmabadi
Copy link
Member

Great. That makes me super happy.

@JoeRobich
Copy link
Member

JoeRobich commented Mar 30, 2022

@mavasani Would you also be able to update the tool that generates a mapping table of CodeAction Provider to TelemetryId? https://github.com/mavasani/roslyn/tree/CodeActionTelemetry/src/Tools/BuildActionTelemetryTable

Nevermind, not sure how I missed it.

@jmarolf
Copy link
Contributor

jmarolf commented Mar 30, 2022

Thanks @mavasani! No issues with the PR, will just need to remember to keep both kinds of maps in our queries so we don't drop stuff from before this change goes in.

@mavasani
Copy link
Contributor Author

Would you also be able to update the tool that generates a mapping table of CodeAction Provider to TelemetryId?

Actually, good observation. I have done partial fixes to that tool, but can get it fully working again only after I am able to cleanup and remove the MyCodeAction nested types. More changes to the tool are coming in the next PR.

@Youssef1313
Copy link
Member

@mavasani There is an unrelated failure here. Can you restart it so the PR can be merged?

@mavasani mavasani merged commit 6039b44 into dotnet:main Apr 4, 2022
@ghost ghost modified the milestones: 17.3, Next Apr 4, 2022
@mavasani mavasani deleted the CodeActionTelemetry branch April 5, 2022 04:03
@dibarbet dibarbet removed this from the Next milestone Apr 25, 2022
@dibarbet dibarbet added this to the 17.3.P1 milestone Apr 25, 2022
mavasani added a commit to mavasani/roslyn that referenced this pull request May 2, 2022
mavasani added a commit to mavasani/roslyn that referenced this pull request May 2, 2022
mavasani added a commit to mavasani/roslyn that referenced this pull request May 2, 2022
mavasani added a commit to mavasani/roslyn that referenced this pull request May 2, 2022
mavasani added a commit to mavasani/roslyn that referenced this pull request May 2, 2022
mavasani added a commit to mavasani/roslyn that referenced this pull request Jun 9, 2022
Follow up to dotnet#60480.
The above PR led to us logging provider name instead of code action name in the telemetry when provider is using CodeAction.Create helper to create a code action. This broke the CodeActionDescriptionMap within the BuildActionTelemetryTable tool that is used to search for code action telemetry in Kusto.

This PR regenerates the CodeActionDescriptionMap. I have added a helper method to the tool which can be used when required to regenerate this description map in future.
mavasani added a commit to mavasani/roslyn that referenced this pull request Jun 9, 2022
Follow up to dotnet#60480.

The above PR led to us logging provider name instead of code action name in the telemetry when provider is using CodeAction.Create helper to create a code action. This broke the CodeActionDescriptionMap within the BuildActionTelemetryTable tool that is used to search for code action telemetry in Kusto.

This PR regenerates the CodeActionDescriptionMap. I have added a helper method to the tool which can be used when required to regenerate this description map in future.
mavasani added a commit to mavasani/roslyn that referenced this pull request Jun 9, 2022
Follow up to dotnet#60480.

The above PR led to us logging provider name instead of code action name in the telemetry when provider is using CodeAction.Create helper to create a code action. This broke the CodeActionDescriptionMap within the BuildActionTelemetryTable tool that is used to search for code action telemetry in Kusto.

This PR regenerates the CodeActionDescriptionMap. I have added a helper method to the tool which can be used when required to regenerate this description map in future.
mavasani added a commit to mavasani/roslyn that referenced this pull request Jun 9, 2022
Follow up to dotnet#60480.

The above PR led to us logging provider name instead of code action name in the telemetry when provider is using CodeAction.Create helper to create a code action. This broke the CodeActionDescriptionMap within the BuildActionTelemetryTable tool that is used to search for code action telemetry in Kusto.

This PR regenerates the CodeActionDescriptionMap. I have added a helper method to the tool which can be used when required to regenerate this description map in future.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add PredefinedCode{Fix,Refactor}ProviderNames to CodeAction.CustomTags to identify analyzers\fixers for telemetry

6 participants