gmplAnalyseStatement

Analyse Statement Summary

Analyse is a nonterminal, command statement that occurs only in command scripts. It initiates the code analysis phase of the translation process. This phase takes as input the intermediate code produced by the compiler and outputs an intermediate code that can be authored in the target language. Once completed each active code unit has two intermediate code representations stored in the virtual binary information file.

The attributes of the Analyse statement are as follows:

Attribute Description
Dialect This deprecated attribute specifies one of the three target language identifiers csh, vbn, or usr. It changes the system wide target language as selected and thus effects all further processing.
Project This attribute specifies the name of a previously compiled VBP project or ASP page. It restricts the analyzer to effect the specified component only. The use of this attribute should be limited to complex migrations where the order in which code units are processed must be controlled.

Though technically a nonterminal statement, the Analyse statement has no substatements at this time.

The script errors associated with the Analyse statement are as follows:

Error Description
1001 Encountered illegal ANALYSE directive %1d
1002 The Language dialect [%1d] is not supported.
1003 The Project [%1d] does not exist in storage area.
1004 The Component [%1d] is not a project.
1005 The Storage area does not contain any projects.

The analysis phase proceeds in the following detailed steps:

Step Description
CheckPass1 Check for simple problems introduced into the symbol tables during the first pass of the compiler.
StartAnalyser Trigger the StartAnalyser event.
CheckCompile Check for simple problems introduced in the compiled code like multiply typed variables.
ProcessDirectives Process any refactoring statements within the scope of the ANALYSE statement
RemoveMethods Scan the symbol tables for methods that should be removed and mark them accordingly
Pass1Interface Determine if the project contains any interface projects. If so, look for Enumerations and variables whose class or usertype needs to be switched from an interface class to the implementation class for that interface.
FixReserved Scan the symbol tables for symbols with reserved identifiers and replace them with new target identifier.
VariantValues References to symbols with variant values are sought in the code to determine if their usage makes it possible to infer a stronger type for them. Most type inferences occur during this step.
CodeReview The code is reviewed and changes are made to make it compatible with the target .NET language. The actual changes made are different for C# versus VB.NET.
ByRefArguments The argument passing logic is analysed. Argument types are cast to the appropriate types required by the parameters that they are passed to. Arguments that are passed ByRef are examined and where necessary temporaries are created to contain computed, constant, or NULL values that cannot be passed ByRef.
FinalPass A final pass is made through the code units to make any final adjustments needed in so far as the .NET languages are concerned.
CheckBuild Do another pass though the code looking for build problems. The primary strategy used to fix problems is to change the type of problem variables to simple objects and then to use casting and boxing logic to fix any problems that this change causes. But if a parameter is changed then the entire process has to be rerun since may cause additional problems.
FinishAnalyser Trigger the FinishAnalyser event.


Details about the CheckPass1 analysis step

One of the tasks of the CheckPass1 analysis step is to check for inconsistent accessibility problems. In .NET there is the following error that is not an error in VB6.


 error CS0059: Inconsistent accessibility: "type" is less accessible than "user of type".
Simply stated a non-private component cannot have a private type or have a child or parameter of a private type. There is no such restriction in VB6. A simple example would be


Private Type enumError
   errNumber As Long
   errDescription As String
   errHelpFile As String
   errHelpContext As String
   errSource As String
End Type
  Public m_enumError As enumError
more complicated example would be


Private Type CMSPR_SpreadDistanceOptionType
   NextFeatureOffset As Integer
   FeatureSymbolOffset As Integer
     ...
 Private Type CMSPR_SpreadOptionType
   general As CMSPR_SpreadGeneralOptionType
   pics    As CMSPR_SpreadPicsOptionType
     ...
Public cmspr_left_spread_options_1 As CMSPR_SpreadOptionType
Public cmspr_left_spread_options_2 As CMSPR_SpreadOptionType
The reference in the non-private variable to CMSPR_SpreadOptionType forces that type to be non-private. Then the field general in the now non-private type forces SpreadDistanceOptionType to be non-private.

When detected the accessibility of the type component is changed to non-private and for structures the types of its members are check to make certain no new inconsistent accessibility problems have been introduced.

Details about the CodeReview analysis step

This step reviews the code and changes are made to make it compatible with the target .NET language. The actual changes made are different for C# versus VB.NET. There are many detailed migrations performed as are described in the following subtopics.

Analyse MessageBox Styles

This migration is performed if the code for the current method has any references to the MessageButton Constants enumeration. If these references are contained within a call to the MsgBox command or function, then those calls might be refactored as call to the .NET MessageBox.Show method as opposed to the VBNET.Interaction.MsgBox method. The problem here has to do with the VBNET.MsgBoxStyle enumeration which is identical, except for one small difference, with the VB6 enumeration used in the same context. This enumeration contains a complex mixture of members divided into four groups -- button types, icon style, default button, and modality/options. The simpler MessageBox.Show method breaks the first two into separate enumerations and ignores the rest.The button types are:

MsgBoxStyle MessageBox.Show
OKOnly MessageBoxButtons.OK
OKCancel MessageBoxButtons.OKCancel
AbortRetryIgnore MessageBoxButtons.AbortRetryIgnore
YesNoCancel MessageBoxButtons.YesNoCancel
YesNo MessageBoxButtons.YesNo
RetryCancel MessageBoxButtons.RetryCancel

The icon styles are:

MsgBoxStyle MessageBox.Show
Critical MessageBoxIcon.Warning
Question MessageBoxIcon.Question
Exclamation MessageBoxIcon.Exclamation
Information MessageBoxIcon.Information

The default buttons are DefaultButton1, DefaultButton2, and DefaultButton3; and the modality/options are ApplicationModal, SystemModal, MsgBoxHelp, MsgBoxRight, MsgBoxRtlReading and MsgBoxSetForeground.

The strategy is to scan the selections made for the styles. If they are not constants or if they explicitly contain selections from groups three or four or if they contains "weird combinations" then the VBNET MsgBox method is used else it is converted to Message.Show. This migration is being done for both VB.NET and C#.

Note first that the VB6.MsgBox methods have five arguments while the .NET ones have only three. The last two arguments, helpfile, and context, are almost always not used and show up in the code as empty strings and zero. In this migration, these are always ignored.

Unfortunately, when MsgBox is being used as a function, its return value must be of the VBNET.MsgBoxResult type, so no switch can be made to the Show method, unless the method was being called -- i.e., its return value was being ignored. Also, the Show method has more icons than the .NET style, but is missing a "Critical" icon. "Warning" is used instead.

Finally, in VB6 calls can be written this way


 MsgBox MESSAGE_ERROR_IN & "DeselectAll.", vbOKOnly, vbInformation
where the styles are separated by a comma as opposed to a PLUS or an OR. This is checked for so that the second style is not taken as the Title and thus interfere with the normal MsgBox logic.
Table of Contents