当前位置: 首页 > news >正文

西安个人建网站网络商城设计

西安个人建网站,网络商城设计,网站登录到wordpress,微商城和小程序区别随着团队越来越多#xff0c;越来越大#xff0c;需求更迭越来越快#xff0c;每天提交的代码变更由原先的2位数#xff0c;暴涨到3位数#xff0c;每天几百次代码Check In#xff0c;补丁提交#xff0c;大量的代码审查消耗了大量的资源投入。如何确保提交代码的质量和… 随着团队越来越多越来越大需求更迭越来越快每天提交的代码变更由原先的2位数暴涨到3位数每天几百次代码Check In补丁提交大量的代码审查消耗了大量的资源投入。如何确保提交代码的质量和提测产品的质量这两个是非常大的挑战。工欲善其事必先利其器。在上述需求背景下今年我们准备用工具和技术全面把控并提升代码质量和产品提测质量。即1. 代码质量提升通过自定义代码扫描规则将有问题的代码、不符合编码规则的代码扫描出来禁止签入2. 产品提测质量通过单元测试覆盖率和执行通过率严控产品提交质量覆盖率和通过率达不到标准无法提交测试。准备用2篇文章和大家分享我们是如何提升代码质量和产品提测质量的。今天分享第一篇通过Roslyn代码分析全面提升代码质量。一、什么是Roslyn  Roslyn 是微软开源的 .NET 编译平台(.NET Compiler Platform)。  编译平台支持 C# 和 Visual Basic 代码编译并提供丰富的代码分析 API。  利用Roslyn可以生成代码分析器和代码修补程序从而发现和更正编码错误。   分析器不仅理解代码的语法和结构还能检测应更正的做法。代码修补程序建议一处或多处修复以修复分析器发现的编码错误。  我们写下面一堆代码Roslyn编译器会有如下提示    通过编写分析器和代码修补程序主要服务以下场景  强制执行团队编码标准Local提供库包方面的指导约束Nuget提供代码分析器相关的VSIX扩展插件Visual Studio Marketplace Roslyn是如何做到代码分析的呢这背后依赖于一套强大的语法分析和API   上图中Language Service语言层面的服务可以简单理解为我们在VS中编码时,可以实现的语法高亮、查找所有引用、重命名、转到定义、格式化、抽取方法等操作  Compiler API编译器API这里提供了Syntax Tree API代码语法树APISymbol API代码符号API  Binding and Flow Anllysis APIs绑定和流分析APIhttps://joshvarty.com/2015/02/05/learn-roslyn-now-part-8-data-flow-analysis/  Emit API编译反射发出APIhttps://joshvarty.com/2016/01/16/learn-roslyn-now-part-16-the-emit-api/  这里我们详细看一下语法树、符号、语义模型、工作区  1. 语法树是一种由编译器 API 公开的基础数据结构。 这些树表示源代码的词法和语法结构。其包含  语法节点是语法树的一个主要元素。这些节点表示声明、语句、子句和表达式等语法构造。语法标记表示代码的最小语法片段。语法标记包含关键字、标识符、文本和标点。琐碎内容对正常理解代码基本上没有意义的源文本部分例如空格、注释和预处理器指令。范围每个节点、标记或琐碎内容在源文本内的位置和包含的字符数。种类标识节点、标记或琐碎内容所表示的确切语法元素。错误表示源文本中包含的语法错误。     看一张语法树的图    2. 符号符号表示源代码声明的不同元素或作为元数据从程序集中导出。每个命名空间、类型、方法、属性、字段、事件、参数或局部变量都由符号表示。  3. 语义模型语义模型表示单个源文件的所有语义信息。可使用语义模型查找到以下内容   在源中特定位置引用的符号。任何表达式的结果类型。所有诊断错误和警告。变量流入和流出源区域的方式。更多推理问题的答案。  4. 工作区工作区是对整个解决方案执行代码分析和重构的起点。相关的API可以实现     将解决方案中项目的全部相关信息组织为单个对象模型可让用户直接访问编译器层对象模型如源文本、语法树、语义模型和编译而无需分析文件、配置选项或管理项目内依赖项。     了解了Roslyn的大致情况之后我们开始基于Roslyn做一些“不符合编程规范要求团队自定义的”的代码分析。二、基于Roslyn进行代码分析  接下来讲通过Show case的方法通过实际的场景和大家分享。在我们编写实际的代码分析器之前我们先把开发环境准备好      使用VS2017创建一个Analyzer with Code Fix工程    因为我本机的VS2019找了好久没找到对应的工程这个章节使用VS2017吧    创建完成会有两个工程        其中TeldCodeAnalyzer.Vsix工程主要用以生成VSIX扩展文件   TeldCodeAnalyzer工程主要用于编写代码分析器。    工程转换好之后我们开始编码吧。 1. catch 吞掉异常场景  问题catch吞掉异常后线上很难排查问题同时确定哪块代码有问题  示例代码123456789try{     var logService HSFService.ProxyILogService();     logService.SendMsg(new SysActionLog());}catch (Exception ex){                 }  需求当开发人员在catch吞掉异常时给与编程提示异常吞掉时必须上报监控或者日志  明确了上述需要我们开始编写Roslyn代码分析器。ExceptionCatchWithMonitorAnalyzer    我们详细解读一下  ① ExceptionCatchWithMonitorAnalyzer必须继承抽象类DiagnosticAnalyzer  ② 重写方法SupportedDiagnostics注册代码扫描规则DiagnosticDescriptor    1234internal static DiagnosticDescriptor Rule  new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category,            DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description); public override ImmutableArrayDiagnosticDescriptor SupportedDiagnostics ImmutableArray.Create(Rule); ③ 重写方法Initialize注册Microsoft.CodeAnalysis.SyntaxNode完成Catch语句的语义分析后的事件Action12345public override void Initialize(AnalysisContext context){           context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.None);            context.EnableConcurrentExecution();            context.RegisterSyntaxNodeAction(AnalyzeDeclaration, SyntaxKind.CatchClause);} ④ 实现语法分析AnalyzeDeclaration检查对catch语句中代码实现   123456789101112131415161718private void AnalyzeDeclaration(SyntaxNodeAnalysisContext context){            var catchClause (CatchClauseSyntax)context.Node;            var block catchClause.Block;            foreach (var statement in block.Statements)            {                if (statement is ThrowStatementSyntax)                {                    return;                }            }              if (Common.IsReallyContains(block, MonitorClient)  false)            {                context.ReportDiagnostic(Diagnostic.Create(Rule, block.GetLocation()));            }}  代码实现后的效果直接调试VSIX工程即可  代码编译后也有对应Warnning提示 2. 在For循环中进行服务调用  问题for循环中调用RPC服务每次访问都会发起一次RPC请求如果循环次数太多性能很差建议使用批量处理的RPC方法  示例代码foreach (var item in items){      var logService HSFService.ProxyILogService();      logService.SendMsg(new SysActionLog());}    需求当开发人员在For循环中调用HSF服务时给与编程提示不建议在循环中调用HSF服务, 建议调用批量处理方法.  明确了上述需要我们开始编写Roslyn代码分析器。HSFForLoopAnalyzer  [DiagnosticAnalyzer(LanguageNames.CSharp)]public sealed class HSFForLoopAnalyzer : DiagnosticAnalyzer{    public const string DiagnosticId  TA001;    internal const string Title  增加循环中HSF服务调用检查;    public const string MessageFormat  不建议在循环中调用HSF服务, 建议调用批量处理方法.;    internal const string Category  CodeSmell;     internal static DiagnosticDescriptor Rule  new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category,        DiagnosticSeverity.Warning, isEnabledByDefault: true);     public override ImmutableArrayDiagnosticDescriptor SupportedDiagnostics ImmutableArray.Create(Rule);     public override void Initialize(AnalysisContext context)    {        context.RegisterSyntaxNodeAction(AnalyzeMethodForLoop, SyntaxKind.InvocationExpression);    }     private static void AnalyzeMethodForLoop(SyntaxNodeAnalysisContext context)    {        var expression (InvocationExpressionSyntax)context.Node;        string exressionText expression.ToString();        if (Common.IsReallyContains(expression, HSFService.Proxy))        {            var loop expression.Ancestors().FirstOrDefault(p p is ForStatementSyntax || p is ForEachStatementSyntax || p is DoStatementSyntax || p is WhileStatementSyntax);            if (loop ! null)            {                var diagnostic Diagnostic.Create(Rule, expression.GetLocation());                context.ReportDiagnostic(diagnostic);                return;            }             if (Common.IsReallyContains(expression, .)  false)            {                var syntax expression.Ancestors().FirstOrDefault(p p is LocalDeclarationStatementSyntax);                if (syntax ! null)                {                    var declaration (LocalDeclarationStatementSyntax)syntax;                    var variable declaration.Declaration.Variables.SingleOrDefault();                                        var method declaration.Ancestors().First(p p is MethodDeclarationSyntax);                    var expresses method.DescendantNodes().Where(p p is InvocationExpressionSyntax);                    foreach (var express in expresses)                    {                        loop express.Ancestors().FirstOrDefault(p p is ForStatementSyntax || p is ForEachStatementSyntax || p is DoStatementSyntax || p is WhileStatementSyntax);                        if (loop ! null)                        {                            var diagnostic Diagnostic.Create(Rule, expression.GetLocation());                            context.ReportDiagnostic(diagnostic);                            return;                        }                    }                }            }        }    }}  基本的实现方式和上一个差不多唯一不同的逻辑是在实际的代码分析过程中AnalyzeMethodForLoop。大家可以根据自己的需要写一下。       实际的效果              还有几个代码检查场景基本都是同样的实现思路再次不一一罗列了。       在这里还可以自动完成代理修补程序这个地方我们还在研究中可能每个业务代码的场景不同很难给出一个通用的改进代码所以这个地方等后续我们完成后再和大家分享。三、通过Roslyn实现静态代码扫描  线上很多代码已经写完了发布上线了对已有的代码进行代码扫描也是非常重要的。因此我们对catch吞掉异常的代码进行了一次集中扫描和改进。  那么基于Roslyn如何实现静态代码扫描呢主要的步骤有  ① 创建一个编译工作区MSBuildWorkspace.Create()  ② 打开解决方案文件OpenSolutionAsync(slnPath);    ③ 遍历Project中的Document  ④ 拿到代码语法树、找到Catch语句CatchClauseSyntax  ⑤ 判断是否有throw语句如果没有收集数据进行通知改进  看一下具体代码实现  先看一下Nuget引用  Microsoft.CodeAnalysis  Microsoft.CodeAnalysis.Workspaces.MSBuild    代码的具体实现      public async TaskListCodeCheckResult CheckSln(string slnPath)       {           var slnFile  new FileInfo(slnPath);           var results  new ListCodeCheckResult();                    var solution await MSBuildWorkspace.Create().OpenSolutionAsync(slnPath);                       if (solution.Projects ! null  solution.Projects.Count() 0)           {               foreach (var project in solution.Projects.ToList())               {                   var documents project.Documents.Where(x x.Name.Contains(.cs));                    foreach (var document in documents)                   {                       var tree await document.GetSyntaxTreeAsync();                       var root tree.GetCompilationUnitRoot();                       if (root.Members  null || root.Members.Count 0) continue;                       //member                       var firstmember root.Members[0];                       //命名空间Namespace                       var namespaceDeclaration (NamespaceDeclarationSyntax)firstmember;                        foreach (var classDeclare in namespaceDeclaration.Members)                       {                           var programDeclaration classDeclare as ClassDeclarationSyntax;                            foreach (var method in programDeclaration.Members)                           {                                //方法 Method                               var methodDeclaration (MethodDeclarationSyntax)method;                                var catchNode methodDeclaration.DescendantNodes().FirstOrDefault(i i is CatchClauseSyntax);                               if (catchNode ! null)                               {                                   var catchClause catchNode as CatchClauseSyntax;                                   if (catchClause ! null || catchClause.Declaration ! null)                                   {                                       if (catchClause.DescendantNodes().OfTypeThrowStatementSyntax().Count() 0)                                       {                                           results.Add(new CodeCheckResult()                                           {                                               Sln slnFile.Name,                                               ProjectName project.Name,                                               ClassName programDeclaration.Identifier.Text,                                               MethodName methodDeclaration.Identifier.Text,                                           });                                       }                                   }                               }                           }                       }                   }               }           }            return results;       }       以上是通过Roslyn代码分析全面提升代码质量的一些具体实践分享给大家。
http://www.huolong8.cn/news/352512/

相关文章:

  • 重庆网站建设优化排名学计算机网络技术的就业方向
  • 做海报在哪个网站可以找素材品牌策划公司招聘
  • 一个旅游网站建设需求分析江门制作手机网站
  • 企业网站seo诊断工具企业所得税规避50种
  • 怎么做网站代理商物流公司招聘信息
  • 网站源码怎么做网站怎么添加字体在wordpress
  • 天长市城乡规划建设局网站台州做网站最好的
  • 网站开发和软件开发环保局 网站建设
  • 公司网站维护建设费入什么科目o2o与网站建设论文
  • 全能网站建设pdfwordpress页面标题排序
  • 自己怎么免费做网站网页专门做品牌网站设计服务
  • 做一件代发的网站哈尔滨app网站开发
  • 合肥有什么好的网站建设公司好天津seo培训班在哪里
  • 厘米售卡站怎么做网站wordpress 注册角色
  • 上上海网站设计建设网站建设需要审批吗
  • 免费做网站的网站朝阳网络公司怎么样
  • 六安网站制作费用想学管理方面的培训班
  • 制作营销网站优化防疫政策
  • 杭州做购物网站wordpress 获取相册图片
  • 做平面设计在那个网站上找图好网站做系统叫什么名字
  • 网站编辑wordpress文章版权声明
  • 宁波网站制作报价四川省住房与城乡建设厅网站官网
  • wordpress能做cms魔方优化大师官网
  • 鲜花网站建设策划书甘肃省引洮工程建设管理局官方网站
  • 中学加强校园网站内容建设免费中文网站模板下载
  • 桐城市美丽乡村建设专题网站网站交易平台怎么注册
  • 网站转移空间临淄网站建设公司
  • 官方网站怎么做辽宁工程信息招标网
  • 大连零基础网站建设培训电话erp管理软件开发公司
  • 无法进行网站备案网站优化页面