Intro
Prior to V40.14, gmBasic used MigrationSupport namespace and class conventions for the language runtime support (RTS) framework. These conventions were found in the translation of application code referencing the RTS as well as the stub framework generated to satisfy the references.
MigrationSupport conventions had the following features:
- The namespaces of the language runtime support stub framework are hard-coded into the system and included MigrationSupport, MigrationSupportUI, and VB6Controls.
- Extension method stubs are placed in the MigrationSupport.SystemExtensions class.
- Stub framework references are identified by scanning the generated code for the string "MigrationSupport" and also scanning the operation streams for references to status="extension" operations.
- MigrationSupport conventions are deprecated.
Beginning with V40.18, gmBasic system uses the gmRTL conventions. gmRTL conventions have the following features:
- The namespaces of the language runtime support stub framework are driven by the metalang files. The default RTS namespaces include gmRTL.Core, gmRTL.GUI, and gmRTL.ASP.
- Extension method stubs may be placed in any namespace. The stubs for status=extensions extension methods are placed in a SystemExtensions class in the namespace specified by the Select.ExtensionMethods select. By default this namespace is set in VB7Lang.xml <Select ExtensionMethods="gmRTL.Core" />
- The gmRTL framework has more classes than MigrationSupport framework providing a more descriptive structure for organizing the framework members.
- Stub framework references are identified by details in the metalang and by scanning the operation streams for references to RTS namespaces and classes.
- gmRTL conventions should be used for all new projects started after the 2021-11-30 release.
Note: stubs for references to COM APIs are handled differently from stubs for references to language operations. COM stub declarations are driven by COM IDFs and based on scanning operation streams for references to COM API elements. Also note that using the use of a stub framework is one possible mode of translation. It is typically used only in the early stages of an upgrade project before custom migration requirements are defined. Custom requirements may be implemented as custom migration rules that direct an automated translation meeting the custom requirements. See the Incremental Upgrade Cookbook for details.
We continually work to extend, improve, and stabilize the gmRTL namespaces to provide an option for migrating legacy code not so easily represented in .NET. Our plan is to make a copy of the gmRTL codebase in an open source repository (e.g. GitHub) so the .NET programming community may have access and contribute to its development.
Impact
Implementing the gmRTL conventions required numerous changes to the metalang and the gmBasic logic. The resulting RTS stubbing process is more precise and flexible as well as being a bit faster. gmRTL translations look very different from MigrationSupport translations, but the changes are mainly different names for the namespaces and classes holding the RTS members. Although the organization and structure of the RTL stub framework changed, the locations of RTS references in generated code are the same.
Backward compatibility
Although the details of gmRTL language mappings differ considerably from MigrationSupport mappings, it is possible to reproduce MigrationSupport-style translations with custom migration rules. The use and structure of the RTS framework in a translation is completely controlled by the tool's metalang files, so an upgrade team may implement a custom metalang to produce other translations. However, a simpler technique is to use a few refactoring and post-editing commands. The ScriptRules file below is an example of how to revert gmRTL translations back to MigrationSupport conventions if you must complete a project using the deprecated MigrationSupport.dll assembly.
<ScriptRules> <!-- Description: Rules to restore MigrationSupport conventions in a gmRTL code. --> <ScriptRule id="MSRollBack" Condition="%TaskTag%=='upg'"> <Option> </Option> <PostAnalyse> <refactor> <Migrate id="[gmRTL.Core]" migName="MigrationSupport"/> </refactor> </PostAnalyse> <Author> <Fix name="PostEdit"> <Replace status="active" name="Reference MigrationSupport.dll rather than gmRTL.Core" lang="csproj"> <OldBlock><![CDATA[ <Reference Include="gmRTL.Core"> ... </Reference> ]]></OldBlock> <NewBlock><![CDATA[ <Reference Include="MigrationSupport"> <Name>MigrationSupport</Name> <HintPath>..\MigrationSupport\bin\Debug\MigrationSupport.dll</HintPath> </Reference> ]]></NewBlock> </Replace> <Replace status="active" name="Remove gmRTL.GUI.dll reference" lang="csproj"> <OldBlock><![CDATA[ <Reference Include="gmRTL.GUI"> ... </Reference> ]]></OldBlock> </Replace> <Replace name="gmRTL.Core.GlobalException"> <OldBlock><![CDATA[gmRTL.Core.GlobalException]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.GlobalException]]></NewBlock> </Replace> <Replace name="using gmRTL.Core;"> <OldBlock><![CDATA[using gmRTL.Core;]]></OldBlock> <NewBlock><![CDATA[using MigrationSupport;]]></NewBlock> </Replace> <Replace name="using gmRTL.GUI;"> <OldBlock><![CDATA[using gmRTL.GUI;]]></OldBlock> </Replace> <Replace name="gmRTL.Core.Enums"> <OldBlock><![CDATA[gmRTL.Core.Enums]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Utils]]></NewBlock> </Replace> <Replace name="gmRTL.Core.Enums"> <OldBlock><![CDATA[gmRTL.GUI.Enums]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Utils]]></NewBlock> </Replace> <Replace name="gmRTL.Core.App"> <OldBlock><![CDATA[gmRTL.Core.App]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.App]]></NewBlock> </Replace> <Replace name="gmRTL.Core.ErrorHandling"> <OldBlock><![CDATA[gmRTL.Core.ErrorHandling]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Utils]]></NewBlock> </Replace> <Replace name="gmRTL.Core.ErrorHandling"> <OldBlock><![CDATA[gmRTL.Core.FormatHelper]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Utils]]></NewBlock> </Replace> <Replace name="gmRTL.Core.ErrorHandling"> <OldBlock><![CDATA[gmRTL.Core.FormatHelper]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Utils]]></NewBlock> </Replace> <Replace name="gmRTL.GUI.LineControl"> <OldBlock><![CDATA[gmRTL.GUI.LineControl]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Line]]></NewBlock> </Replace> <Replace name="gmRTL.GUI.ShapeControl"> <OldBlock><![CDATA[gmRTL.GUI.ShapeControl]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.ShapeControl]]></NewBlock> </Replace> <Replace name="gmRTL.GUI.ControlHelper"> <OldBlock><![CDATA[gmRTL.GUI.ControlHelper.]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Utils.]]></NewBlock> </Replace> <Replace name="gmRTL.GUI.FontHelper."> <OldBlock><![CDATA[FontHelper.SetName]]></OldBlock> <NewBlock><![CDATA[FontHelper.FontChangeName]]></NewBlock> </Replace> <Replace name="gmRTL.GUI.FontHelper."> <OldBlock><![CDATA[FontHelper.SetBold]]></OldBlock> <NewBlock><![CDATA[FontHelper.FontChangeBold]]></NewBlock> </Replace> <Replace name="gmRTL.GUI.FontHelper."> <OldBlock><![CDATA[FontHelper.SetSize]]></OldBlock> <NewBlock><![CDATA[FontHelper.FontChangeSize]]></NewBlock> </Replace> <Replace name="gmRTL.GUI.FontHelper."> <OldBlock><![CDATA[gmRTL.GUI.FontHelper.]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Utils.]]></NewBlock> </Replace> <Replace name="gmRTL.Core.InformationHelper."> <OldBlock><![CDATA[gmRTL.Core.InformationHelper.]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Utils.]]></NewBlock> </Replace> <Replace name="gmRTL.Core.InteractionHelper."> <OldBlock><![CDATA[gmRTL.Core.InteractionHelper.]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Utils.]]></NewBlock> </Replace> <Replace name="gmRTL.Core.DateTimeHelper."> <OldBlock><![CDATA[gmRTL.Core.DateTimeHelper.]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Utils.]]></NewBlock> </Replace> <Replace name="gmRTL.Core.MathHelper."> <OldBlock><![CDATA[gmRTL.Core.MathHelper.]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Rand.]]></NewBlock> </Replace> <Replace name="gmRTL.Core.MathHelper."> <OldBlock><![CDATA[gmRTL.Core.MathHelper.]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Utils.]]></NewBlock> </Replace> <Replace name="Source.GetControlIndex()"> <OldBlock><![CDATA[Source.GetControlIndex()]]></OldBlock> <NewBlock><![CDATA[MigrationSupport.Utils.GetControlIndex(Source)]]></NewBlock> </Replace> <Replace name="MigrationSupport.Utils.OLEDropConstants"> <OldBlock><![CDATA[MigrationSupport.Utils.OLEDropConstants]]></OldBlock> <NewBlock><![CDATA[OLEDropConstants]]></NewBlock> </Replace> </Fix> </Author> </ScriptRule> </ScriptRules>