I first wrote a DiagnosticAnalyzer
and then battled to get it to load until I listed its project as an Asset in the VSIX manifest.
Now I also added a CodeFixProvider
to the same project as the analyzer, but it doesn't load.
What am I missing?
I tried the following:
- Added the SharedAttribute.
- Changed its namespace to the same namespace as the analyzer.
- Made sure the DiagnosticId is pointing to the same DiagnosticId used by the Analyzer.
- Deleted the "C:\Users\cp321831\AppData\Local\Microsoft\VisualStudio\15.0_c657f3ebRoslyn\ComponentModelCache" directory
- Deleted the "C:\Users\cp321831\AppData\Local\Microsoft\VisualStudio\15.0_c657f3ebExp\ComponentModelCache" directory
- Deleted the completed "15.0_c657f3ebRoslyn" and "15.0_c657f3ebExp" directories
- I made sure the name ends with CodeFixProvider.
A breakpoint in the type constructor as well as the instance constructor and any of the methods reveal that nothing in the code fixer is loaded and nothing gets hit.
Here is the code for the code fixer:
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Capitec.CodeAnalysis.Diagnostics
{
[ExportCodeFixProvider(LanguageNames.CSharp), Shared]
public sealed class UserInteractionCodeFixProvider : CodeFixProvider
{
private const string Title = "Invoke mapped function instead";
static UserInteractionCodeFixProvider()
{
}
public UserInteractionCodeFixProvider()
{
}
public override ImmutableArray<string> FixableDiagnosticIds =>
ImmutableArray.Create(
AutomationScriptAnalyzerOfReplacableUserInteractions.DiagnosticId);
public override FixAllProvider GetFixAllProvider()
{
return WellKnownFixAllProviders.BatchFixer;
}
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken)
.ConfigureAwait(false);
var diagnostic = context.Diagnostics.First();
var span = diagnostic.Location.SourceSpan;
var invocation = ResolveInvocation(root, span);
context.RegisterCodeFix(
CodeAction.Create(
Title,
ct => InvokeFunctionInstead(context.Document, invocation, ct),
equivalenceKey: Title),
diagnostic);
}
private InvocationExpressionSyntax ResolveInvocation(SyntaxNode root, TextSpan span)
{
return root
.FindToken(span.Start)
.Parent
.AncestorsAndSelf()
.OfType<InvocationExpressionSyntax>()
.First();
}
private Task<Document> InvokeFunctionInstead(
Document document,
InvocationExpressionSyntax invocation,
CancellationToken cancellationToken)
{
return Task.FromResult(document);
}
}
}
Any help would be appreciated.
Thanks.