建立标准编码规则(二)-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 ?? ) < ) return;//参数小于2返回
var regexLiteral =
argumentList.Arguments[].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
建立标准编码规则(二)-DiagnosticAnalyzer 增加诊断分析代码的更多相关文章
- 建立标准编码规则(三)-CodeFixProvider 给代码分析器增加修复建议
给代码分析器增加修复建议 既然代码分析器,向代码编写者提出了错误或警告,那么有没有可能向代码编写者提交有效的改进建议? 相对于 DiagnosticAnalyzer,代码修复继承与 CodeFixPr ...
- 建立标准编码规则(一)-自定义C#代码分析器
1.下载Roslyn的Visual Studio分析器模板插件(VS2015 或VS2017) https://marketplace.visualstudio.com/items?itemName= ...
- 建立标准编码规则(四)-C#编码规范分类及实现
1 现实中的问题 在任何一个公司,每个程序员编写的习惯可能都是不一样的,大到命名空间,小到变量的名字.甚至,我们去github,里面的大牛每个开源的项目的命名规则可能都不一样. 我们通常会遇到下面的问 ...
- gops —— Go 程序诊断分析工具
GitHub: https://github.com/google/gops 一个用于列出和诊断分析系统中正在运行的 Go 程序的命令行工具 安装 go get -u github.com/googl ...
- openssl ans.1编码规则分析及证书密钥编码方式
1 数据编码格式 openssl的数据编码规则是基于ans.1的,ans.1是什么 ? 先上高大上的解释 ASN.1(Abstract Syntax Notation One), 是一种结构化的描述语 ...
- 04Redis入门指南笔记(内部编码规则简介)
Redis是一个基于内存的数据库,所有的数据都存储在内存中.所以如何优化存储,减少内存空间占用是一个非常重要的话题.精简键名和键值是最直观的减少内存占用的方式,如将键名very.important.p ...
- UTF-8编码规则(转)
from:http://www.cnblogs.com/chenwenbiao/archive/2011/08/11/2134503.html UTF-8是Unicode的一种实现方式,也就是它的字节 ...
- UTF-8编码规则
UTF-8是Unicode的一种实现方式,也就是它的字节结构有特殊要求,所以我们说一个汉字的范围是0X4E00到0x9FA5,是指unicode值,至于放在utf-8的编码里去就是由三个字节来组织,所 ...
- UTF-8编码规则【转】
hz_chenwenbiao UTF-8编码规则(转) UTF-8是Unicode的一种实现方式,也就是它的字节结构有特殊要求,所以我们说一个汉字的范围是0X4E00到0x9FA5,是指unicode ...
随机推荐
- iOS开发(1):设置APP的图标与启动图 | iOS图标的尺寸 | LaunchScreen的使用
每个APP都应该有自己的图标跟启动图. 这里介绍怎么设置iOS的APP的图标跟启动图. (1)图标 小程的xcode是10.0版本,设置图标的入口如下: 点击入口后,进到设置页面,如下: 可以看到有很 ...
- eosio.cdt:EOS智能合约工具集
目前EOS已经迎来了1.5.x时代,很多内容都有了较大的改变.其中智能合约的工作流程发生了改变,EOSIO为智能合约提供了独立且功能完整的工具集eosio.cdt.该工具集基于WASM平台,可解耦于e ...
- 认识Nginx,理解原理和功能
前端工程师在理解Nginx之后,就能更好的与后端工程师沟通,为了能提高工作效率,这两天抽空读了<Nginx高性能Web服务器实战教程>. 一.Nginx Nginx是一款高性能的Web服务 ...
- 程序员进阶之算法练习:LeetCode专场
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由落影发表 前言 LeetCode上的题目是大公司面试常见的算法题,今天的目标是拿下5道算法题: 题目1是基于链表的大数加法,既考察基本 ...
- springboot + freemarker 实现国际化
前言 写过一篇springboot+freemarker国际化过程中的细节问题,但没有写过具体的国际化实现过程.正好有人在问,我就把我实现的过程贴出来,即使自己知识的一个备份,如果对别人有点用,那是再 ...
- [HEOI2016] 字符串
Description 给定长度为n的字符串,m次询问,每次询问s[a...b]的所有子串与s[c...d]的LCP的最大值.n,m<=10^5. Solution 感觉这种n,m<=10 ...
- c# UTF-16转UTF-8 互转
/// <summary> /// UTF-16转UTF-8 /// </summary> /// <param name="str">< ...
- Asp.net中GridView详解《转》
ASP.NET服务器控件GridView 1 ASP.NET 服务器控件GridView使用 本教程不介绍服务器端控件的呈现,事件处理,状态等理论知识,只介绍服务器端控件的使用操作,如 ...
- CentOS6.5安装mysql以及常见问题的解决
前言 最近在学习Linux系统,今天在安装MySQL数据库时出现很多问题,花费了两个小时终于解决,故记录下来以供大家参考.(本人目前还在学习阶段,下面写到的是自己结合网上查到的资料以及各位前辈给出的解 ...
- 性能监控(1)--linux下的top命令
Linux下的监控工具 top命令 top命令能够实时显示系统中各个进程的资源占用情况,其输出信息分为两部分,前半部分为系统统计信息,后半部分是进程信息. 第一行是任务队列信息,它的结果等同于upti ...