Roslyn VSIX 扩展因在修复提供程序中添加功能而爆炸 [英] Roslyn VSIX Extension Blows up from adding function in fix provider

查看:43
本文介绍了Roslyn VSIX 扩展因在修复提供程序中添加功能而爆炸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在处理一个问题,我假设它是特定于环境的.当我向 CodeFixProvider 中添加任何函数时,我安装并重新安装了

I've been dealing with an issue I'm going to assume is environment specific. I installed and reinstalled the Roslyn Templates when I add any function to the CodeFixProvider(Referenced or not). VS blows up with an system aggregate exception when trying to open the preview window:

这是完整的代码修复提供程序,唯一修改的是添加新功能

This is the full code fix provider the only thing modified is adding the new function

[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(AggregateBugAnalyzerCodeFixProvider)), Shared]
public class AggregateBugAnalyzerCodeFixProvider : CodeFixProvider
{
    private const string title = "Make uppercase";

    public sealed override ImmutableArray<string> FixableDiagnosticIds
    {
        get { return ImmutableArray.Create(AggregateBugAnalyzerAnalyzer.DiagnosticId); }
    }

    public sealed override FixAllProvider GetFixAllProvider()
    {
        // See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/FixAllProvider.md for more information on Fix All Providers
        return WellKnownFixAllProviders.BatchFixer;
    }

    public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
    {
        var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

        // TODO: Replace the following code with your own analysis, generating a CodeAction for each fix to suggest
        var diagnostic = context.Diagnostics.First();
        var diagnosticSpan = diagnostic.Location.SourceSpan;

        // Find the type declaration identified by the diagnostic.
        var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<TypeDeclarationSyntax>().First();

        // Register a code action that will invoke the fix.
        context.RegisterCodeFix(
            CodeAction.Create(
                title: title,
                createChangedSolution: c => MakeUppercaseAsync(context.Document, declaration, c),
                equivalenceKey: title),
            diagnostic);
    }

    private async Task<Solution> MakeUppercaseAsync(Document document, TypeDeclarationSyntax typeDecl, CancellationToken cancellationToken)
    {
        // Compute new uppercase name.
        var identifierToken = typeDecl.Identifier;
        var newName = identifierToken.Text.ToUpperInvariant();

        // Get the symbol representing the type to be renamed.
        var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
        var typeSymbol = semanticModel.GetDeclaredSymbol(typeDecl, cancellationToken);

        // Produce a new solution that has all references to that type renamed, including the declaration.
        var originalSolution = document.Project.Solution;
        var optionSet = originalSolution.Workspace.Options;
        var newSolution = await Renamer.RenameSymbolAsync(document.Project.Solution, typeSymbol, newName, optionSet, cancellationToken).ConfigureAwait(false);

        // Return the new solution with the now-uppercase type name.
        return newSolution;
    }

    //Just the existance of this function causes VS to throw
    public string Blowup()
    {
        return "Why";
    }
}

当我打开所有异常时,我发现了这个错误:

When I turn on all exception I catch this error:

附加信息:无法将System.Reflection.RuntimeMethodInfo"类型的对象转换为System.Reflection.ConstructorInfo"类型.

Additional information: Unable to cast object of type 'System.Reflection.RuntimeMethodInfo' to type 'System.Reflection.ConstructorInfo'.

这可能是由不匹配的运行时引起的.如果我将函数移动到它自己的类中,一切都很好.

Which is presumably cause by mismatching runtimes. If I move the function into it's own class everything is fine.

内部异常堆栈跟踪

>   at Microsoft.VisualStudio.Composition.Reflection.ResolverExtensions.Resolve(ConstructorRef constructorRef)
   at Microsoft.VisualStudio.Composition.RuntimeComposition.RuntimePart.get_ImportingConstructor()
   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.RuntimePartLifecycleTracker.CreateValue()
   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.Create()
   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveNext(PartLifecycleState nextState)
   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveToState(PartLifecycleState requiredState)
   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.GetValueReadyToExpose()
   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.<>c__DisplayClass15_0.<GetExportedValueHelper>b__0()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.<>c__DisplayClass15_0.<GetExportedValueHelper>b__0()
   at Microsoft.VisualStudio.Composition.DelegateServices.<>c__DisplayClass2_0`1.<As>b__0()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at System.Lazy`1.get_Value()
   at Microsoft.CodeAnalysis.CodeFixes.CodeFixService.<>c__DisplayClass24_0.<GetFixerPerLanguageMap>b__0()
   at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Lazy`1.get_Value()
   at Microsoft.CodeAnalysis.CodeFixes.CodeFixService.<AppendFixesAsync>d__13.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.CodeAnalysis.CodeFixes.CodeFixService.<GetFixesAsync>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.CodeAnalysis.Editor.Implementation.Suggestions.SuggestedActionsSourceProvider.Source.<>c__DisplayClass15_1.<<GetCodeFixes>b__0>d.MoveNext()

推荐答案

我怀疑 VS MEF 缓存了来自您的类的旧版本的 CIL 令牌,而新方法正在丢弃缓存的令牌.

I suspect that VS MEF cached CIL tokens from an older build of your class, and the new method is throwing off the cached tokens.

从 AppData\Local\Microsoft\VisualStudio_您的测试实例_中删除 ComponentModelCache 目录.

Delete the ComponentModelCache directory from AppData\Local\Microsoft\VisualStudio_your test instance_.

这篇关于Roslyn VSIX 扩展因在修复提供程序中添加功能而爆炸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆