Previous | Index | Next 

[HOWTO] Apply pragmas only to variables of specific types

Note: this article only applies to conversions to VB.NET.

VB Migration Partner allows you to apply most pragmas to the project, file, method, and variable scope. For example, if you want to preserve the VB6 semantics for all the auto-instancing (As New) variables in your project, this is the pragma to use:

        '## project:AutoNew
        Dim col As New Collection
        Dim col2 As New Collection
        Dim frm As New Form1

Apparently, you can’t apply pragmas only to a given type of variables, for example only to variables of type Collection. It seems that the only way to do so is interspersing your code with myriads of variable-scoped pragmas:

        '## col.AutoNew
        '## col2.AutoNew
        Dim col As New Collection
        Dim col2 As New Collection
        Dim frm As New Form1

Surprisingly, however, there is a solution to this problem. In fact, you can pre-process the VB6 code being fed to VB Migration Partner, so that you can automatically insert a variable-scoped AutoNew immediately before the declarations of the variables you’re interested in:

        '## project:PreProcess "\b(Public|Private|Dim)\s+(?<name>\w+)\s+As\s+New\s+Collection\b", 
            "'## ${name}.AutoNew\r\n$0", True
        Dim col As New Collection
        Dim col2 As New Collection
        Dim frm As New Form1

(previous pragma should be typed as a single-line remark). The neat effect of the PreProcess pragma is transforming the original VB6 code into the following text:

        '## col.AutoNew
        Dim col As New Collection
        '## col2.AutoNew
        Dim col2 As New Collection
        Dim frm As New Form1

This pre-processed code is then analyzed by the parser, which finds the two AutoNew pragmas and reacts accordingly. This is a great example of the flexibility that only VB Migration Partner can offer.

Of course, you aren’t limited to the AutoNew pragma. For example, you can ensure that only ADODB Connection and Recordset objects be disposed of correctly, using the following project-level pragma:

        '## project:PreProcess "\b(Public|Private|Dim)\s+(?<name>\w+)\s+As\s+New\s+(ADODB\.)?
            (Connection|Recordset)\b", "'## ${name}.AutoDispose\r\n$0", True

This technique can be especially useful if your VB6 code follows strict naming guidelines. For example, let’s assume that all 1-dimensional arrays in your code have an “arr” prefix and that all 2-dimensional arrays have a “mat” prefix (as in “matrix”):

        Dim arrNames() As String
        Dim matValues() As Double

VB Migration Partner is capable to deduce the rank of any array by analyzing how the array is used. In some cases this isn’t possible, however, and you can use the following trick:

        '## PreProcess "\b(Public|Private|Dim)\s+(?<name>mat\w+)
            \(\)\s+As\s+(?<type>\w+(\.\w+)?)\b", "'## ${name}.ArrayRank  2\r\n$0", True

Another case is when the 2-dim array appears as a method parameter. If the embedding class is used to define an interface, the method is likely to contain any code, therefore VB Migration Partner has no clue about the array rank:

        Public Function ProcessValues(matValues() As Double) As Double()
            ' no code, as this is an interface definition
        End Function 

Here’s how you can assign rank=2 for all the method parameters whose name begins with “mat”:

        '## PreProcess "\b(Public\s+|Private\s+|Friend\s+)?(Sub|Function)\s+\w+
            \(.*\b(?<name>mat\w+)\(\)\s+As\b.+\r\n", "$0'## ${name}.ArrayRank 2\r\n", True

 

Previous | Index | Next