From 87a53d1ed2dbf5cf072498660002721effc06ca6 Mon Sep 17 00:00:00 2001 From: dinkumoil Date: Thu, 10 Nov 2022 14:50:02 +0100 Subject: [PATCH] Add Pascal/Delphi for Function List Add Pascal/Delphi FunctionList parser and unit tests. Fix #3664, close #12489 --- PowerEditor/Test/FunctionList/pascal/unitTest | 445 ++++++++++++++++++ .../pascal/unitTest.expected.result | 1 + PowerEditor/installer/functionList/pascal.xml | 161 +++++++ 3 files changed, 607 insertions(+) create mode 100644 PowerEditor/Test/FunctionList/pascal/unitTest create mode 100644 PowerEditor/Test/FunctionList/pascal/unitTest.expected.result create mode 100644 PowerEditor/installer/functionList/pascal.xml diff --git a/PowerEditor/Test/FunctionList/pascal/unitTest b/PowerEditor/Test/FunctionList/pascal/unitTest new file mode 100644 index 000000000..af90bbae7 --- /dev/null +++ b/PowerEditor/Test/FunctionList/pascal/unitTest @@ -0,0 +1,445 @@ +unit Test; + + +interface + +uses + System.SysUtils, System.Types, System.Classes; + + +// ATTENTION!!! This is a known issue! +// The following function should NOT be part of the function list tree. +// However, it is still included because of the TYPE keyword after its declaration. +// Global functions or procedures should therefor be declared immediately before +// the keyword IMPLEMENTATION. +function FreeFunc(const Param: integer): integer; + + +type +// ----------------------------------------------------------------------------- +// TStdClass +// ----------------------------------------------------------------------------- + + TStdClass = class(TObject) + private type + TStdInternalClass = class(TObject) + private + FName: string; + FId: integer; + + public + constructor Create; + destructor Destroy; override; + + procedure CopyTo(Dest: TStdInternalClass); + + property Name: string read FName write FName; + property Id: integer read FId write FId; + end; + + private + FId: integer; + FValue: string; + + class var FInstCnt: integer; + + class function Init(Cnt: integer): boolean; + class function DeInit(Cnt: integer): boolean; + + procedure SetValue(const Value: string); + + public + constructor Create; + destructor Destroy; override; + + function Convert(const Value: string): X; + + class property InstCnt: integer read FInstCnt; + + property PropId: integer read FId write FId; + property PropValue: string read FValue write SetValue; + + end; + + +// ----------------------------------------------------------------------------- +// TGenericClass +// ----------------------------------------------------------------------------- + + TGenericClass = class(TObject) + private type + TGenericInternalClass = class(TObject) + strict private + FName: string; + FId: T; + FValue: I; + + public + constructor Create; + destructor Destroy; override; + + procedure CopyTo(Dest: TGenericInternalClass); + + property Name: string read FName write FName; + property Id: T read FId write FId; + property Value: I read FValue write FValue; + end; + + strict private + FId: integer; + FValue: T; + + class var FInstCnt: integer; + + class function Init(Cnt: integer): boolean; + class function DeInit(Cnt: integer): boolean; + + procedure SetValue(const Value: T); + + public + constructor Create; + destructor Destroy; override; + + class property InstCnt: integer read FInstCnt; + + property PropId: integer read FId write FId; + property PropValue: T read FValue write SetValue; + + end; + + + +type +// ----------------------------------------------------------------------------- +// TEnum +// ----------------------------------------------------------------------------- + TEnum = (enMember1, enMember2, enMember3); + + TEnumHelper = record helper for TEnum + public + function ToString: string; + class function FromString(const AString: string): TEnum; static; + end; + + +// ----------------------------------------------------------------------------- +// TStdClassHelper +// ----------------------------------------------------------------------------- + TStdClassHelper = class helper for TStdClass + public + function AsString: string; + class function FromString(const AString: string): TStdClass; static; + end; + + + +// ----------------------------------------------------------------------------- +// Free routines +// ----------------------------------------------------------------------------- + +function FreeFunc2(const Param: integer): integer; + + + +implementation + +{R *.dfm} + + +// ----------------------------------------------------------------------------- +// Free routines +// ----------------------------------------------------------------------------- + +{ Free function 3 } + +function FreeFunc3(const Param: integer): integer; forward; + + + +{ Free function 1 } + +function FreeFunc(const Param: integer): integer; +begin + // +end; + + + +{ Free function 4 } + +procedure FreeFunc4(const Param: integer); forward; + + + +// ----------------------------------------------------------------------------- +// TStdClass +// ----------------------------------------------------------------------------- + +constructor TStdClass.Create; +begin + inherited; + + Init(Succ(InstCnt)); +end; + + +destructor TStdClass.Destroy; +begin + DeInit(Pred(InstCnt)); + + inherited; +end; + + +class function TStdClass.Init(Cnt: integer): boolean; +begin + FInstCnt := Cnt; +end; + + +class function TStdClass.DeInit(Cnt: integer): boolean; +begin + FInstCnt := Cnt; +end; + + +procedure TStdClass.SetValue(const Value: string); +begin + FValue := Value; +end; + + +function TStdClass.Convert(const Value: string): X; +begin + Result := ToType(Value); +end; + + + + +// ----------------------------------------------------------------------------- +// TStdClass.TStdInternalClass +// ----------------------------------------------------------------------------- + +constructor TStdClass.TStdInternalClass.Create; +begin + inherited; + + // +end; + + +destructor TStdClass.TStdInternalClass.Destroy; +begin + // + + inherited; +end; + + +procedure TStdClass.TStdInternalClass.CopyTo(Dest: TStdInternalClass); +begin + Dest.Name := Name; + Dest.Id := Id; +end; + + + +// ----------------------------------------------------------------------------- +// Free routines +// ----------------------------------------------------------------------------- + +{ Free function 2 with internal function preceeded by a comment } + +function FreeFunc2(const Param: integer): integer; + + // Internal routine + function FreeFunc2Internal: integer; + begin + // + end; + +begin + // +end; + + + +{ Free function 3 with internal procedure } + +function FreeFunc3: integer; + + procedure FreeFunc3Internal(const Param: integer); + begin + // + end; + +begin + // +end; + + + +{ Free procedure 4 with internal function } + +procedure FreeFunc4; + + function FreeFunc4Internal(const Param: integer): string; + begin + // + end; + +begin + // +end; + + + +{ Free procedure 5 with internal procedure preceeded by a comment } + +procedure FreeFunc5; + + // Internal routine + procedure FreeFunc5Internal; + begin + // + end; + +begin + // +end; + + + +// ----------------------------------------------------------------------------- +// TGenericClass +// ----------------------------------------------------------------------------- + +constructor TGenericClass.Create; +begin + inherited; + + Init(Succ(InstCnt)); +end; + + +destructor TGenericClass.Destroy; +begin + DeInit(Pred(InstCnt)); + + inherited; +end; + + +// This is a class function +class function TGenericClass.Init(Cnt: integer): boolean; + + // --------------------------------------------------------------------------- + // This is an inline function with surrounding comments + function InitStdInternalClass: integer; + begin + // + end; + // --------------------------------------------------------------------------- + + function ReInitStdInternalClass: integer; + begin + // This is an inline function without surrounding comments + end; + +// This is the main function's body +begin + FInstCnt := Cnt; +end; + + +// This is a class function +class function TGenericClass.DeInit(Cnt: integer): boolean; +begin + FInstCnt := Cnt; +end; + + +procedure TGenericClass.SetValue(const Value: T); +begin + FValue := Value; +end; + + + +// ----------------------------------------------------------------------------- +// TGenericClass.TGenericInternalClass +// ----------------------------------------------------------------------------- + +constructor TGenericClass.TGenericInternalClass.Create; +begin + inherited; + + FValue := ''; + FId := Default(T); + FName := Default(I); +end; + + +destructor TGenericClass.TGenericInternalClass.Destroy; +begin + // + + inherited; +end; + + +procedure TGenericClass.TGenericInternalClass.CopyTo(Dest: TGenericInternalClass); +begin + Dest.Name := Name; + Dest.Id := Id; + Dest.Value := Value; +end; + + + +// ----------------------------------------------------------------------------- +// TEnumHelper +// ----------------------------------------------------------------------------- + +function TEnumHelper.ToString: string; +begin + case Self of + enMember2: Result := 'Member 2'; + enMember3: Result := 'Member 3'; + else Result := 'Unknown'; + end; +end; + + +class function TEnumHelper.FromString(const AString: string): TEnum; +begin + if SameText(AString, 'Member 2') then + Result := enMember2 + + if SameText(AString, 'Member 3') then + Result := enMember3 + + else + Result := enMember1; +end; + + + +// ----------------------------------------------------------------------------- +// TStdClassHelper +// ----------------------------------------------------------------------------- + +function TStdClassHelper.AsString: string; +begin + Result := 'TStdClass instance'; +end; + + +class function TStdClassHelper.FromString(const AString: string): TStdClass; +begin + Result := TStdClass.Create.Convert(AString); +end; + + +end. diff --git a/PowerEditor/Test/FunctionList/pascal/unitTest.expected.result b/PowerEditor/Test/FunctionList/pascal/unitTest.expected.result new file mode 100644 index 000000000..74202abc3 --- /dev/null +++ b/PowerEditor/Test/FunctionList/pascal/unitTest.expected.result @@ -0,0 +1 @@ +{"leaves":["FreeFunc","FreeFunc","FreeFunc2","FreeFunc2Internal","FreeFunc3","FreeFunc3Internal","FreeFunc4","FreeFunc4Internal","FreeFunc5","FreeFunc5Internal","InitStdInternalClass","ReInitStdInternalClass"],"nodes":[{"leaves":["Create","Destroy","Init","DeInit","SetValue","Convert"],"name":"TStdClass"},{"leaves":["Create","Destroy","CopyTo"],"name":"TStdClass.TStdInternalClass"},{"leaves":["Create","Destroy","Init","DeInit","SetValue"],"name":"TGenericClass"},{"leaves":["Create","Destroy","CopyTo"],"name":"TGenericClass.TGenericInternalClass"},{"leaves":["ToString","FromString"],"name":"TEnumHelper"},{"leaves":["AsString","FromString"],"name":"TStdClassHelper"}],"root":"unitTest"} \ No newline at end of file diff --git a/PowerEditor/installer/functionList/pascal.xml b/PowerEditor/installer/functionList/pascal.xml new file mode 100644 index 000000000..e2719c132 --- /dev/null +++ b/PowerEditor/installer/functionList/pascal.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file