Some Helper Tools for Migrating Delphi Projects to Elements

(Friedrich Westermann) #1

Hi All,
I have startet to publish some Helper -Tools to make the transition from Delphi to Elements easier. I’m in the cleanup phase, but before I spend to much time
I would like to know about the interest from the community here.
The most work is done around the Delphi-Ast Project.
What is planed so far:

  • Port Delphi-Ast to Elements (Done and published GitHub)
  • Build a Tool to show up Problems in Delphi Sources before porting to Elements. (More or less done needs some polish)
  • Build a Tool to Setup Tests for all the Classes and Public Methods in the Delphi Sources. (partly done including some Helper Classes to use DUnitX-Tests in Elements)

Reason why I do this work:
I’m porting a large Delphi Project to Elements. And as a Developer,I wan’t as much as possible done an automatic way.
The second reason: This way I’m learning a lot about Elements, that will be helpful in the future for me.

to Show parts of a result from the actual Problems-Checker:

cad.Types.FastGeoCalc.pas

has With Clauses
has Initialization
has Finalizations
has Public Vars in Interface needs {GLOBALS ON}
has Public Methods in Interface needs {GLOBALS ON}
has Variant record Type

And my TestClasses are defined this way:

Unit ElementTestBase;

interface
uses
{$IF ELEMENTS}
  RemObjects.Elements.EUnit,
{$ELSE}
  Dunitx.ElementsHelper,
{$ENDIF}
  DUnitX.TestFramework;

type
 [TestFixture]
  ElementTest =  class(TTest)
  private
  protected
  public
  [Test]
    Procedure FirstTest;
  end;

implementation

Procedure ElementTest.FirstTest;
begin
  Assert.IsTrue(true);
end;

 {$IF NOT ELEMENTS}
initialization
  TDUnitX.RegisterTestFixture(ElementTest);
{$ENDIF}
end.
(marc hoffman) #2

This is awesome Fritz! Great job. cant wait to expose this in more detail.

One question off hand (after literally just looking at the repo for 30 seconds ;): Would be be possible.sensible for the DelphiAST port to generate/covert the Abstract Syntax Tree in/to CodeGen4 format?

That way, it could get re-emitted right away to a number of languages supported by CG4, including all 5 Elements languages, and more (including VB, C++, etc).

I’m sure we’d find a bunt of structures we don’t support ion CG4 yet (which I’ll be happy to add, and that will help make CG4 more well-rounded, in the process), and we could also identify/create automatic “conversions” for structures not supported the same way in Oxygene… (say, convert a destructor to a finalizer and a dispose method).

What do you think?

(Friedrich Westermann) #3

Yeah that was on of my Ideas, but I think it is to much for the start.
(and I need a closer look at CodeGen4, for myself to understand it better),
but I’m willing to do this part.
To be honest I’m also awaiting the reactions of the “community”

1 Like
(Friedrich Westermann) #4

Hi to All,
i have more or less finished the ProblemChecker.

i was running it on the PascalScript_Core Package:
here a Part of the result: Logged as Level 0 (Needs to check before convert)

upscompiler.pas
  Variant record Type (1)   TIfRVariant [133, 17]
  With Clauses  (24)   [12373, 3] ,[12377, 3] ,[12381, 3] ,[12432, 3] ,[12437, 3] ,[12441, 3] ,[13069, 3] ,[13074, 3] ,[13094, 3] ,[13114, 3] ,[13121, 3] ,[13128, 3] ,[13140, 3] ,[13226, 3] ,[13231, 3] ,[13237, 3] ,[13245, 3] ,[13252, 3] ,[14607, 3] ,[14612, 3] ,[15085, 3] ,[15520, 3] ,[15525, 3] ,[15710, 3]
====

upsruntime.pas
  Variant record Type (1)   TClassItem [499, 16]
  Variables with defined Types (1)   pp [253, 3]
  Assembler is used (8)   RealFloatCall_Register [14, 5] ,RealFloatCall_Other [42, 5] ,RealFloatCall_CDecl [67, 5] ,RealCall_Register [101, 5] ,RealCall_Other [151, 5] ,RealCall_CDecl [198, 5] ,MyAllMethodsHandler [11622, 3] ,PutOnFPUStackExtended [11715, 3]
====

And here a result from my CodeGenerator

Base Delphi:

const
  LIBCLANG = 'libclang.dll';

const
  CXError_Success = 0;
  CXError_Failure = 1;
  CXError_Crashed = 2;
  CXError_InvalidArguments = 3;
  CXError_ASTReadError = 4;

function clang_getCString(_string: TCXString): PAnsiChar; cdecl external LIBCLANG;

procedure clang_disposeString(_string: TCXString); cdecl external LIBCLANG;

Result:

{$GLOBALS ON}

const LIBCLANG = 'libclang.dll';
const CXError_Success = 0;
const CXError_Failure = 1;
const CXError_Crashed = 2;
const CXError_InvalidArguments = 3;
const CXError_ASTReadError = 4;

[DllImport(LIBCLANG)]
[CallingConvention(CallingConvention.Cdecl)]
method clang_getCString(_string: TCXString): PAnsiChar; external;

[DllImport(LIBCLANG)]
[CallingConvention(CallingConvention.Cdecl)]
method clang_disposeString(_string: TCXString); external;

Also a snippet from a class:
constructor and class function added

 public
    // Proholz.CodeBuilder:  Nameless Constructor added
    constructor(const ABegin: TSourceLocation; const AEnd: TSourceLocation);
    // Proholz.CodeBuilder:  Static Factory method added
    class method Create(const ABegin: TSourceLocation; const AEnd: TSourceLocation): TSourceRange;
(marc hoffman) #5

Awesome! I’ll have to try this on some real code, later the week.