TestForNullArgumentBeforeReferencingRule.cs :  » Development » devAdvantage » AnticipatingMinds » KnowledgePack » ErrorHandling » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Development » devAdvantage 
devAdvantage » AnticipatingMinds » KnowledgePack » ErrorHandling » TestForNullArgumentBeforeReferencingRule.cs
using System;
using System.Collections;
using System.Collections.Specialized;
using AnticipatingMinds.Genesis.KnowledgeManagement;
using AnticipatingMinds.Genesis.CodeDOM;
using AnticipatingMinds.Genesis.CodeDOM.Utilities;
using System.Windows.Forms;
using System.Xml;

namespace AnticipatingMinds.KnowledgePack.ErrorHandling{
  public class TestForNullArgumentBeforeReferencingRuleTemplate : RuleTemplate
    {
    public TestForNullArgumentBeforeReferencingRuleTemplate(string templateId, IDictionary templateProperties):base(templateId,templateProperties)
    {
      KnowledgePackLicense.Validate();
    }

    public override string Name
    {
      get
      {
        return ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Name");
      }
    }
    
    public override string Description
    {
      get
      {
        return ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Description");
      }
    }

    public override Rule CreateRule(string ruleId, IDictionary ruleProperties)
    {
      return new TestForNullArgumentBeforeReferencingRuleRule(ruleId, Id, ruleProperties);
    }  
  
    public override AnticipatingMinds.CommonUIControls.PropertyPage[] GetRulePropertiesUI(IDictionary ruleProperties)
    {
      AnticipatingMinds.CommonUIControls.PropertyPage[] pages = new AnticipatingMinds.CommonUIControls.PropertyPage[1];
      pages[0] = new TestForNullArgumentCorrectionPropertiesPage(ruleProperties); 
      return pages;
    }

  }

  public class TestForNullArgumentBeforeReferencingRuleRule : Rule
  {
    #region Rule Property
    public new class PropertyName : Rule.PropertyName
    {
      public const string ArgumentNullExceptionMessage = "ArgumentNullExceptionMessage";

      public const string ParamNameConstructor = "ParamNameConstructor";
      public const string ParamAndMessageConstructor = "ParamAndMessageConstructor";

      public const string ParamAndMessageDefault = "ParamAndMessageDefault";
      public const string ParamNameDefault = "ParamNameDefault";
    }
    private string ArgumentNullExceptionMessage
    {
      get{
        return GetProperty(PropertyName.ArgumentNullExceptionMessage, ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|ArgumentNullExceptionMessageDefault")).ToString();
      }
      set{
        SetProperty(PropertyName.ArgumentNullExceptionMessage, value);  
      }
    }
    private bool ParamNameConstructor
    {
      get{ return Convert.ToBoolean(GetProperty(PropertyName.ParamNameConstructor, true)); }
      set{ SetProperty(PropertyName.ParamNameConstructor, value);}
    }
    
    private bool ParamNameDefault
    {
      get{ return Convert.ToBoolean(GetProperty(PropertyName.ParamNameDefault, true)); }
      set{ SetProperty(PropertyName.ParamNameDefault, value);}
    }

    private bool ParamAndMessageConstructor
    {
      get{ return Convert.ToBoolean(GetProperty(PropertyName.ParamAndMessageConstructor, false)); }
      set{ SetProperty(PropertyName.ParamAndMessageConstructor, value);}
    }
    
    private bool ParamAndMessageDefault
    {
      get{ return Convert.ToBoolean(GetProperty(PropertyName.ParamAndMessageDefault, false)); }
      set{ SetProperty(PropertyName.ParamAndMessageDefault, value);}
    }
    
    #endregion
    #region Rule Data
    
    private class RuleData
    {
      /// <summary>
      /// MethodParameters - for MethodParameter which testing now 
      /// </summary>
      public Stack MethodParameters = new Stack();
      public RuleViolationCollection violations = new RuleViolationCollection();
      public string MemberName = "";
    }
    private class MethodParameter
    {
      /// <summary>
      /// list object where testing current MethodParameter
      /// </summary>
      public ArrayList TrowArgumentNullExceptionTrace;
      public CodeMethodParameter CodeMethodParameter;
      public bool IsToTrowArgumentNullException;

      public MethodParameter(CodeMethodParameter codeMethodParameter)
      {
        CodeMethodParameter = codeMethodParameter;
        IsToTrowArgumentNullException = false;
        TrowArgumentNullExceptionTrace = new ArrayList();
      }
    }
    /// <summary>
    /// 
    /// </summary>
    private class VariableDeclarationStatement
    {
      public bool IsExistsMethodParameterReferenceExpression;
      public CodeMethodParameterReferenceExpression MethodParameterReferenceExpression;

      public VariableDeclarationStatement(CodeMethodParameterReferenceExpression methodParameterReferenceExpression)
      {
        this.MethodParameterReferenceExpression = methodParameterReferenceExpression;
        IsExistsMethodParameterReferenceExpression = false;
      }
    }
    #endregion

    internal TestForNullArgumentBeforeReferencingRuleRule(string id, string templateId, IDictionary ruleProperties) : base(id,templateId,ruleProperties)
    {
    }
  
    public override Type[] TargetedCodeElements
    {
      get
      {
        return targetedCodeElements;
      }
    }
    
    #region  Analyze
    private RuleViolation[] AnalyzeMethod(CodeTypeMethodDeclaration methodDeclaration, RuleData ruleData)
    {
      string[] methodSignatureParameters = new string[methodDeclaration.Parameters.Count];
      int index = 0;
      string methodSignature = CodeTypeReferenceUtils.GetShortestTypeNameReference( methodDeclaration.DeclaringType, methodDeclaration.DeclaringType.FullName) + ((methodDeclaration.Name == ".ctor") ? "" : "." + methodDeclaration.Name ) +"(";
      foreach(CodeMethodParameter parameter in methodDeclaration.Parameters)
      {
        if(CheckConfigurationData(parameter))
        {
          /*
           * Search block where current parameter test for Null and 
           * exception thrown or initialize           
           * */
          MethodParameter ruleParameter = new MethodParameter(parameter);
          ruleData.MethodParameters.Push(ruleParameter);
          CodeDomWalker.WalkCodeElement(methodDeclaration.Statements ,new CodeDomWalker.WalkerCallback(FindThrowArgumentNullException), ruleData);
        }

        string parameterModifier = "";
        if(parameter.Modifier == CodeMethodParameter.CodeMethodParameterModifier.Out)
        {
          parameterModifier = "out";
        }
        else if(parameter.Modifier == CodeMethodParameter.CodeMethodParameterModifier.Ref)
        {
          parameterModifier = "ref";
        }
        methodSignatureParameters[index++] = parameterModifier +" "+ parameter.Type.TypeName +" "+ parameter.Name;
      }
      methodSignature += String.Join(", ", methodSignatureParameters)+ ")";

      /*
       * Search all CodeMethodParameterReferenceExpression in current Method
       * */
      CodeDomWalker.WalkCodeElement(methodDeclaration.Statements ,new CodeDomWalker.WalkerCallback(TypeMethodDeclarationAnalyzer), ruleData);

      ArrayList violationMethodParameterListInMethod = new ArrayList();
      for(int i = 0; i < ruleData.violations.Count ; i++)
      {
        RuleViolation violation = ruleData.violations[i];
        CodeMethodParameterReferenceExpression parameterReference = violation.ViolationData["MethodParameterReferenceExpression"] as CodeMethodParameterReferenceExpression;
        /*
         * If exists several violation for parameter leave only one
         * */
        if(violationMethodParameterListInMethod.Contains(parameterReference.MethodParameter))
        {
          ruleData.violations.RemoveAt(ruleData.violations.IndexOf(violation));
          i--;
          continue;
        }
        else
        {
          violationMethodParameterListInMethod.Add(parameterReference.MethodParameter);
        }

        RuleViolationCorrection violationCorrection;
        violation.ViolationData["TypeMethodDeclaration"] = methodDeclaration;

        violation.ViolationData["TypeMethodDeclarationSignature"] = methodSignature;
        if(this.ParamAndMessageConstructor)
        {
          violationCorrection = violation.AddCorrection(ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Violation|ParamNameAndMessage"), this.ParamAndMessageDefault , false);
        }
        if(this.ParamNameConstructor)
        {
          violationCorrection = violation.AddCorrection(ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Violation|ParamName"), this.ParamNameDefault , false);
        }
      }
      if(ruleData.violations.Count != 0)
        return ruleData.violations.ToArray();
      else
        return emptyViolationsList;
    }
    
    private RuleViolation[] AnalyzeIndexer(CodeTypeIndexerDeclaration indexerDeclaration, RuleData ruleData)
    {
      string[] methodSignatureParameters = new string[indexerDeclaration.Parameters.Count];
      int index = 0;
      string methodSignature = CodeTypeReferenceUtils.GetShortestTypeNameReference(indexerDeclaration.DeclaringType, indexerDeclaration.DeclaringType.FullName) + ".this[";
      foreach(CodeMethodParameter parameter in indexerDeclaration.Parameters)
      {
        if(CheckConfigurationData(parameter))
        {
          /*
           * Search block where current parameter test for Null and 
           * exception thrown or initialize           
           * */
          MethodParameter ruleParameter = new MethodParameter(parameter);
          ruleData.MethodParameters.Push(ruleParameter);
          CodeDomWalker.WalkCodeElement(indexerDeclaration.SetAccessorStatements ,new CodeDomWalker.WalkerCallback(FindThrowArgumentNullException), ruleData);
          CodeDomWalker.WalkCodeElement(indexerDeclaration.GetAccessorStatements ,new CodeDomWalker.WalkerCallback(FindThrowArgumentNullException), ruleData);
        }

        methodSignatureParameters[index++] = parameter.Type.TypeName +" "+ parameter.Name;
      }
      methodSignature += String.Join(", ", methodSignatureParameters)+ "]";

      /*
       * Search all CodeMethodParameterReferenceExpression in current Method
       * */
      CodeDomWalker.WalkCodeElement(indexerDeclaration.SetAccessorStatements ,new CodeDomWalker.WalkerCallback(TypeMethodDeclarationAnalyzer), ruleData);
      CodeDomWalker.WalkCodeElement(indexerDeclaration.GetAccessorStatements ,new CodeDomWalker.WalkerCallback(TypeMethodDeclarationAnalyzer), ruleData);

      ArrayList violationMethodParameterListInIndexerGet = new ArrayList();
      ArrayList violationMethodParameterListInIndexerSet = new ArrayList();
      for(int i = 0; i < ruleData.violations.Count ; i++)
      {
        RuleViolation violation = ruleData.violations[i];
        CodeMethodParameterReferenceExpression parameterReference = violation.ViolationData["MethodParameterReferenceExpression"] as CodeMethodParameterReferenceExpression;
        /*
         * If exists several violation for parameter leave only one
         * */
        string indexerBlock = violation.ViolationData["IndexerBlockStatement"] as string;
        if(indexerBlock == "GET")
        {
          if(violationMethodParameterListInIndexerGet.Contains(parameterReference.MethodParameter))
          {
            ruleData.violations.RemoveAt(ruleData.violations.IndexOf(violation));
            i--;
            continue;
          }
          else
          {
            violationMethodParameterListInIndexerGet.Add(parameterReference.MethodParameter);
          }
        }
        if(indexerBlock == "SET")
        {
          if(violationMethodParameterListInIndexerSet.Contains(parameterReference.MethodParameter))
          {
            ruleData.violations.RemoveAt(ruleData.violations.IndexOf(violation));
            i--;
            continue;
          }
          else
          {
            violationMethodParameterListInIndexerSet.Add(parameterReference.MethodParameter);
          }
        }
        RuleViolationCorrection violationCorrection;
        violation.ViolationData["TypeMethodDeclaration"] = indexerDeclaration;

        violation.ViolationData["TypeMethodDeclarationSignature"] = methodSignature;
        
        if(this.ParamAndMessageConstructor)
        {
          violationCorrection = violation.AddCorrection(ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Violation|ParamNameAndMessage"), this.ParamAndMessageDefault , false);
        }
        if(this.ParamNameConstructor)
        {
          violationCorrection = violation.AddCorrection(ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Violation|ParamName"), this.ParamNameDefault , false);
        }
      }
      if(ruleData.violations.Count != 0)
        return ruleData.violations.ToArray();
      else
        return emptyViolationsList;
    }


    private RuleViolation[] AnalyzeProperty(CodeTypePropertyDeclaration propertyDeclaration, RuleData ruleData)
    {
      #region Analize Type
      string parameterTypeInfoFullName = "";
      if(propertyDeclaration.ReturnType.TypeInfo != null)
      {
        parameterTypeInfoFullName = propertyDeclaration.ReturnType.TypeInfo.FullName;
      }
      else return emptyViolationsList;

      if(propertyDeclaration.GetAssemblyTypeManager().IsTypeSubclassOf(parameterTypeInfoFullName,typeof(ValueType).FullName))
      {
        return emptyViolationsList;
      }
      #endregion
      MethodParameter ruleParameter = new MethodParameter(null);
      ruleData.MethodParameters.Push(ruleParameter);
      CodeDomWalker.WalkCodeElement(propertyDeclaration.SetAccessorStatements ,new CodeDomWalker.WalkerCallback(FindThrowArgumentNullExceptionUnresolvedReference), ruleData);
      /*
       * Search all CodeMethodParameterReferenceExpression in current Property
       * */
  
      CodeDomWalker.WalkCodeElement(propertyDeclaration.SetAccessorStatements ,new CodeDomWalker.WalkerCallback(CodeTypePropertyDeclarationAnalyzer), ruleData);

      if(ruleData.violations.Count != 0)
      {
        RuleViolation violation = ruleData.violations[0];

        RuleViolationCorrection violationCorrection;
        violation.ViolationData["TypeMethodDeclaration"] = propertyDeclaration;
        string methodSignature = "";
        if(propertyDeclaration is CodeTypeIndexerDeclaration)
        {
          CodeTypeIndexerDeclaration indexerDeclaration = propertyDeclaration as CodeTypeIndexerDeclaration;

          string[] methodSignatureParameters = new string[indexerDeclaration.Parameters.Count];
          int index = 0;
          methodSignature = CodeTypeReferenceUtils.GetShortestTypeNameReference(indexerDeclaration.DeclaringType, indexerDeclaration.DeclaringType.FullName) + ".this[";
          foreach(CodeMethodParameter parameter in indexerDeclaration.Parameters)
          {
            methodSignatureParameters[index++] = parameter.Type.TypeName +" "+ parameter.Name;
          }
          methodSignature += String.Join(", ", methodSignatureParameters)+ "]";
        }
        else
        {
          methodSignature = propertyDeclaration.DeclaringType.FullName+"."+propertyDeclaration.Name;
        }
        violation.ViolationData["TypeMethodDeclarationSignature"] = methodSignature;
        
        if(this.ParamAndMessageConstructor)
        {
          violationCorrection = violation.AddCorrection(ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Violation|ParamNameAndMessage"), this.ParamAndMessageDefault , false);
        }
        if(this.ParamNameConstructor || violation.Corrections.Count == 0)
        {
          violationCorrection = violation.AddCorrection(ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Violation|ParamName"), this.ParamNameDefault , false);
        }
        return ruleData.violations.ToArray();
      }
      else
        return emptyViolationsList;
    }
    
    private RuleViolation[] AnalyzeEvent(CodeTypeEventDeclaration eventDeclaration, RuleData ruleData)
    {
      MethodParameter ruleParameter = new MethodParameter(null);
      ruleData.MethodParameters.Push(ruleParameter);
      CodeDomWalker.WalkCodeElement(eventDeclaration.RemoveAccessorStatements ,new CodeDomWalker.WalkerCallback(FindThrowArgumentNullExceptionUnresolvedReference), ruleData);
      CodeDomWalker.WalkCodeElement(eventDeclaration.AddAccessorStatements ,new CodeDomWalker.WalkerCallback(FindThrowArgumentNullExceptionUnresolvedReference), ruleData);
      /*
       * Search all CodeMethodParameterReferenceExpression in current Property
       * */
      CodeDomWalker.WalkCodeElement(eventDeclaration.RemoveAccessorStatements ,new CodeDomWalker.WalkerCallback(CodeTypePropertyDeclarationAnalyzer), ruleData);
      CodeDomWalker.WalkCodeElement(eventDeclaration.AddAccessorStatements ,new CodeDomWalker.WalkerCallback(CodeTypePropertyDeclarationAnalyzer), ruleData);

      bool addAccessorBlock = false;
      bool removeAccessorBlock = false;
      for(int i = 0; i < ruleData.violations.Count ; i++)
      {
        RuleViolation violation = ruleData.violations[i];
        string indexerBlock = violation.ViolationData["IndexerBlockStatement"] as string;

        if(indexerBlock == "ADD")
        {
          if(addAccessorBlock)
          {
            ruleData.violations.RemoveAt(ruleData.violations.IndexOf(violation));
            i--;
            continue;
          }
          else
          {
            addAccessorBlock = true;
          }
        }
        if(indexerBlock == "REMOVE")
        {
          if(removeAccessorBlock)
          {
            ruleData.violations.RemoveAt(ruleData.violations.IndexOf(violation));
            i--;
            continue;
          }
          else
          {
            removeAccessorBlock = true;
          }
        }

        RuleViolationCorrection violationCorrection;
        violation.ViolationData["TypeMethodDeclaration"] = eventDeclaration;

        violation.ViolationData["TypeMethodDeclarationSignature"] = eventDeclaration.DeclaringType.FullName+"."+eventDeclaration.Name;
        
        if(this.ParamAndMessageConstructor)
        {
          violationCorrection = violation.AddCorrection(ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Violation|ParamNameAndMessage"), this.ParamAndMessageDefault , false);
        }
        if(this.ParamNameConstructor)
        {
          violationCorrection = violation.AddCorrection(ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Violation|ParamName"), this.ParamNameDefault , false);
        }
      }
      if(ruleData.violations.Count != 0)
      {
        return ruleData.violations.ToArray();
      }
      else
        return emptyViolationsList;
    }

    public override RuleViolation[] Analyze(object codeElement, System.Threading.ManualResetEvent cancelAnalysisEvent)
    {
      // Serge, I commented lines bellow because we are using applicability scope for figuring
      // out which methods to analze and which one to leave alone
      if(!IsCodeElementInRuleApplicabilityScope(codeElement as CodeElement))
        return emptyViolationsList;
      

      CodeTypeMethodDeclaration methodDeclaration = codeElement as CodeTypeMethodDeclaration;
      CodeTypeIndexerDeclaration indexerDeclaration = codeElement as CodeTypeIndexerDeclaration;

      RuleData ruleData = new RuleData();
      if(methodDeclaration != null)
      {
        ruleData.MemberName = (methodDeclaration.Name == ".ctor") ? CodeTypeReferenceUtils.GetShortestTypeNameReference(methodDeclaration.DeclaringType, methodDeclaration.DeclaringType.FullName) + "." + methodDeclaration.DeclaringType.Name : CodeTypeReferenceUtils.GetShortestTypeNameReference(methodDeclaration.DeclaringType, methodDeclaration.DeclaringType.FullName) + "." + methodDeclaration.Name ;
        return AnalyzeMethod(methodDeclaration, ruleData);
      }
      else if(indexerDeclaration != null)
      {
        ruleData.MemberName = CodeTypeReferenceUtils.GetShortestTypeNameReference(indexerDeclaration.DeclaringType, indexerDeclaration.DeclaringType.FullName)+".this";
        RuleViolationCollection indexerViolation = new RuleViolationCollection();
        indexerViolation.AddRange(AnalyzeIndexer(indexerDeclaration, ruleData));

        return indexerViolation.ToArray();
      }
      else if(codeElement is CodeTypePropertyDeclaration)
      {
        CodeTypePropertyDeclaration propertyDeclaration = codeElement as CodeTypePropertyDeclaration;
        ruleData.MemberName = CodeTypeReferenceUtils.GetShortestTypeNameReference(propertyDeclaration.DeclaringType, propertyDeclaration.DeclaringType.FullName) + "." + propertyDeclaration.Name;

        return AnalyzeProperty(propertyDeclaration, ruleData);
      }
      else if(codeElement is CodeTypeEventDeclaration)
      {
        CodeTypeEventDeclaration eventDeclaration = codeElement as CodeTypeEventDeclaration;
        ruleData.MemberName = CodeTypeReferenceUtils.GetShortestTypeNameReference(eventDeclaration.DeclaringType, eventDeclaration.DeclaringType.FullName)+ "." + eventDeclaration.Name;
        return AnalyzeEvent(eventDeclaration, ruleData);
      }
      else
      {
        return emptyViolationsList;
      }
    }  
    private CodeDomWalker.WalkerCallbackReturn FindThrowArgumentNullExceptionUnresolvedReference(CodeElement codeElement, CodeDomWalker.CallBackNotificationType notificationType, CodeDomWalkerContext walkerContext,object applicationData)
    {
      if(notificationType != CodeDomWalker.CallBackNotificationType.OnElement)
      {
        return CodeDomWalker.WalkerCallbackReturn.Next;
      }
      
      CodeIfStatement codeIfStatement = codeElement as CodeIfStatement;
      if(codeIfStatement != null )
      {
        CodeExpression expression = codeIfStatement.Condition;
        if(expression is CodeParenthesizedExpression)
        {
          expression =(expression as CodeParenthesizedExpression).Expression;
        }
        if(expression is CodeBinaryExpression)
        {
          RuleData ruleData = applicationData as RuleData;
          MethodParameter ruleParameter = ruleData.MethodParameters.Peek() as MethodParameter;
          if(TrowArgumentNullExceptionUnresolvedReference((CodeBinaryExpression)expression))
          {
            ruleParameter.TrowArgumentNullExceptionTrace.Add(codeElement);
          }
        }
      }
      return CodeDomWalker.WalkerCallbackReturn.Next;
    }    

    private bool CheckConfigurationData(CodeMethodParameter parameter)
    {
      // test parameter for simple type : if simple type (int, bool, ...) skip current parameter
      string parameterTypeInfoFullName = "";
      if(parameter.Type.TypeInfo != null)
      {
        parameterTypeInfoFullName = parameter.Type.TypeInfo.FullName;
      }
      else
      {
        return false;
      }
      if(parameter.GetAssemblyTypeManager().IsTypeSubclassOf(parameterTypeInfoFullName,typeof(ValueType).FullName))
      {
        return false;
      }
      /// if parameter is Array
      if(parameter.IsParameterArray)
      {
        return false;
      }
      // test for Modifier : if ref/out skip current parameter
      if(parameter.Modifier == CodeMethodParameter.CodeMethodParameterModifier.Out || parameter.Modifier == CodeMethodParameter.CodeMethodParameterModifier.Ref)
      {
        return false;
      }
      return true;
    }
    

    private CodeDomWalker.WalkerCallbackReturn FindThrowArgumentNullException(CodeElement codeElement,CodeDomWalker.CallBackNotificationType notificationType, CodeDomWalkerContext walkerContext,object applicationData)
    {
      if(notificationType != CodeDomWalker.CallBackNotificationType.OnElement)
      {
        return CodeDomWalker.WalkerCallbackReturn.Next;
      }
      
      CodeIfStatement codeIfStatement = codeElement as CodeIfStatement;
      if(codeIfStatement != null )
      {
        CodeExpression expression = codeIfStatement.Condition;
        if(expression is CodeParenthesizedExpression)
        {
          expression =(expression as CodeParenthesizedExpression).Expression;
        }
        if(expression is CodeBinaryExpression)
        {
          RuleData ruleData = applicationData as RuleData;
          MethodParameter ruleParameter = ruleData.MethodParameters.Peek() as MethodParameter;
          CodeMethodParameter codeMethodParameter = TrowArgumentNullException((CodeBinaryExpression)expression);
          if(codeMethodParameter == ruleParameter.CodeMethodParameter)
          {
            ruleParameter.TrowArgumentNullExceptionTrace.Add(codeElement);
          }
        }
      }
      return CodeDomWalker.WalkerCallbackReturn.Next;
    }    

    
    private CodeDomWalker.WalkerCallbackReturn CodeTypePropertyDeclarationAnalyzer(CodeElement codeElement,CodeDomWalker.CallBackNotificationType notificationType, CodeDomWalkerContext walkerContext,object applicationData)
    {
      CodeMethodParameterReferenceExpression unresolvedReference = codeElement as CodeMethodParameterReferenceExpression;
      RuleData ruleData = applicationData as RuleData;
      if(unresolvedReference != null && notificationType == CodeDomWalker.CallBackNotificationType.OnElement )
      {
        #region create list with code elements 
        ArrayList listElement = new ArrayList();
        System.Collections.IEnumerator ruleDataEnumerator = ruleData.MethodParameters.GetEnumerator();
        while( ruleDataEnumerator.MoveNext() )
        {
          MethodParameter mParameter = ruleDataEnumerator.Current as MethodParameter;
          if( mParameter.CodeMethodParameter == null )
          {
            listElement = mParameter.TrowArgumentNullExceptionTrace;
          }
        }
        #endregion
        if(unresolvedReference.Parent is CodeBinaryExpression 
          && ((unresolvedReference.Parent as CodeBinaryExpression).Operator == CodeBinaryOperatorType.Equality || (unresolvedReference.Parent as CodeBinaryExpression).Operator == CodeBinaryOperatorType.Inequality)
          )
        {
          return CodeDomWalker.WalkerCallbackReturn.Next;
        }
        #region Check if parameter is compared to null. If yes - clear violations and exit. Developers thought of this case
        CodeExpression parameterReferenceExpression = unresolvedReference;
        
        //Skip parethethies
        while(parameterReferenceExpression.Parent is CodeParenthesizedExpression)
          parameterReferenceExpression = parameterReferenceExpression.Parent as CodeExpression;

        //Check if inside comparison
        //If the condition has comparison to null - return there. After that point developer
        //evidently thought of case where parameter is null.
        if(parameterReferenceExpression.Parent is CodeBinaryExpression)
        {
          CodeBinaryExpression binaryExpression = parameterReferenceExpression.Parent as CodeBinaryExpression;
          if(binaryExpression.Operator == CodeBinaryOperatorType.Equality
            || binaryExpression.Operator == CodeBinaryOperatorType.Inequality)
          {
            if(binaryExpression.RightOperand is CodeNullReferenceExpression || binaryExpression.LeftOperand is CodeNullReferenceExpression)
              return CodeDomWalker.WalkerCallbackReturn.Cancel;
          }
        }
        #endregion
        CodeElementTrace trace = CodeElementTrace.GetCodeElementTrace(codeElement);
        
        string indexerBlockStatement = "";
        for(int traceFrameIndex = trace.Trace.Length-1;traceFrameIndex>=0; traceFrameIndex--)
        {
          #region CodeIfStatement Analize
          // if exists testing for null in parent elements
          if(trace.Trace[traceFrameIndex] is CodeIfStatement )
          {
            CodeIfStatement ifStatement = trace.Trace[traceFrameIndex] as CodeIfStatement;
            CodeStatement statement = trace.Trace[traceFrameIndex + 1] as CodeStatement;
            if(statement == null) continue;

            if(CheckExpression(ifStatement.Condition, unresolvedReference, statement.Equals(ifStatement.TrueStatement)))
            {
              return CodeDomWalker.WalkerCallbackReturn.Next;
            }
          }
          #endregion
          #region CodeConditionalExpression Analize
          if(trace.Trace[traceFrameIndex] is CodeConditionalExpression )
          {
            CodeConditionalExpression conditionalExpression = trace.Trace[traceFrameIndex] as CodeConditionalExpression;
            CodeExpression expression = conditionalExpression.Condition;
            if(expression is CodeParenthesizedExpression)
            {
              expression = (expression as CodeParenthesizedExpression).Expression;
            }
            if(expression is CodeBinaryExpression)
            {
              CodeExpression codeExpression = trace.Trace[traceFrameIndex + 1] as CodeExpression;
              if(CheckCodeBinaryExpressionUnresolvedReference(unresolvedReference, (CodeBinaryExpression)expression, codeExpression.Equals(conditionalExpression.TrueExpression)))
              {
                return CodeDomWalker.WalkerCallbackReturn.Next;
              }
            }
          }
          #endregion
          #region CodeTryStatement Analize
          if(trace.Trace[traceFrameIndex] is CodeTryStatement && trace.Trace[traceFrameIndex + 1] is CodeStatementBlock)
          {
            CodeTryStatement tryStatement = trace.Trace[traceFrameIndex] as CodeTryStatement;
            foreach(CodeCatchClause catchClause in tryStatement.CatchClauses)
            {
              CodeAssemblyTypeManager typeManager = tryStatement.GetAssemblyTypeManager();
              if(catchClause.CatchExceptionType != null && catchClause.CatchExceptionType.TypeInfo != null)
              {
                if( typeManager.IsTypeSubclassOf(catchClause.CatchExceptionType.TypeInfo.FullName, "System.ArgumentNullException") )
                {
                  return CodeDomWalker.WalkerCallbackReturn.Next;
                }
              }
            }
          }
          #endregion
          #region CodeStatementBlock Analize
          if(trace.Trace[traceFrameIndex] is CodeStatementBlock)
          {
            foreach(CodeElement traceElement in (trace.Trace[traceFrameIndex] as CodeStatementBlock).Statements )
            {
              if(listElement.Contains(traceElement))
              {
                return CodeDomWalker.WalkerCallbackReturn.Next;
              }
              if(trace.Trace[traceFrameIndex+1] == traceElement)
                break;
            }
          }
          #endregion
          
        if(trace.Trace[traceFrameIndex] is CodeTypeMethodDeclaration)
            break;

          if(trace.Trace[traceFrameIndex] is CodeTypeIndexerDeclaration )
          {
            indexerBlockStatement = (trace.Trace[traceFrameIndex+1] == (trace.Trace[traceFrameIndex] as CodeTypeIndexerDeclaration).SetAccessorStatements)?"SET":"GET";
            break;
          }
          
          if(trace.Trace[traceFrameIndex] is CodeTypePropertyDeclaration)
          {
            indexerBlockStatement = (trace.Trace[traceFrameIndex+1] == (trace.Trace[traceFrameIndex] as CodeTypePropertyDeclaration).SetAccessorStatements)?"SET":"GET";
            break;
          }

          if(trace.Trace[traceFrameIndex] is CodeTypeEventDeclaration)
          {
            indexerBlockStatement = (trace.Trace[traceFrameIndex+1] == (trace.Trace[traceFrameIndex] as CodeTypeEventDeclaration).AddAccessorStatements)?"ADD":"REMOVE";
            break;
          }
        }
        
        if(!isParameterUsedAsTargetInReference(unresolvedReference))
        {return CodeDomWalker.WalkerCallbackReturn.Next;}

        RuleViolation violation = new RuleViolation(this, unresolvedReference);
        violation.Description = String.Format(ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Violation|Description"), "value", ruleData.MemberName);
        
        violation.Severity = RuleViolation.ViolationSeverity.Warning;
        violation.ViolationData["MethodParameterReferenceExpression"] = unresolvedReference;
        violation.ViolationData["IndexerBlockStatement"] = indexerBlockStatement;

        ruleData.violations.Add(violation);
      }
      return CodeDomWalker.WalkerCallbackReturn.Next;
    }
    private bool AnalizeBinaryExcpression(CodeBinaryExpression binary, CodeMethodParameterReferenceExpression parameterReference)
    {
      if(binary.RightOperand == parameterReference
        && binary.Operator == CodeBinaryOperatorType.Assign)
        return true;
      return false;
    }
    private CodeDomWalker.WalkerCallbackReturn TypeMethodDeclarationAnalyzer(CodeElement codeElement,CodeDomWalker.CallBackNotificationType notificationType, CodeDomWalkerContext walkerContext,object applicationData)
    {
      CodeMethodParameterReferenceExpression parameterReference = codeElement as CodeMethodParameterReferenceExpression;
      RuleData ruleData = applicationData as RuleData;
      
      if(parameterReference != null && parameterReference.MethodParameter != null && notificationType == CodeDomWalker.CallBackNotificationType.OnElement )
      {
        #region create list with code elements 
        ArrayList listElement = new ArrayList();
        System.Collections.IEnumerator ruleDataEnumerator = ruleData.MethodParameters.GetEnumerator();
        while( ruleDataEnumerator.MoveNext() )
        {
          MethodParameter mParameter = ruleDataEnumerator.Current as MethodParameter;
          if( mParameter.CodeMethodParameter == parameterReference.MethodParameter )
          {
            listElement = mParameter.TrowArgumentNullExceptionTrace;
          }
        }
        #endregion
        
        if(!CheckConfigurationData(parameterReference.MethodParameter))
          return CodeDomWalker.WalkerCallbackReturn.Next;
          
        #region Check if parameter is compared to null. If yes - clear violations and exit. Developers thought of this case
        CodeExpression parameterReferenceExpression = parameterReference;
        
        //Skip parethethies
        while(parameterReferenceExpression.Parent is CodeParenthesizedExpression)
          parameterReferenceExpression = parameterReferenceExpression.Parent as CodeExpression;

        //Check if inside comparison
        //If the condition has comparison to null - return there. After that point developer
        //evidently thought of case where parameter is null.
        if(parameterReferenceExpression.Parent is CodeBinaryExpression)
        {
          CodeBinaryExpression binaryExpression = parameterReferenceExpression.Parent as CodeBinaryExpression;
          if(binaryExpression.Operator == CodeBinaryOperatorType.Equality
            || binaryExpression.Operator == CodeBinaryOperatorType.Inequality)
          {
            if(binaryExpression.RightOperand is CodeNullReferenceExpression || binaryExpression.LeftOperand is CodeNullReferenceExpression)
              return CodeDomWalker.WalkerCallbackReturn.Cancel;
          }
        }
        #endregion
        if(parameterReference.Parent is CodeBinaryExpression 
          && ((parameterReference.Parent as CodeBinaryExpression).Operator == CodeBinaryOperatorType.Equality 
          || (parameterReference.Parent as CodeBinaryExpression).Operator == CodeBinaryOperatorType.Inequality
          || (parameterReference.Parent as CodeBinaryExpression).Operator == CodeBinaryOperatorType.Is)
        )
        {
          return CodeDomWalker.WalkerCallbackReturn.Next;
        }
        CodeElementTrace trace = CodeElementTrace.GetCodeElementTrace(codeElement);
        
        string indexerBlockStatement = "";
        for(int traceFrameIndex = trace.Trace.Length-1;traceFrameIndex>=0; traceFrameIndex--)
        {
          #region CodeIfStatement Analize
          if(trace.Trace[traceFrameIndex] is CodeIfStatement )
          {
            CodeIfStatement ifStatement = trace.Trace[traceFrameIndex] as CodeIfStatement;
            CodeStatement statement = trace.Trace[traceFrameIndex + 1] as CodeStatement;
            if(statement == null) continue;

            if(CheckExpression(ifStatement.Condition, parameterReference, statement.Equals(ifStatement.TrueStatement)))
            {
              return CodeDomWalker.WalkerCallbackReturn.Next;
            }
          }
          #endregion
          #region CodeConditionalExpression Analize
          if(trace.Trace[traceFrameIndex] is CodeConditionalExpression )
          {
            CodeConditionalExpression conditionalExpression = trace.Trace[traceFrameIndex] as CodeConditionalExpression;
            CodeExpression expression = conditionalExpression.Condition;
            if(expression is CodeParenthesizedExpression)
            {
              expression = (expression as CodeParenthesizedExpression).Expression;
            }
            if(expression is CodeBinaryExpression)
            {
              CodeExpression codeExpression = trace.Trace[traceFrameIndex + 1] as CodeExpression;
              if(CheckCodeBinaryExpression(parameterReference, (CodeBinaryExpression)expression, codeExpression.Equals(conditionalExpression.TrueExpression)))
              {
                return CodeDomWalker.WalkerCallbackReturn.Next;
              }
            }
          }
          #endregion
          #region CodeTryStatement Analize
          if(trace.Trace[traceFrameIndex] is CodeTryStatement && trace.Trace[traceFrameIndex + 1] is CodeStatementBlock)
          {
            CodeTryStatement tryStatement = trace.Trace[traceFrameIndex] as CodeTryStatement;
            foreach(CodeCatchClause catchClause in tryStatement.CatchClauses)
            {
              CodeAssemblyTypeManager typeManager = tryStatement.GetAssemblyTypeManager();
              if(catchClause.CatchExceptionType != null && catchClause.CatchExceptionType.TypeInfo != null)
              {
                if( typeManager.IsTypeSubclassOf(catchClause.CatchExceptionType.TypeInfo.FullName, "System.ArgumentNullException") )
                {
                  return CodeDomWalker.WalkerCallbackReturn.Next;
                }
              }
            }
          }
          #endregion
          #region CodeStatementBlock Analize
          if(trace.Trace[traceFrameIndex] is CodeStatementBlock)
          {
            foreach(CodeElement traceElement in (trace.Trace[traceFrameIndex] as CodeStatementBlock).Statements )
            {
              if(listElement.Contains(traceElement))
              {
                return CodeDomWalker.WalkerCallbackReturn.Next;
              }
              if(trace.Trace[traceFrameIndex+1] == traceElement)
                break;
            }
          }
          #endregion
          if(trace.Trace[traceFrameIndex] is CodeTypeMethodDeclaration)
            break;
          if(trace.Trace[traceFrameIndex] is CodeTypeIndexerDeclaration)
          {
            indexerBlockStatement = (trace.Trace[traceFrameIndex+1] == (trace.Trace[traceFrameIndex] as CodeTypeIndexerDeclaration).SetAccessorStatements)?"SET":"GET";
            break;
          }
        }
        if(!isParameterUsedAsTargetInReference(parameterReference))
        {return CodeDomWalker.WalkerCallbackReturn.Next;}

        RuleViolation violation = new RuleViolation(this,  parameterReference);
        violation.Description = String.Format(ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Violation|Description"), parameterReference.ParameterName, ruleData.MemberName);
        
        violation.Severity = RuleViolation.ViolationSeverity.Warning;
        violation.ViolationData["MethodParameterReferenceExpression"] = parameterReference;
        violation.ViolationData["IndexerBlockStatement"] = indexerBlockStatement;

        ruleData.violations.Add(violation);
      }
      return CodeDomWalker.WalkerCallbackReturn.Next;
    }
    private bool isParameterUsedAsTargetInReference(CodeElement parameterReference)
    {
      CodeElement child = parameterReference;
      //skip parenthethies and type casts
      while(
        child.Parent is CodeParenthesizedExpression || 
        child.Parent is CodeTypeCastExpression ||
        (child.Parent is CodeBinaryExpression && ((child.Parent as CodeBinaryExpression).Operator == CodeBinaryOperatorType.As)))
      {
        child = child.Parent;
      }

      if((child.Parent is CodeNamedReferenceExpression)
        && (child.Parent as CodeNamedReferenceExpression).TargetObject == child)
      {
        return true;
      }
      if(parameterReference.Parent is CodeIndexerInvokeExpression)
      {
        return true;
      }

      return false;
    }
    private bool CheckExpression(CodeExpression condition, CodeMethodParameterReferenceExpression parameterReference, bool trueBlock)
    {
      if(condition is CodeParenthesizedExpression)
      {
        condition = (condition as CodeParenthesizedExpression).Expression;  
      }
      if(condition is CodeBinaryExpression)
      {
        CodeBinaryExpression binary = condition as CodeBinaryExpression;
        CodeExpression leftOperand = binary.LeftOperand;
        if(leftOperand is CodeParenthesizedExpression) leftOperand = (leftOperand as CodeParenthesizedExpression).Expression;        
        
        CodeExpression rightOperand = binary.RightOperand;
        if(rightOperand is CodeParenthesizedExpression) rightOperand = (rightOperand as CodeParenthesizedExpression).Expression;        
        
        if(leftOperand is CodeBinaryExpression && rightOperand is CodeBinaryExpression)
        {
          if(binary.Operator == CodeBinaryOperatorType.LogicalOr)
          {
            return (CheckExpression(leftOperand, parameterReference, trueBlock) && CheckExpression(rightOperand, parameterReference, trueBlock));
          }
          if(binary.Operator == CodeBinaryOperatorType.LogicalAnd)
          {
            return (CheckExpression(leftOperand, parameterReference, trueBlock) || CheckExpression(rightOperand, parameterReference, trueBlock));
          }
        }
        else
        {
          return CheckCodeBinaryExpression(parameterReference, binary, trueBlock);
        }
      }
      return false;
  
    }
    #region Analize CodeIf statement for intricate variant: if(arg != null && arg.Lenght != 0) and other
    private class ifStatementCondiotion
    {
      public CodeMethodParameterReferenceExpression ParameterReference;
      public CodeBinaryOperatorType CheckType = CodeBinaryOperatorType.Inequality;
      public bool TestForInEqualityNull = false;
    }
    
    private bool CheckCodeIfStatement(CodeMethodParameterReferenceExpression parameterReference, CodeIfStatement ifStatement, CodeStatement statement)
    {
      ifStatementCondiotion conditionData = new ifStatementCondiotion();
      conditionData.ParameterReference = parameterReference;
      if(statement != null)
      {
        conditionData.CheckType =( !statement.Equals(ifStatement.TrueStatement))?CodeBinaryOperatorType.Equality:CodeBinaryOperatorType.Inequality;
      }

      CodeDomWalker.WalkCodeElement(ifStatement.Condition, new CodeDomWalker.WalkerCallback(CheckIfStatementCondition), conditionData);

      return conditionData.TestForInEqualityNull;
    }
    
    private CodeDomWalker.WalkerCallbackReturn CheckIfStatementCondition(CodeElement codeElement, CodeDomWalker.CallBackNotificationType notificationType, CodeDomWalkerContext walkerContext,object applicationData)
    {
      if(notificationType != CodeDomWalker.CallBackNotificationType.OnElement)
      {
        return CodeDomWalker.WalkerCallbackReturn.Next;
      }
      if(codeElement is CodeBinaryExpression)
      {
        CodeBinaryExpression binary = codeElement as CodeBinaryExpression;
        ifStatementCondiotion conditionData = applicationData as ifStatementCondiotion;

        if((binary.Operator == conditionData.CheckType
          && binary.LeftOperand is CodeMethodParameterReferenceExpression
          && binary.RightOperand is CodeNullReferenceExpression)
          ||
          (binary.Operator == conditionData.CheckType
          && binary.RightOperand is CodeMethodParameterReferenceExpression
          && binary.LeftOperand is CodeNullReferenceExpression)
          )
        {
          if(conditionData.ParameterReference.ParameterName == (binary.LeftOperand as CodeMethodParameterReferenceExpression).ParameterName)
            conditionData.TestForInEqualityNull = true;
        }
      }
      return CodeDomWalker.WalkerCallbackReturn.Next;
    }
    #endregion
    
    private bool CheckCodeBinaryExpression(CodeMethodParameterReferenceExpression parameterReference, CodeBinaryExpression binaryExpression, bool trueBlock)
    {
      bool contentsParameterReferenceAndNull = false;
      if(binaryExpression.Operator == CodeBinaryOperatorType.Is
        && binaryExpression.LeftOperand is CodeMethodParameterReferenceExpression
        && binaryExpression.RightOperand is CodeTypeReferenceExpression
        )
      {
        return trueBlock;
      }
      if(binaryExpression.LeftOperand is CodeMethodParameterReferenceExpression)
      {
        if((binaryExpression.LeftOperand as CodeMethodParameterReferenceExpression).MethodParameter == parameterReference.MethodParameter && binaryExpression.RightOperand is CodeNullReferenceExpression)
        {
          contentsParameterReferenceAndNull = true;  
        }
      }
      if(binaryExpression.RightOperand is CodeMethodParameterReferenceExpression)
      {
        if((binaryExpression.RightOperand as CodeMethodParameterReferenceExpression).MethodParameter == parameterReference.MethodParameter && binaryExpression.LeftOperand is CodeNullReferenceExpression)
        {
          contentsParameterReferenceAndNull = true;  
        }
      }
      if(!contentsParameterReferenceAndNull) 
        return false;

      if( (binaryExpression.Operator == CodeBinaryOperatorType.Inequality && trueBlock)
        ||
        (binaryExpression.Operator == CodeBinaryOperatorType.Equality && !trueBlock )
        )
      {
        return true;
      }
      return false;
    }
    
    private bool CheckCodeBinaryExpressionUnresolvedReference(CodeMethodParameterReferenceExpression parameterReference, CodeBinaryExpression binaryExpression, bool trueBlock)
    {
      bool contentsParameterReferenceAndNull = false;
      if(binaryExpression.LeftOperand is CodeMethodParameterReferenceExpression && (binaryExpression.LeftOperand as CodeMethodParameterReferenceExpression).ParameterName == "value")
      {
        contentsParameterReferenceAndNull = true;  
      }
      if(binaryExpression.RightOperand is CodeMethodParameterReferenceExpression && (binaryExpression.RightOperand as CodeMethodParameterReferenceExpression).ParameterName == "value")
      {
        contentsParameterReferenceAndNull = true;  
      }
      if(!contentsParameterReferenceAndNull) 
        return false;

      if( (binaryExpression.Operator == CodeBinaryOperatorType.Inequality && trueBlock)
        ||
        (binaryExpression.Operator == CodeBinaryOperatorType.Equality && !trueBlock )
        )
      {
        return true;
      }
      return false;
    }
    
    private bool CheckCodeBinaryExceptionAssign(CodeMethodParameter parameter, CodeBinaryExpression binaryExpression)
    {
      // testing on initialize current parameter
      if(binaryExpression.Operator == CodeBinaryOperatorType.Assign)
      {
        if(binaryExpression.LeftOperand is CodeMethodParameterReferenceExpression 
          &&
          (binaryExpression.LeftOperand as CodeMethodParameterReferenceExpression).MethodParameter == parameter
          )
        {
          return true;                      
        }
      }
      return false;
    }
    private bool TrowArgumentNullExceptionUnresolvedReference(CodeBinaryExpression binaryExpression)
    {
      #region find UnresolvedReferenceAndNull 
      bool contentsParameterReferenceAndNull = false;
      if(binaryExpression.LeftOperand is CodeMethodParameterReferenceExpression && (binaryExpression.LeftOperand as CodeMethodParameterReferenceExpression).ParameterName == "value" && binaryExpression.RightOperand is CodeNullReferenceExpression)
      {
        contentsParameterReferenceAndNull = true;  
      }
      if(binaryExpression.RightOperand is CodeMethodParameterReferenceExpression && (binaryExpression.RightOperand as CodeMethodParameterReferenceExpression).ParameterName == "value" && binaryExpression.LeftOperand is CodeNullReferenceExpression)
      {
        contentsParameterReferenceAndNull = true;  
      }

      if(!contentsParameterReferenceAndNull) 
        return false;
      #endregion

      MethodParameter ifStatementData = new MethodParameter(null);
      
      CodeIfStatement codeIfStatement;
      if(binaryExpression.Parent is CodeParenthesizedExpression)
      {
        codeIfStatement = binaryExpression.Parent.Parent as CodeIfStatement;
      }
      else
      {
        codeIfStatement = binaryExpression.Parent as CodeIfStatement;
      }
      
      if( binaryExpression.Operator == CodeBinaryOperatorType.Equality )
      {
        CodeDomWalker.WalkCodeElement( codeIfStatement.TrueStatement ,new CodeDomWalker.WalkerCallback(CodeIfStatementAnalyzer), ifStatementData);
      }
      else
      {
        CodeDomWalker.WalkCodeElement( codeIfStatement.FalseStatement ,new CodeDomWalker.WalkerCallback(CodeIfStatementAnalyzer), ifStatementData);
      }
      return ifStatementData.IsToTrowArgumentNullException;
    }

    private CodeMethodParameter TrowArgumentNullException(CodeBinaryExpression binaryExpression)
    {
      #region find ParameterReferenceAndNull 
      bool contentsParameterReferenceAndNull = false;
      CodeMethodParameter methodParameter = null;
      if(binaryExpression.LeftOperand is CodeMethodParameterReferenceExpression && binaryExpression.RightOperand is CodeNullReferenceExpression)
      {
        methodParameter = (binaryExpression.LeftOperand as CodeMethodParameterReferenceExpression).MethodParameter;
        contentsParameterReferenceAndNull = true;  
      }
      if(binaryExpression.RightOperand is CodeMethodParameterReferenceExpression && binaryExpression.LeftOperand is CodeNullReferenceExpression)
      {
        methodParameter = (binaryExpression.RightOperand as CodeMethodParameterReferenceExpression).MethodParameter;
        contentsParameterReferenceAndNull = true;  
      }

      if(!contentsParameterReferenceAndNull) 
        return null;
      #endregion

      MethodParameter ifStatementData = new MethodParameter(methodParameter);
      
      CodeIfStatement codeIfStatement;
      if(binaryExpression.Parent is CodeParenthesizedExpression)
      {
        codeIfStatement = binaryExpression.Parent.Parent as CodeIfStatement;
      }
      else
      {
        codeIfStatement = binaryExpression.Parent as CodeIfStatement;
      }
      
      if( binaryExpression.Operator == CodeBinaryOperatorType.Equality )
      {
        CodeDomWalker.WalkCodeElement( codeIfStatement.TrueStatement ,new CodeDomWalker.WalkerCallback(CodeIfStatementAnalyzer), ifStatementData);
      }
      else
      {
        CodeDomWalker.WalkCodeElement( codeIfStatement.FalseStatement ,new CodeDomWalker.WalkerCallback(CodeIfStatementAnalyzer), ifStatementData);
      }
      return (ifStatementData.IsToTrowArgumentNullException)? methodParameter : null;
    }
    
    
    private CodeDomWalker.WalkerCallbackReturn CodeIfStatementAnalyzer(CodeElement codeElement,CodeDomWalker.CallBackNotificationType notificationType, CodeDomWalkerContext walkerContext,object applicationData)
    {
      if(notificationType != CodeDomWalker.CallBackNotificationType.OnElement)
        return CodeDomWalker.WalkerCallbackReturn.Next;

      MethodParameter ifSatementData = applicationData as MethodParameter;
      if(codeElement is CodeMethodParameterReferenceExpression && (codeElement as CodeMethodParameterReferenceExpression).MethodParameter == ifSatementData.CodeMethodParameter)
      {
        // testing on initialize current MethodParameter
        if(codeElement.Parent is CodeBinaryExpression )
        {
          if(CheckCodeBinaryExceptionAssign( ifSatementData.CodeMethodParameter, (CodeBinaryExpression)codeElement.Parent))
          {
            ifSatementData.IsToTrowArgumentNullException = true;                      
          }
         }
        return CodeDomWalker.WalkerCallbackReturn.Cancel;
      }
      if(codeElement is CodeThrowStatement)
      {
        // testing on throwing ArgumentNullException
        CodeObjectCreateExpression objectCreateExpression;
        if((codeElement as CodeThrowStatement).ToThrow is CodeParenthesizedExpression )
        {
          objectCreateExpression = ((codeElement as CodeThrowStatement).ToThrow as CodeParenthesizedExpression).Expression as CodeObjectCreateExpression;
        }
        else
        {
          objectCreateExpression = (codeElement as CodeThrowStatement).ToThrow as CodeObjectCreateExpression;
        }
        if(objectCreateExpression != null)
        {
          CodeAssemblyTypeManager typeManager = objectCreateExpression.GetAssemblyTypeManager();
          if(objectCreateExpression.CreateType.TypeInfo != null)
          {
            if(typeManager.IsTypeSubclassOf(objectCreateExpression.CreateType.TypeInfo.FullName, "System.ArgumentNullException"))
            {
              ifSatementData.IsToTrowArgumentNullException = true;                      
            }
          }
        }
        return CodeDomWalker.WalkerCallbackReturn.Cancel;
      }
      return CodeDomWalker.WalkerCallbackReturn.Next;
    }    
    
    #endregion  
    
    #region Correct 
    public override void Correct(RuleViolationCorrection[] requestedCorrections, AnticipatingMinds.Genesis.Effectors.CodeEffector codeEffector, System.Threading.ManualResetEvent cancelCorrectionEvent)
    {
      codeEffector.BeginCodeChanges("And If Statement");
      foreach(RuleViolationCorrection requestedCorrection in requestedCorrections)
      {
        if(requestedCorrection.Violation.IsFixed)
          continue;
        
        CodeStatementCollection ifStatementCollection = new CodeStatementCollection();
        bool isParamNameAndMessageDefault = requestedCorrection.Name.Equals(ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|Violation|ParamNameAndMessage"));
        string methodSignature = requestedCorrection.Violation.ViolationData["TypeMethodDeclarationSignature"] as string;
        CodeReferenceExpression methodExpression = requestedCorrection.Violation.ViolationData["MethodParameterReferenceExpression"] as CodeReferenceExpression;
        string parameterName;                
        
        if(requestedCorrection.Violation.ViolationData["MethodParameterReferenceExpression"] is CodeMethodParameterReferenceExpression)
        {
          parameterName = (requestedCorrection.Violation.ViolationData["MethodParameterReferenceExpression"] as CodeMethodParameterReferenceExpression).ParameterName;
        }
        else
        {
          parameterName = "value";
        }
        
        CodeMethodParameterReferenceExpression methodParameterExpression = requestedCorrection.Violation.ViolationData["MethodParameterReferenceExpression"] as CodeMethodParameterReferenceExpression;

        CodeIfStatement codeIfStatement = CreateCodeIfStatement(methodExpression, isParamNameAndMessageDefault, methodSignature, parameterName);
        
        ifStatementCollection.Add(codeIfStatement);
        if(requestedCorrection.Violation.ViolationData["TypeMethodDeclaration"] is CodeTypeMethodDeclaration)
        {
          CorrectMethod(requestedCorrection, codeEffector, ifStatementCollection);        
        }
        else if(requestedCorrection.Violation.ViolationData["TypeMethodDeclaration"] is CodeTypeIndexerDeclaration)
        {
          string indexerBlock = requestedCorrection.Violation.ViolationData["IndexerBlockStatement"] as string;
          if(indexerBlock == "GET")
            CorrectIndexerGet(requestedCorrection, codeEffector, ifStatementCollection);        
  
          if(indexerBlock == "SET")
            CorrectIndexerSet(requestedCorrection, codeEffector, ifStatementCollection);        
        }
        else if(requestedCorrection.Violation.ViolationData["TypeMethodDeclaration"] is CodeTypeEventDeclaration)
        {
          string indexerBlock = requestedCorrection.Violation.ViolationData["IndexerBlockStatement"] as string;
          if(indexerBlock == "ADD")
            CorrectEventAdd(requestedCorrection, codeEffector, ifStatementCollection);        
  
          if(indexerBlock == "REMOVE")
            CorrectEventRemove(requestedCorrection, codeEffector, ifStatementCollection);        
        }
        else if(requestedCorrection.Violation.ViolationData["TypeMethodDeclaration"] is CodeTypePropertyDeclaration)
        {
          CorrectProperty(requestedCorrection, codeEffector, ifStatementCollection);        
        }

        requestedCorrection.Violation.IsFixed = true;
      }
      try
      {
        codeEffector.CommitCodeChanges();
      }
      catch(Exception)
      {
        codeEffector.RollbackCodeChanges();
        throw;
      }
    }
    private void CorrectIndexerSet(RuleViolationCorrection requestedCorrection, AnticipatingMinds.Genesis.Effectors.CodeEffector codeEffector, CodeStatementCollection ifStatementCollection)
    {
      CodeMethodParameterReferenceExpression methodParameterExpression = requestedCorrection.Violation.ViolationData["MethodParameterReferenceExpression"] as CodeMethodParameterReferenceExpression;
      CodeTypeIndexerDeclaration indexerDeclaration = requestedCorrection.Violation.ViolationData["TypeMethodDeclaration"] as CodeTypeIndexerDeclaration;

      //Always insert at the start of the method
      codeEffector.AddCodeElements( ifStatementCollection, indexerDeclaration.SetAccessorStatements, indexerDeclaration.SetAccessorStatements.Statements, 0);
      codeEffector.PerformCodeChanges();
    }
    
    private void CorrectIndexerGet(RuleViolationCorrection requestedCorrection, AnticipatingMinds.Genesis.Effectors.CodeEffector codeEffector, CodeStatementCollection ifStatementCollection)
    {
      CodeMethodParameterReferenceExpression methodParameterExpression = requestedCorrection.Violation.ViolationData["MethodParameterReferenceExpression"] as CodeMethodParameterReferenceExpression;
      CodeTypeIndexerDeclaration indexerDeclaration = requestedCorrection.Violation.ViolationData["TypeMethodDeclaration"] as CodeTypeIndexerDeclaration;

      //Always insert at the start of the method
      codeEffector.AddCodeElements( ifStatementCollection, indexerDeclaration.GetAccessorStatements, indexerDeclaration.GetAccessorStatements.Statements, 0);
      codeEffector.PerformCodeChanges();
    }
    
    private void CorrectProperty(RuleViolationCorrection requestedCorrection, AnticipatingMinds.Genesis.Effectors.CodeEffector codeEffector, CodeStatementCollection ifStatementCollection)
    {
      CodeMethodParameterReferenceExpression methodParameterExpression = requestedCorrection.Violation.ViolationData["MethodParameterReferenceExpression"] as CodeMethodParameterReferenceExpression;
      CodeTypePropertyDeclaration propertyDeclaration = requestedCorrection.Violation.ViolationData["TypeMethodDeclaration"] as CodeTypePropertyDeclaration;

      //Always insert at the start of the method
      codeEffector.AddCodeElements( ifStatementCollection, propertyDeclaration.SetAccessorStatements, propertyDeclaration.SetAccessorStatements.Statements, 0);
      codeEffector.PerformCodeChanges();
    }

    private void CorrectEventAdd(RuleViolationCorrection requestedCorrection, AnticipatingMinds.Genesis.Effectors.CodeEffector codeEffector, CodeStatementCollection ifStatementCollection)
    {
      CodeMethodParameterReferenceExpression methodParameterExpression = requestedCorrection.Violation.ViolationData["MethodParameterReferenceExpression"] as CodeMethodParameterReferenceExpression;
      CodeTypeEventDeclaration eventDeclaration = requestedCorrection.Violation.ViolationData["TypeMethodDeclaration"] as CodeTypeEventDeclaration;

      //Always insert at the start of the method
      codeEffector.AddCodeElements( ifStatementCollection, eventDeclaration.AddAccessorStatements, eventDeclaration.AddAccessorStatements.Statements, 0);
      codeEffector.PerformCodeChanges();
    }

    private void CorrectEventRemove(RuleViolationCorrection requestedCorrection, AnticipatingMinds.Genesis.Effectors.CodeEffector codeEffector, CodeStatementCollection ifStatementCollection)
    {
      CodeMethodParameterReferenceExpression methodParameterExpression = requestedCorrection.Violation.ViolationData["MethodParameterReferenceExpression"] as CodeMethodParameterReferenceExpression;
      CodeTypeEventDeclaration eventDeclaration = requestedCorrection.Violation.ViolationData["TypeMethodDeclaration"] as CodeTypeEventDeclaration;

      //Always insert at the start of the method
      codeEffector.AddCodeElements( ifStatementCollection, eventDeclaration.RemoveAccessorStatements, eventDeclaration.RemoveAccessorStatements.Statements, 0);
      codeEffector.PerformCodeChanges();
    }
  
    private void CorrectMethod(RuleViolationCorrection requestedCorrection, AnticipatingMinds.Genesis.Effectors.CodeEffector codeEffector, CodeStatementCollection ifStatementCollection)
    {
      CodeMethodParameterReferenceExpression methodParameterExpression = requestedCorrection.Violation.ViolationData["MethodParameterReferenceExpression"] as CodeMethodParameterReferenceExpression;
      CodeTypeMethodDeclaration methodDeclaration = requestedCorrection.Violation.ViolationData["TypeMethodDeclaration"] as CodeTypeMethodDeclaration;
      
      //Always insert at the start of the method
      codeEffector.AddCodeElements( ifStatementCollection, methodDeclaration.Statements, methodDeclaration.Statements.Statements, 0);
      codeEffector.PerformCodeChanges();
    }

    private AnticipatingMinds.Genesis.CodeDOM.CodeDomWalker.WalkerCallbackReturn FindVariableDeclarationStatement(CodeElement codeElement,AnticipatingMinds.Genesis.CodeDOM.CodeDomWalker.CallBackNotificationType notificationType, AnticipatingMinds.Genesis.CodeDOM.CodeDomWalkerContext walkerContext,object applicationData)
    {
      // search   current MethodParameterReferenceExpression in CodeVariableDeclarationStatement
      if(notificationType == CodeDomWalker.CallBackNotificationType.OnElement)
      {
        VariableDeclarationStatement variableDeclarationStatementData =  applicationData as VariableDeclarationStatement;
        if(variableDeclarationStatementData.MethodParameterReferenceExpression == codeElement)
        {
          variableDeclarationStatementData.IsExistsMethodParameterReferenceExpression = true;
          return CodeDomWalker.WalkerCallbackReturn.Cancel;
        }
      }
      return CodeDomWalker.WalkerCallbackReturn.Next;
    }
    
    private CodeIfStatement CreateCodeIfStatement(CodeReferenceExpression methodParameterExpression, bool isParamNameAndMessageDefault, string methodSignature, string parameterName)
    {
      #region Create BinaryExpression Equality
      CodeBinaryExpression binaryExpression = new CodeBinaryExpression();
      binaryExpression.Operator = CodeBinaryOperatorType.Equality;
      binaryExpression.LeftOperand = methodParameterExpression.Clone() as CodeExpression;
      binaryExpression.RightOperand = new CodeNullReferenceExpression();
      #endregion
      
      #region Create TrueStatement

      CodeObjectCreateExpression objectCreateExpression = new CodeObjectCreateExpression();
      objectCreateExpression.CreateType = new CodeTypeReference("System.ArgumentNullException");
      
      CodePrimitiveExpression primitiveExpression = new CodePrimitiveExpression(parameterName);
      CodeArgument paramNameArgument = new CodeArgument();
      paramNameArgument.Value = primitiveExpression;
      objectCreateExpression.Arguments.Add(paramNameArgument);
      
      if(isParamNameAndMessageDefault){

        string ErrorMessage;
        try
        {
          String.Format(this.ArgumentNullExceptionMessage, parameterName, methodSignature);
          ErrorMessage = this.ArgumentNullExceptionMessage;
        }
        catch(System.FormatException)
        {
          ErrorMessage = ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|ArgumentNullExceptionMessageDefault");
        }
        
        CodePrimitiveExpression primitiveExpressionMessage = new CodePrimitiveExpression(ErrorMessage);
        CodeArgument paramStringMessageArgument = new CodeArgument();
        paramStringMessageArgument.Value = primitiveExpressionMessage;

        CodePrimitiveExpression primitiveExpressionParameterName = new CodePrimitiveExpression(parameterName);
        CodeArgument paramStringParameterNameArgument = new CodeArgument();
        paramStringParameterNameArgument.Value = primitiveExpressionParameterName;

        CodePrimitiveExpression primitiveExpressionMethodSignature = new CodePrimitiveExpression(methodSignature);
        CodeArgument paramMethodNameArgument = new CodeArgument();
        paramMethodNameArgument.Value = primitiveExpressionMethodSignature;

        CodeTypeReference stringTypeReference = new CodeTypeReference("String");
        CodeTypeReferenceExpression stringTypeReferenceExpresion = new CodeTypeReferenceExpression(stringTypeReference);

        CodeMethodInvokeExpression methodInfokeExpression = new CodeMethodInvokeExpression();
        methodInfokeExpression.Arguments.Add(paramStringMessageArgument);
        methodInfokeExpression.Arguments.Add(paramStringParameterNameArgument);
        methodInfokeExpression.Arguments.Add(paramMethodNameArgument);
        methodInfokeExpression.MethodReferenceExpression = new CodeMethodReferenceExpression(stringTypeReferenceExpresion, "Format");
        

        CodeArgument paramMessageArgument = new CodeArgument();
        paramMessageArgument.Value = methodInfokeExpression;
        objectCreateExpression.Arguments.Add(paramMessageArgument);
      }

      CodeParenthesizedExpression codeParenthesizedExpression = new CodeParenthesizedExpression();
      codeParenthesizedExpression.Expression = objectCreateExpression;
      CodeThrowStatement throwStatement = new CodeThrowStatement();
      throwStatement.ToThrow = codeParenthesizedExpression;

      CodeStatementBlock codeStatementThrowBlock = new CodeStatementBlock();
      codeStatementThrowBlock.Statements.Add(throwStatement);
      
      #endregion
      
      CodeIfStatement ifStatement = new CodeIfStatement();
      ifStatement.Condition = binaryExpression;
      ifStatement.TrueStatement = codeStatementThrowBlock;
      return ifStatement;

    }
    private CodeIfStatement CreateCodeIfStatementUnresolvedReference(CodeMethodParameterReferenceExpression methodParameterExpression, bool isParamNameAndMessageDefault, string methodSignature)
    {
      #region Create BinaryExpression Equality
      CodeBinaryExpression binaryExpression = new CodeBinaryExpression();
      binaryExpression.Operator = CodeBinaryOperatorType.Equality;
      binaryExpression.LeftOperand = methodParameterExpression.Clone() as CodeExpression;
      binaryExpression.RightOperand = new CodeNullReferenceExpression();
      #endregion
      
      #region Create TrueStatement

      CodeObjectCreateExpression objectCreateExpression = new CodeObjectCreateExpression();
      objectCreateExpression.CreateType = new CodeTypeReference("System.ArgumentNullException");
      
      CodePrimitiveExpression primitiveExpression = new CodePrimitiveExpression(methodParameterExpression.ParameterName);
      CodeArgument paramNameArgument = new CodeArgument();
      paramNameArgument.Value = primitiveExpression;
      objectCreateExpression.Arguments.Add(paramNameArgument);
      
      if(isParamNameAndMessageDefault)
      {
        string ErrorMessage;
        try
        {
          String.Format(this.ArgumentNullExceptionMessage, methodParameterExpression.ParameterName, methodSignature);
          ErrorMessage = this.ArgumentNullExceptionMessage;
        }
        catch(System.FormatException)
        {
          ErrorMessage = ResourceManager.GetLocalizedString("TestForNullArgumentBeforeReferencingRuleTemplate|ArgumentNullExceptionMessageDefault");
        }
      
        CodePrimitiveExpression primitiveExpressionMessage = new CodePrimitiveExpression(ErrorMessage);
        CodeArgument paramStringMessageArgument = new CodeArgument();
        paramStringMessageArgument.Value = primitiveExpressionMessage;

        CodePrimitiveExpression primitiveExpressionParameterName = new CodePrimitiveExpression(methodParameterExpression.ParameterName);
        CodeArgument paramStringParameterNameArgument = new CodeArgument();
        paramStringParameterNameArgument.Value = primitiveExpressionParameterName;

        CodePrimitiveExpression primitiveExpressionMethodSignature = new CodePrimitiveExpression(methodSignature);
        CodeArgument paramMethodNameArgument = new CodeArgument();
        paramMethodNameArgument.Value = primitiveExpressionMethodSignature;

        CodeTypeReference stringTypeReference = new CodeTypeReference("String");
        CodeTypeReferenceExpression stringTypeReferenceExpresion = new CodeTypeReferenceExpression(stringTypeReference);

        CodeMethodInvokeExpression methodInfokeExpression = new CodeMethodInvokeExpression();
        methodInfokeExpression.Arguments.Add(paramStringMessageArgument);
        methodInfokeExpression.Arguments.Add(paramStringParameterNameArgument);
        methodInfokeExpression.Arguments.Add(paramMethodNameArgument);
        methodInfokeExpression.MethodReferenceExpression = new CodeMethodReferenceExpression(stringTypeReferenceExpresion, "Format");
      

        CodeArgument paramMessageArgument = new CodeArgument();
        paramMessageArgument.Value = methodInfokeExpression;
        objectCreateExpression.Arguments.Add(paramMessageArgument);
      }

      CodeParenthesizedExpression codeParenthesizedExpression = new CodeParenthesizedExpression();
      codeParenthesizedExpression.Expression = objectCreateExpression;
      CodeThrowStatement throwStatement = new CodeThrowStatement();
      throwStatement.ToThrow = codeParenthesizedExpression;

      CodeStatementBlock codeStatementThrowBlock = new CodeStatementBlock();
      codeStatementThrowBlock.Statements.Add(throwStatement);
      
      #endregion
      
      CodeIfStatement ifStatement = new CodeIfStatement();
      ifStatement.Condition = binaryExpression;
      ifStatement.TrueStatement = codeStatementThrowBlock;
      return ifStatement;

    }
    
    #endregion

    private static Type[] applicableApplicabilityScopeTypes = {typeof(MethodApplicabilityScope),typeof(PropertyApplicabilityScope),typeof(EventApplicabilityScope),typeof(FileApplicabilityScope)};
    public override Type[] ApplicableApplicabilityScopeTypes
    {
      get
      {
        return applicableApplicabilityScopeTypes;
      }
    }

    private static RuleViolation[] emptyViolationsList = new  RuleViolation[0];
    private Type[] targetedCodeElements = {typeof(CodeTypeMethodDeclaration), typeof(CodeTypeIndexerDeclaration), typeof(CodeTypeEventDeclaration), typeof(CodeTypePropertyDeclaration)};
  }

}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.