zoukankan      html  css  js  c++  java
  • 建立标准编码规则(二)-DiagnosticAnalyzer 增加诊断分析代码

    1.使用语法树

    当我们要编写一个规则,例如 检测正值表达式的时候,如何编写有效的规则呢

    Regex.Match("my text", @"pXXX");

    这里我们可以借助分析工具 Roslyn Syntax Visualizer,在 视图>其他窗口>Syntax Visualizer

    当我们在ConsoleApp项目中编写如下代码

    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Regex.Match("my text", @"pXXX");
            } 
        }
    }

    发现 SyntaxTree (以下称语法树)自动定位到对应的语法中

    在语法树中

    1 蓝色表示语法节点

    2 绿色表示编译器读取源文件时所发现的语法令牌、各个词、数字和符号

    3 红色表示琐碎内容,代表不是令牌的其他内容:空格、注释等。

     2.编写实例

    新建RegexAnalyzerAnalyzer 类,继承DiagnosticAnalyzer,写法类似默认生成的 DiagnosticAnalyzer.cs

      public class RegexAnalyzerAnalyzer : DiagnosticAnalyzer
       {
            public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }
            public override void Initialize(AnalysisContext context)
            {
                context.RegisterSyntaxNodeAction(
                  AnalyzeNode, SyntaxKind.InvocationExpression);
            }
    }

    其中 AnalysisContext 如下:

    RegisterSyntaxNodeAction 在分析特定类型的语法节点时触发
    RegisterSymbolAction 在分析特定类型的符号时触发
    RegisterSyntaxTreeAction 在分析文件的整棵语法树时触发
    RegisterSemanticModelAction 在语义模型可用于整个文件时触发
    RegisterCodeBlockStartAction
    RegisterCodeBlockEndAction
    在分析方法主体或其他代码块之前/之后触发

    RegisterCompilationStartAction
    RegisterCompilationEndAction
    在分析整个项目之前/之后触发

    11

    具体判断代码

    /// <summary>
            /// 1 首先他是一个表达式节点
            /// 2 他是Match方法
            /// 3 他是ystem.Text.RegularExpressions.Regex.Match下的方法
            /// 4 他有两个参数
            /// 5 第二个参数有值
            /// 6 使用Match捕捉第二个参数的正值表达式异常
            /// </summary>
            /// <param name="context"></param>
            private void AnalyzeNode(SyntaxNodeAnalysisContext context)
            {
                var invocationExpr = (InvocationExpressionSyntax)context.Node;//InvocationExpressionSyntax 表达式特定节点
                var memberAccessExpr =
                  invocationExpr.Expression as MemberAccessExpressionSyntax;
                if (memberAccessExpr?.Name.ToString() != "Match") return;//如果不是Match 返回
                var memberSymbol = context.SemanticModel.
                  GetSymbolInfo(memberAccessExpr).Symbol as IMethodSymbol;//获取上下文memberAccessExpr的语义模型
                if (!memberSymbol?.ToString().StartsWith(
                  "System.Text.RegularExpressions.Regex.Match") ?? true) return;//如果memberAccessExpr不是System.Text.RegularExpressions.Regex.Match 返回
                var argumentList = invocationExpr.ArgumentList as ArgumentListSyntax;//获取节点参数 
                if ((argumentList?.Arguments.Count ?? 0) < 2) return;//参数小于2返回
                var regexLiteral =
                  argumentList.Arguments[1].Expression as LiteralExpressionSyntax;//获取第二个参数内容
                if (regexLiteral == null) return;//第二个参数是null的返回
                var regexOpt = context.SemanticModel.GetConstantValue(regexLiteral);//获取参数的常量字符串
                if (!regexOpt.HasValue) return;//空值返回
                var regex = regexOpt.Value as string;//获取字符串
                if (regex == null) return;
                try
                {
                    System.Text.RegularExpressions.Regex.Match("", regex);//使用System.Text.RegularExpressions.Regex.Match 如果异常抛出异常
                }
                catch (ArgumentException e)
                {
                    //ArgumentException异常 抛出定义的说明
                    var diagnostic =
                      Diagnostic.Create(Rule, regexLiteral.GetLocation(), e.Message);
                    context.ReportDiagnostic(diagnostic);
                }
            }

    参考:https://msdn.microsoft.com/zh-cn/library/dn879356

    禁止转载
  • 相关阅读:
    webdav srs相关
    How To Configure WebDAV Access with Apache on Ubuntu 14.04
    ubuntu 编译lighttpd
    srs编译及推流测试
    Compile pciutils (lspci, setpci) in Windows x86,在 Windows x86 平台下编译 pciutils (lspci, setpci)
    mingw MSYS2 区别
    Qt之美(三):隐式共享
    Qt之美(二):元对象
    Qt之美(一):d指针/p指针详解
    C++的栈空间和堆空间
  • 原文地址:https://www.cnblogs.com/fishpro/p/7874992.html
Copyright © 2011-2022 走看看