locked
Naming Rule For Variables RRS feed

  • Question

  • Hi,
    I am new to FxCop and am trying to write a custom rule.I just want to write a rule for naming convention i.e to check that all the variables of type String starts with "str".I used the following code
    Public Overrides Function Check(ByVal member As Microsoft.FxCop.Sdk.Member) As Microsoft.FxCop.Sdk.ProblemCollection
            Dim objMethod As Method
            Dim lstLocals As LocalCollection
            Try
                objMethod = member
                If (objMethod IsNot Nothing) Then
                    lstLocals = objMethod.Instructions(0).Value
                    For Each objLocal As Local In lstLocals
                        If (objLocal.Type.FullName = "System.String") Then
                            If (Not objLocal.Name.Name.StartsWith("str")) Then
                                Me.Problems.Add(New Problem(GetResolution(), objLocal.Name.Name))
                            End If
                        End If
                    Next
                End If
            Catch ex As Exception
    
            End Try
            Return Me.Problems
        End Function
    But here i am facing a problem,like the functions which are having a return type as string are also added with the error of not starting with str, apart from the function variables.Please tell what i am doing wrong

    Thank You
      Rahul
    FEAR NOT TO BE JUST Please mark posts as answers/helpful if it answers your query
    Wednesday, June 3, 2009 9:43 AM

Answers

  • Hi,

    Even after adding that extra check it did not work.
    I found out the problem.

    For IL generated from C# code the RuleUtilities.IsCompilerGenerated() method will work.Since the IL will look like the one given by Roahn Luo .

    For VB code It was that the locals contain the function name and its return type.
    So when checking for the local type you need to do an extra check for seeing whether the method name and the local name are same.if it is same then no need to check for the rule condition.
    For the same function as above see the IL generated by VB compiler.

    Code:
    
     Public Function Foo() As String
            Dim localString As String = "Hello, world!"
            Return "Message here"
        End Function
    
    IL:
    
    .method public instance string  Foo() cil managed
    {
      // Code size       17 (0x11)
      .maxstack  1
      .locals init ([0] string Foo,
               [1] string localString)
      IL_0000:  nop
      IL_0001:  ldstr      "Hello, world!"
      IL_0006:  stloc.1
      IL_0007:  ldstr      "Message here"
      IL_000c:  stloc.0
      IL_000d:  br.s       IL_000f
      IL_000f:  ldloc.0
      IL_0010:  ret
    } // end of method Window1::Foo
    
    
    Above you can see that the locals also contains "Foo" which is actually the function name.

    Ps:Since Vb does not allow to have a variable name same as the function name inside the function,you can very well go ahead and chek for this condition.

    Here is the working code for that for one compiled in vb.
    Will post once i find the one common for both.
     Public Overrides Function Check(ByVal member As Microsoft.FxCop.Sdk.Member) As Microsoft.FxCop.Sdk.ProblemCollection
            Dim objMethod As Method
            Dim lstLocals As LocalCollection
            Try
                objMethod = member
                If (objMethod IsNot Nothing) Then
                    lstLocals = objMethod.Instructions(0).Value
                    For Each objLocal As Local In lstLocals
                        If ((objLocal.Type Is FrameworkTypes.String) And (objLocal.Name.Name <> objMethod.Name.Name)) Then
                            If (Not objLocal.Name.Name.StartsWith("str")) Then
                                Me.Problems.Add(New Problem(GetResolution(), objLocal.Name.Name))
                            End If
                        End If
                    Next
                End If
            Catch ex As Exception
    
            End Try
            Return Me.Problems
        End Function
    I dont know if i have missed any more such conditions.Just exploring.Will post if i find any :)

    Hope it helps :)


    FEAR NOT TO BE JUST Please mark posts as answers/helpful if it answers your query
    • Marked as answer by Rahul P Nath Saturday, June 6, 2009 5:28 AM
    • Edited by Rahul P Nath Saturday, June 6, 2009 5:52 AM Edited the code
    Saturday, June 6, 2009 5:28 AM

All replies

  • Have you tried StyleCop?

    This is all about naming and styling.
    Ewald - Please remember to mark the replies as answers if they help.
    Wednesday, June 3, 2009 12:14 PM
  • Hi,
    I will check that out .
    But that doesn't solve this issue.I would like to know whats going wrong here

    Thank You
    FEAR NOT TO BE JUST Please mark posts as answers/helpful if it answers your query
    Wednesday, June 3, 2009 12:45 PM
  • Hello Rahul,

    You did nothing wrong, however, we seem to omit some further checks.
    The cause here is the VB compiler/C# compiler will automatically gernerates some local variables, something like: String CS$1$000.
    We could check those variables in the MISL Disassembler tool, let's assume a method like:
    public String Foo()
    {
           String localString = "Hello, world!";
           return "Message here";
    }
    It will generate the MISL like:
    .method public hidebysig instance string 
            Foo() cil managed
    {
      // Code size       25 (0x19)
      .maxstack  1
      .locals init ([0] string strlcl,
               [1] string CS$1$0000)
      IL_0000:  nop
      IL_0001:  ldstr      "Hello, world"
      .............
    }
    in the .locals section, there's a hidden variable (generated by the compiler), it is this variable that cause the issue.

    In order to omit those variables generated by the compiler, we could use RuleUtilities.IsCompilerGenerated() method to check the local variables.
    Please refer to this link for more information.

    Best regards,
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    If you have any feedback, please tell us.
    Welcome to the All-In-One Code Framework!
    Friday, June 5, 2009 5:48 AM
  • Hi,

    Even after adding that extra check it did not work.
    I found out the problem.

    For IL generated from C# code the RuleUtilities.IsCompilerGenerated() method will work.Since the IL will look like the one given by Roahn Luo .

    For VB code It was that the locals contain the function name and its return type.
    So when checking for the local type you need to do an extra check for seeing whether the method name and the local name are same.if it is same then no need to check for the rule condition.
    For the same function as above see the IL generated by VB compiler.

    Code:
    
     Public Function Foo() As String
            Dim localString As String = "Hello, world!"
            Return "Message here"
        End Function
    
    IL:
    
    .method public instance string  Foo() cil managed
    {
      // Code size       17 (0x11)
      .maxstack  1
      .locals init ([0] string Foo,
               [1] string localString)
      IL_0000:  nop
      IL_0001:  ldstr      "Hello, world!"
      IL_0006:  stloc.1
      IL_0007:  ldstr      "Message here"
      IL_000c:  stloc.0
      IL_000d:  br.s       IL_000f
      IL_000f:  ldloc.0
      IL_0010:  ret
    } // end of method Window1::Foo
    
    
    Above you can see that the locals also contains "Foo" which is actually the function name.

    Ps:Since Vb does not allow to have a variable name same as the function name inside the function,you can very well go ahead and chek for this condition.

    Here is the working code for that for one compiled in vb.
    Will post once i find the one common for both.
     Public Overrides Function Check(ByVal member As Microsoft.FxCop.Sdk.Member) As Microsoft.FxCop.Sdk.ProblemCollection
            Dim objMethod As Method
            Dim lstLocals As LocalCollection
            Try
                objMethod = member
                If (objMethod IsNot Nothing) Then
                    lstLocals = objMethod.Instructions(0).Value
                    For Each objLocal As Local In lstLocals
                        If ((objLocal.Type Is FrameworkTypes.String) And (objLocal.Name.Name <> objMethod.Name.Name)) Then
                            If (Not objLocal.Name.Name.StartsWith("str")) Then
                                Me.Problems.Add(New Problem(GetResolution(), objLocal.Name.Name))
                            End If
                        End If
                    Next
                End If
            Catch ex As Exception
    
            End Try
            Return Me.Problems
        End Function
    I dont know if i have missed any more such conditions.Just exploring.Will post if i find any :)

    Hope it helps :)


    FEAR NOT TO BE JUST Please mark posts as answers/helpful if it answers your query
    • Marked as answer by Rahul P Nath Saturday, June 6, 2009 5:28 AM
    • Edited by Rahul P Nath Saturday, June 6, 2009 5:52 AM Edited the code
    Saturday, June 6, 2009 5:28 AM
  • Good job! Rahul!

    Your code snippet is absolutely right for VB code! Well done!

    Regards,
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    If you have any feedback, please tell us.
    Welcome to the All-In-One Code Framework!
    Monday, June 8, 2009 2:10 AM