编写StyleCop自定义规则教程(二)---校验规则增加配置参数

上一篇教程编写StyleCop自定义规则教程(一)---编写中文备注的简单校验规则 中使用的例子是校验代码中所有属性,不区分Public、Internal等。本文沿用原有例子增加两个规则的属性(IncludePublic和InculdeInternal),规则根据这两个属性的开关值,控制是否检查代码中访问权限是Public或Internal的代码。

 

在规则的xml文件中加入Properties节点

 

View Code
<Properties>
    
<BooleanProperty
      
Name="IncludePublic"
      DefaultValue
="True"
      FriendlyName
="包括Pulbic"
      Description
="代码分析时检验Public属性"
    
/>
    
<BooleanProperty
      
Name="IncludeInternal"
      DefaultValue
="True"
      FriendlyName
="包括Internal"
      Description
="代码分析时检验Internal属性"
    
/>    
  
</Properties>

 

CsDocument 类重载了多个WalkDocument方法,上一篇教程使用的是
WalkDocument(CodeWalkerElementVisitor<object> elementCallback,object context); 最后一个参数传入了空值,本文需要传入属性校验的开关值。因此使用void WalkDocument<T>(CodeWalkerElementVisitor<T> elementCallback, T context),定义一个结构体传入用户配置的值。
View Code
[StructLayout(LayoutKind.Sequential)]
        
private struct AnalyzerSettings
        {
            
public bool IncludePublic;
            
public bool IncludeInternal;
        }

private AnalyzerSettings LoadSettings(CodeDocument document)
        {
            AnalyzerSettings result 
= new AnalyzerSettings();
            result.IncludeInternal 
= true;
            result.IncludePublic 
= true;

            
if (document.Settings != null)
            {
                BooleanProperty addInSetting 
= document.Settings.GetAddInSetting(this"IncludePublic"as BooleanProperty;
                
if (addInSetting != null)
                {
                    result.IncludePublic 
= addInSetting.Value;
                }

                addInSetting 
= document.Settings.GetAddInSetting(this"IncludeInternal"as BooleanProperty;
                
if (addInSetting != null)
                {
                    result.IncludeInternal 
= addInSetting.Value;
                }
            }

            
return result;
        }

 

修改规则子类必须重写的AnalyzeDocument方法

View Code
public override void AnalyzeDocument(CodeDocument document)
        {
            Param.RequireNotNull(document, 
"document");
            CsDocument document2 
= (CsDocument)document;
            
if ((document2.RootElement != null&& !document2.RootElement.Generated)
            {
                AnalyzerSettings settings 
= LoadSettings(document);

                document2.WalkDocument
<AnalyzerSettings>(new CodeWalkerElementVisitor<AnalyzerSettings>(this.CheckDocumentationForElement), settings);
            }
        }

 

原有的CheckDocumentationForElement方法最后一个参数就是传入的配置值,方法根据代码节点的类型和访问权限进行校验

View Code
private bool CheckDocumentationForElement(CsElement element, CsElement parentElement, AnalyzerSettings settings)
        {
            
if (base.Cancel)
            {
                
return false;
            }

            
if (!element.Generated)
            {
                
if ((element.ElementType == ElementType.Property) &&
                ((settings.IncludePublic 
&& element.AccessModifier == AccessModifierType.Public) ||
                   (settings.IncludeInternal 
&& element.AccessModifier == AccessModifierType.Internal)))
                {
                    
this.ParseHeader(element, element.Header, element.LineNumber, false);
                }
            }
            
return true;
        }

 

 编译后将dll放到stylecop目录,在stylecop settings中选中新的规则,可以在右侧Detailed settings中看到规则的两个开关值。

 

代码: /Files/Byeah/WithSettingRule.zip

posted @ 2011-06-29 15:17  Byeah  阅读(2444)  评论(0编辑  收藏  举报