Resolve Late Bound Variable Types

The Visual Basic Upgrade Companion performs an extensive data analysis to infer the most appropriate data types for variables, parameters, and return values, avoiding the use of generic data types like Variant and Object.

When a variant data-type variable is found, the Visual Basic Upgrade Companion declares the variable with the appropriate type and avoids unnecessary Warning messages generated in the target code.

This preliminary stage not only makes the resulting code better by declaring appropriate types, but it also achieves substantial improvements in the overall conversion process by allowing a considerable amount of advanced transformation rules to apply over variables and compound expressions, whose correct types are accurately identified by the main conversion engine.

Some of these advanced transformations can only be applied when the correct types are known and uses of generic data types have been removed:

  • Type castings, coercions and other crucial corrections for achieving strict typing
  • Default properties resolution
  • Application of appropriate transformation for library members
  • Conversion of arrays with lower bounds different to 0
  • Many Other

The Type inference engine analyzes each variable and all of its references in order to obtain implicit typing information from the VB6 late binding environment. When a late bound variable is detected, the typing engine will analyze all the references made to this variable in order to deduce the correct data type; this analysis can be done with different levels of granularity. These options can be tweaked from the graphical user interface in the Main Project Grid:

  • Full Typing: This option will make the typing engine to analyze all the typing information using the entire upgrade solution scope. This means, all the late bound variables information will be analyzed from a global scope including references found on other projects detected during the preprocessing stage.
  • Local Typing: The typing information will be processed only from each file scope.
  • No Typing: Leaves the variable types as they were defined in the original source code.

The VBUC is able to have different type inference settings for each project in the upgrade solution. Depending on the internal structure and the typing/binding techniques of the original VB6 system, some files can be upgraded without the compulsory need of full typing, thus, changing this setting to local typing or no typing can save some time during the automated migration stage.

The next code sample demonstrates a couple of subroutines containing non typed variables.

Original VB6 Code:

Public Sub typeInference()
  Dim var1
  Dim var2
  Dim var3
  Dim var4 As String * 50
  var4 = App.Path & "\createDsn.ini"
  var1 = ArgTypeInference(var2, var3, var4, CInt(var3))
End Sub


Public Function ArgTypeInference(ByVal arg1 As Integer, ByVal arg2 As String, ByVal arg3 As String, ByVal arg4 As Integer)
    MsgBox arg1, , "Argument1"
    MsgBox arg2, , "Argument2"
    MsgBox arg3, , "Argument3"
    MsgBox arg4, , "Argument4"
    ArgTypeInference = 1
End Function

Due to its advanced type inference mechanism, the Visual Basic Upgrade Companion’s resulting source code contains clearly defined data types. For this example, var1, var2 and var3 were typed based on their usage (Byte, Integer and String respectively). Also the “ArgTypeInference” function return value was upgraded to an explicit call of the “return” keyword.

Resulting VB.NET code

All the transformations applied in the previous example are available for C# source code generation as well.

Resulting C# Code:

The Visual Basic Upgrade Companion’s resulting source code contains clearly defined data types.

For this example, var1, var2 and var3 were typed based on their usage (Byte, Integer and String respectively). Also the “ArgTypeInference” function return value was upgraded to an explicit call of the “return” keyword.

static public void  typeInference()
{
    int var2 = 0;
    string var3 = String.Empty;
    FixedLengthString var4 = new FixedLengthString(50);
    var4.Value = Path.GetDirectoryName(Application.ExecutablePath) + "\\createDsn.ini";
    byte var1 = ArgTypeInference(var2, var3, var4.Value, Convert.ToInt32(Double.Parse(var3)));
}
        
    
static public byte ArgTypeInference( int arg1,  string arg2,  string arg3,  int arg4)
{
    MessageBox.Show(arg1.ToString(), "Argument1");
    MessageBox.Show(arg2, "Argument2");
    MessageBox.Show(arg3, "Argument3");
    MessageBox.Show(arg4.ToString(), "Argument4");
    return 1;
}