【问题标题】:Roslyn Vsix stopped working after moving the projectRoslyn Vsix 在移动项目后停止工作
【发布时间】:2017-06-27 04:19:58
【问题描述】:

我有一个有效的 Roslyn VSIX 项目,用于分析可本地化的资源。在我将项目移至新位置之前,一切都运行良好。

分析器似乎仍在运行并触发代码修复,但是,代码操作从未注册到 Visual Studio,因此由于某种原因没有该修复的选项。

我的分析仪:

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class ConstDiagnosticAnalyzer : DiagnosticAnalyzer
{
    public const string DiagnosticId = "Viventium.Localization.Tools.ConstantToResource";

    // You can change these strings in the Resources.resx file. If you do not want your analyzer to be localize-able, you can use regular strings for Title and MessageFormat.
    // See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/Localizing%20Analyzers.md for more on localization
    private static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.ConstAnalyzerTitle), Resources.ResourceManager, typeof(Resources));
    private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.ConstAnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources));
    private static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.ConstAnalyzerDescription), Resources.ResourceManager, typeof(Resources));
    private const string Category = "Naming";

    private static ResourceLocalizationRule localizationRule = new ResourceLocalizationRule();

    private static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description);

    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }

    public override void Initialize(AnalysisContext context)
    {
        context.RegisterSyntaxNodeAction(AnalyzeConstDeclaration, SyntaxKind.FieldDeclaration);
    }

    public static void AnalyzeConstDeclaration(SyntaxNodeAnalysisContext context)
    {
        var fieldDeclaration = (FieldDeclarationSyntax)context.Node;

        if (false == IsValidConstDeclaration(context, fieldDeclaration))
        {
            return;
        }

        var firstVariable = fieldDeclaration.Declaration.Variables.FirstOrDefault();
        var firstSymbol = context.SemanticModel.GetDeclaredSymbol(firstVariable);

        context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation(), firstSymbol.Name));
    }

    private static bool VariableIsInResx(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclaration)
    {
        var solution = context.GetSolution();
        var documentPropertyMap = PropertyMapCache.GetDocumentPropertyMap(solution);

        return localizationRule.IsFieldDeclaredInResx(fieldDeclaration, documentPropertyMap);
    }

    private static bool IsValidConstDeclaration(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclaration)
    {
        if (false == fieldDeclaration.Modifiers.Any(SyntaxKind.ConstKeyword))
        {
            return false;
        }

        if (fieldDeclaration.Declaration.Variables.Count > 1)
        {
            return false;
        }

        var declaredVariable = fieldDeclaration.Declaration.Variables.FirstOrDefault();

        var initializer = declaredVariable.Initializer;
        if (initializer == null)
        {
            return false;
        }

        var constantValue = context.SemanticModel.GetConstantValue(initializer.Value);
        if (!constantValue.HasValue)
        {
            return false;
        }

        var variableTypeName = fieldDeclaration.Declaration.Type;
        var variableType = context.SemanticModel.GetTypeInfo(variableTypeName).ConvertedType;

        if (variableType.SpecialType != SpecialType.System_String)
        {
            return false;
        }

        return true;
    }
}

修复提供者:

[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(ConstantToResourceCodeFixProvider)), Shared]
public class ConstantToResourceCodeFixProvider : CodeFixProvider
{
    #region Consts

    private const string title = "Convert Constant Use Resources";

    #endregion

    #region CodeFixProvider Overrides

    public sealed override ImmutableArray<string> FixableDiagnosticIds
    {
        get { return ImmutableArray.Create(ConstDiagnosticAnalyzer.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<FieldDeclarationSyntax>().First();

        // Register a code action that will invoke the fix.
        context.RegisterCodeFix(
            CodeActionWithPreview.CreateStateful(
                title: title,
                createChangedDocument: (c, isPreview) => this.CheckConstForLocalization(context, declaration, isPreview, c),
                equivalenceKey: title),
            diagnostic);
    }

    #endregion

    #region Analyzer Logic

    private async Task<Document> CheckConstForLocalization(CodeFixContext context, FieldDeclarationSyntax field, bool isPreview, CancellationToken cancellationToken)
    {
        var documentPropertyMap = PropertyMapCache.GetDocumentPropertyMap(context.Document.Project.Solution);

        var localizationRule = new ResourceLocalizationRule();
        var updatedDocument = localizationRule.ConvertDocumentToUseResources(context.Document, documentPropertyMap, field, isPreview, cancellationToken);

        return await updatedDocument;
    }

    #endregion
}

谁能给我一个提示,告诉我发生了什么以及如何解决这个问题?

【问题讨论】:

    标签: c# roslyn code-analysis


    【解决方案1】:

    经过数小时的调试,结果发现诊断分析器中不允许有句点...

    public const string DiagnosticId = "Viventium_Localization_Tools_ConstantToResource";
    

    修复非常简单,我只是将 DiagnosticId 更改为使用下划线,并使用 Roslyn 打开了一个错误

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-04
      相关资源
      最近更新 更多