FxCop Custom Rule: To check for variable name

Hi,

I am trying to check if variables declared inside functions follow coding standards.

I have implemented the code to check for Boolean variable. Variable name must start with 'b'

public override ProblemCollection Check(Member member)

{

if (member.NodeType == NodeType.Field)

{

//Local local = listIdea;

Field field = member as Field;

if (field != null)

{

//type = field.Type.ToString();

if (field.Type == SystemTypes.Boolean)

{

if (!field.Name.Name.StartsWith("b"))

{

//Problems.Add(new Resolution("The label {0} must start with 'lbl'", node.Name.Name));

base.Problems.Add(new Problem(GetResolution(field.Name.Name), field.FullName));

}

}

}

}

return Problems;

}

The above code is not checking for variables defined inside the functions. Can anyone please help me in trapping the variables defined inside the functions

I need to check for only variables inside functions and not for function return types, events, property and so on...




Answer this question

FxCop Custom Rule: To check for variable name

  • gau2902

    Hi,

    variables inside a method are also called Locals. Please note that names of locals can only be resolved if pdb's are present (compile your project with /debug)

    To retrieve locals inside a method do something like this:



    public override ProblemCollection Check(Member member)
    {
    Method method = member as Method;
    if (method == null) return null;
    //abstract method, interface etc...
    if (method.Instructions == null || method.Instructions.Length == 0) return null;
    LocalList locals = method.Instructions[0] as LocalList;
    if (locals == null) return null;
    foreach(Local local in locals)
    {
    //do work
    }
    }


  • S M Hasan

    Hi,

    Thnx for the reply. I have tried the following code.

    public override ProblemCollection Check(Member member)

    {

    Method method = member as Method;

    if (method == null)

    {

    return null;

    }

    LocalList list = null;

    if (method.Instructions.Length > 0)

    {

    list = method.Instructions[0].Value as LocalList;

    }

    if (list != null)

    {

    for (int i = 0; i < list.Length; i++)

    {

    Local local = listIdea;

    if (local.Type == SystemTypes.Boolean)

    {

    if (Containsb(local.Name.Name))

    {

    // Found a local boolean not containing b

    base.Problems.Add(new Problem(base.GetResolution(local.Name.Name), local.Name.Name));

    }

    }

    }

    }

    return base.Problems;

    }

    private bool Containsb(string variableName)

    {

    if (!(variableName.StartsWith("b")))

    {

    return true;

    }

    else

    {

    return false;

    }

    }

    }

    The problem with the above code is that it also checks for function return types, property having boolean as return type. I need to check for only local variables . Also I was trying this code for Date Variables In case of date it gave error messages for Variables like _VB_DATE_0, _VB_DATE_1 and so on which are actually not present in the code.

    So can anyone please help me:

    a) To check for only local variables

    b) In case of Date variables what are the variables _Vb_Date_0, _Vb_Date_1 ... signify These are not present in the code been analysed.

    Regards

    Ashish



  • Vitalijus

    Below is the code of the function  having Boolean as return type:

    Private Function IsAddressFull(ByVal tInputParam As xyz.Cl.cAddress) As Boolean

    Dim bFullClAchieved As Boolean

    Dim dicStates As abc.Collect.Dictionary

    Dim sCountry As String

    Dim bStateReqlfilled As Boolean

    Dim bZipCodelfilled As Boolean

    Try

    With tInputParam

    if IsStringNull(.sCountry) = False Then

    sCountry = .sCountry

    Else

    sCountry = CountryS

    End If

    Return bFullClAchieved

    Finally

    Cleanup(dicStates)

    dicStates = Nothing

    End Try

    End Function

    So when I run the custom Rule it gives me error the following error:

    Target : IsAddressFull():System.Boolean (IntrospectionTargetMethodBase)

    Id : IsAddressFull (String)

    Location : file:///C://ABAddr.aspx.vb<1127> (String)

    Resolution : "Add prefix b to variable 'IsAddressFull'"

    Help : http://www.dla.mil/ (String)

    Category : Design Rules (String)

    CheckId : DR0051 (String)

    RuleFile : CodingStandards.dll (String)

    Info : "Boolean Variable should start with b as prefix."

    Created : 3/1/2006 1:04:04 PM (DateTime)

    LastSeen : 3/1/2006 1:04:04 PM (DateTime)

    Status : Active (MessageStatus)

    Fix Category : NonBreaking (FixCategories)

    }

     

    Same is the case with other functions having return type as Boolean.



  • ryuga99

    I'm a little confused as to the return value having the same name as the function, do mean like the following pattern:



    Private Function IsAddressNull(ByVal branch As Boolean, ByVal branch2 As Boolean) As Boolean
    IsAddressNull = True
    End Function

    If so, I've done a few tests and I can't get the IsAddressNull name to be persisted as a local variable. Can you post a sample where you can

    If you are able to get the IsAddressNull to persist as a local variable, you could check the name of each variable against the name of the method that it is defined on and if they match, ignore it.



  • theinspector

    Thanks, looks like the VB compiler is creating this variable in certain situations.

    Even though this is the case, my last paragraph still stands:

    If you are able to get the IsAddressNull to persist as a local variable, you could check the name of each variable against the name of the method that it is defined on and if they match, ignore it.



  • Nidhogg

    The compiler sometimes generates its own locals on top of what is in the source code. You can exclude these by using the RuleUtilities.IsCompilerGenerated helper method.

    This function shows how you could go about implementing this rule:



    public override ProblemCollection Check(Member member)
    {
    Method method = member as Method;

    if (method == null)
    return null;

    if (method.Instructions == null || method.Instructions.Length == 0)
    return null;

    LocalList locals = method.Instructions[0].Value as LocalList;

    if (locals == null)
    return null;

    for (int i = 0; i < locals.Length; i++)
    {
    Local local = locals[ i ];

    if (local.Type != SystemTypes.Boolean)
    continue;

    if (RuleUtilities.IsCompilerGenerated(local))
    continue;

    if (local.Name.Name.StartsWith("b"))
    continue;

    base.Problems.Add(new Problem(base.GetResolution(local.Name.Name), local));
    }

    return Problems;
    }



  • wissgtbob

    Note - I don't know if this is still valid in 1.35. Try it and see...

  • Fernando D. Bozzo

    Thnx for the above code would try that out. But still one of the main problem remains unresolved as locals also inlcude functions return types

    so if I have a function as

    Private Function IsAddressNull(...) As Boolean

    the rule gives error as the function Name is not starting with b and type is boolean.

    How to solve this problem

    Thnx for all the help.... would be great if the above problem could also get resolved.



  • FxCop Custom Rule: To check for variable name