Make Pascal/Delphi functionList more efficient and more reliable
Fix #12808, close #12811
This commit is contained in:
parent
b280db88dc
commit
d476a894c2
|
@ -1,4 +1,4 @@
|
|||
unit Test;
|
||||
unit unitTest;
|
||||
|
||||
|
||||
interface
|
||||
|
@ -7,7 +7,7 @@ uses
|
|||
System.SysUtils, System.Types, System.Classes;
|
||||
|
||||
|
||||
function FreeFunc(const Param: integer): integer;
|
||||
function FreeFunc1(const Param: integer): integer;
|
||||
|
||||
|
||||
type
|
||||
|
@ -40,6 +40,7 @@ type
|
|||
|
||||
class function Init(Cnt: integer): boolean;
|
||||
class function DeInit(Cnt: integer): boolean;
|
||||
class function ToType<X: class, constructor>(const Value: string): X;
|
||||
|
||||
procedure SetValue(const Value: string);
|
||||
|
||||
|
@ -63,21 +64,21 @@ type
|
|||
|
||||
TGenericClass<T> = class(TObject)
|
||||
private type
|
||||
TGenericInternalClass<T, I> = class(TObject)
|
||||
TGenericInternalClass<I, K> = class(TObject)
|
||||
strict private
|
||||
FName: string;
|
||||
FId: T;
|
||||
FValue: I;
|
||||
FId: I;
|
||||
FValue: K;
|
||||
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
|
||||
procedure CopyTo<I>(Dest: TGenericInternalClass<T, I>);
|
||||
procedure CopyTo<J>(Dest: TGenericInternalClass<I, K>);
|
||||
|
||||
property Name: string read FName write FName;
|
||||
property Id: T read FId write FId;
|
||||
property Value: I read FValue write FValue;
|
||||
property Id: I read FId write FId;
|
||||
property Value: K read FValue write FValue;
|
||||
end;
|
||||
|
||||
strict private
|
||||
|
@ -132,18 +133,18 @@ type
|
|||
// Free routines
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function FreeFunc2(const Param: integer): integer;
|
||||
procedure FreeProc1(AParam: integer);
|
||||
|
||||
procedure Foo(AParam: integer);
|
||||
function Bar(const AParam: string): integer;
|
||||
function FreeFunc2(const AParam: string): integer;
|
||||
procedure FreeProc2(AParam: integer);
|
||||
|
||||
{function Unused1(ANum: double): cardinal;}
|
||||
{function UnusedFreeFunc1(ANum: double): cardinal;}
|
||||
|
||||
procedure Boo(AParam: integer);
|
||||
procedure FreeProc3(AParam: integer);
|
||||
|
||||
(*
|
||||
function Unused2(ANum: double): cardinal;
|
||||
function Unused3(ANum: double): cardinal;
|
||||
function UnusedFreeFunc2(ANum: double): cardinal;
|
||||
function UnusedFreeFunc3(ANum: double): cardinal;
|
||||
*)
|
||||
|
||||
|
||||
|
@ -157,64 +158,97 @@ implementation
|
|||
// Free routines
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
{ Free function 3 }
|
||||
|
||||
function FreeFunc3(const Param: integer): integer; forward;
|
||||
|
||||
|
||||
|
||||
{ Free function 1 }
|
||||
|
||||
function FreeFunc(const Param: integer): integer;
|
||||
function FreeFunc1(const Param: integer): integer;
|
||||
begin
|
||||
//
|
||||
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ Free procedure 1 }
|
||||
|
||||
procedure FreeProc1(AParam: integer);
|
||||
begin
|
||||
// Do something
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ Free function 2 }
|
||||
|
||||
function FreeFunc2(const AParam: string): integer;
|
||||
begin
|
||||
// Do something
|
||||
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
// Unused free function 1
|
||||
|
||||
function UnusedFreeFunc1(ANum: double): cardinal;
|
||||
begin
|
||||
// Do something
|
||||
|
||||
Result := 0;
|
||||
end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
{ Free procedure 2 }
|
||||
procedure FreeProc2(AParam: integer);
|
||||
begin
|
||||
// Do something
|
||||
end;
|
||||
|
||||
|
||||
|
||||
(*
|
||||
// Unused free function 2
|
||||
|
||||
function UnusedFreeFunc2(ANum: double): cardinal;
|
||||
begin
|
||||
// Do something
|
||||
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ Unused free function 3 }
|
||||
|
||||
function UnusedFreeFunc3(ANum: double): cardinal;
|
||||
begin
|
||||
// Do something
|
||||
|
||||
Result := 0;
|
||||
end;
|
||||
*)
|
||||
|
||||
|
||||
|
||||
{ Free procedure 3 }
|
||||
|
||||
procedure FreeProc3(AParam: integer);
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ Free function Foo }
|
||||
|
||||
procedure Foo(AParam: integer);
|
||||
begin
|
||||
// Do something
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ Free function Bar }
|
||||
|
||||
function Bar(const AParam: string): integer;
|
||||
begin
|
||||
// Do something
|
||||
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ Free function Test }
|
||||
function Test(Tnum: Double): DWord;
|
||||
begin
|
||||
// Do something
|
||||
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ Free function Boo }
|
||||
procedure Boo(AParam: integer);
|
||||
begin
|
||||
// Do something
|
||||
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ Free function 4 }
|
||||
|
||||
procedure FreeFunc4(const Param: integer); forward;
|
||||
procedure FreeProc4(const Param: integer); forward;
|
||||
|
||||
|
||||
|
||||
|
@ -241,12 +275,20 @@ end;
|
|||
class function TStdClass.Init(Cnt: integer): boolean;
|
||||
begin
|
||||
FInstCnt := Cnt;
|
||||
Result := true;
|
||||
end;
|
||||
|
||||
|
||||
class function TStdClass.DeInit(Cnt: integer): boolean;
|
||||
begin
|
||||
FInstCnt := Cnt;
|
||||
Result := true;
|
||||
end;
|
||||
|
||||
|
||||
class function TStdClass.ToType<X>(const Value: string): X;
|
||||
begin
|
||||
Result := X.Create;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -296,44 +338,32 @@ 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;
|
||||
function FreeFunc3(const Param: integer): integer;
|
||||
|
||||
procedure FreeFunc3Internal(const Param: integer);
|
||||
procedure InternalProc1(const Param: integer);
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
begin
|
||||
//
|
||||
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ Free procedure 4 with internal function }
|
||||
|
||||
procedure FreeFunc4;
|
||||
procedure FreeProc4(const Param: integer);
|
||||
|
||||
function FreeFunc4Internal(const Param: integer): string;
|
||||
function InternalFunc1(const Param: integer): string;
|
||||
begin
|
||||
//
|
||||
|
||||
Result := '';
|
||||
end;
|
||||
|
||||
begin
|
||||
|
@ -344,10 +374,10 @@ end;
|
|||
|
||||
{ Free procedure 5 with internal procedure preceeded by a comment }
|
||||
|
||||
procedure FreeFunc5;
|
||||
procedure FreeProc5;
|
||||
|
||||
// Internal routine
|
||||
procedure FreeFunc5Internal;
|
||||
procedure InternalProc2;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
@ -380,23 +410,9 @@ end;
|
|||
|
||||
// This is a class function
|
||||
class function TGenericClass<T>.Init<I>(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;
|
||||
Result := true;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -404,6 +420,7 @@ end;
|
|||
class function TGenericClass<T>.DeInit(Cnt: integer): boolean;
|
||||
begin
|
||||
FInstCnt := Cnt;
|
||||
Result := true;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -415,20 +432,20 @@ end;
|
|||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// TGenericClass<T>.TGenericInternalClass<T, I>
|
||||
// TGenericClass<T>.TGenericInternalClass<I, K>
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
constructor TGenericClass<T>.TGenericInternalClass<T, I>.Create;
|
||||
constructor TGenericClass<T>.TGenericInternalClass<I, K>.Create;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
FValue := '';
|
||||
FId := Default(T);
|
||||
FName := Default(I);
|
||||
FName := '';
|
||||
FId := Default(I);
|
||||
FValue := Default(K);
|
||||
end;
|
||||
|
||||
|
||||
destructor TGenericClass<T>.TGenericInternalClass<T, I>.Destroy;
|
||||
destructor TGenericClass<T>.TGenericInternalClass<I, K>.Destroy;
|
||||
begin
|
||||
//
|
||||
|
||||
|
@ -436,7 +453,7 @@ begin
|
|||
end;
|
||||
|
||||
|
||||
procedure TGenericClass<T>.TGenericInternalClass<T, I>.CopyTo<I>(Dest: TGenericInternalClass<T, I>);
|
||||
procedure TGenericClass<T>.TGenericInternalClass<I, K>.CopyTo<J>(Dest: TGenericInternalClass<I, K>);
|
||||
begin
|
||||
Dest.Name := Name;
|
||||
Dest.Id := Id;
|
||||
|
@ -464,7 +481,7 @@ begin
|
|||
if SameText(AString, 'Member 2') then
|
||||
Result := enMember2
|
||||
|
||||
if SameText(AString, 'Member 3') then
|
||||
else if SameText(AString, 'Member 3') then
|
||||
Result := enMember3
|
||||
|
||||
else
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"leaves":["FreeFunc","Foo","Bar","Test","Boo","FreeFunc2","FreeFunc2Internal","FreeFunc3","FreeFunc3Internal","FreeFunc4","FreeFunc4Internal","FreeFunc5","FreeFunc5Internal","InitStdInternalClass","ReInitStdInternalClass"],"nodes":[{"leaves":["Create","Destroy","Init","DeInit","SetValue","Convert<X>"],"name":"TStdClass"},{"leaves":["Create","Destroy","CopyTo"],"name":"TStdClass.TStdInternalClass"},{"leaves":["Create","Destroy","Init<I>","DeInit","SetValue"],"name":"TGenericClass<T>"},{"leaves":["Create","Destroy","CopyTo<I>"],"name":"TGenericClass<T>.TGenericInternalClass<T, I>"},{"leaves":["ToString","FromString"],"name":"TEnumHelper"},{"leaves":["AsString","FromString"],"name":"TStdClassHelper"}],"root":"unitTest"}
|
||||
{"leaves":["FreeFunc1","FreeProc1","FreeFunc2","FreeProc2","FreeProc3","FreeFunc3","InternalProc1","FreeProc4","InternalFunc1","FreeProc5","InternalProc2"],"nodes":[{"leaves":["Create","Destroy","Init","DeInit","ToType<X>","SetValue","Convert<X>"],"name":"TStdClass"},{"leaves":["Create","Destroy","CopyTo"],"name":"TStdClass.TStdInternalClass"},{"leaves":["Create","Destroy","Init<I>","DeInit","SetValue"],"name":"TGenericClass<T>"},{"leaves":["Create","Destroy","CopyTo<J>"],"name":"TGenericClass<T>.TGenericInternalClass<I, K>"},{"leaves":["ToString","FromString"],"name":"TEnumHelper"},{"leaves":["AsString","FromString"],"name":"TStdClassHelper"}],"root":"unitTest"}
|
||||
|
|
|
@ -8,81 +8,85 @@
|
|||
\=========================================================================== -->
|
||||
<NotepadPlus>
|
||||
<functionList>
|
||||
<!-- ====================================================== [ Pascal ] -->
|
||||
|
||||
<!-- ====================================================== [ Pascal ] -->
|
||||
<!-- ==================================================== [ Pascal ] -->
|
||||
|
||||
<parser
|
||||
displayName="Pascal"
|
||||
id ="pascal_syntax"
|
||||
commentExpr="(?x) # Utilize inline comments (see `RegEx - Pattern Modifiers`)
|
||||
(?s:\x7B.*?\x7D) # Multi Line Comment 1st variant
|
||||
(?m-s:\x2F{2}.*$) # Single Line Comment
|
||||
| (?s:\x7B.*?\x7D) # Multi Line Comment 1st variant
|
||||
| (?s:\x28\x2A.*?\x2A\x29) # Multi Line Comment 2nd variant
|
||||
| (?m-s:\x2F{2}.*$) # Single Line Comment
|
||||
| (?is:^\h*INTERFACE\h*$.*?^\h*IMPLEMENTATION\h*$) # Prevent matching procedure/function declarations in interface section of unit
|
||||
"
|
||||
>
|
||||
<classRange
|
||||
mainExpr="(?x) # Utilize inline comments (see `RegEx - Pattern Modifiers`)
|
||||
(?im-s) # multi-line mode on, single-line mode off
|
||||
^\h* # optional leading whitespace
|
||||
(?:
|
||||
(?: # indicator that following element exists on class level instead of instance level
|
||||
CLASS\s+
|
||||
)?
|
||||
(?:
|
||||
(?'CONSTRUCTOR_HEADER' # constructor
|
||||
CONSTRUCTOR
|
||||
)
|
||||
| # or
|
||||
(?'DESTRUCTOR_HEADER' # destructor
|
||||
DESTRUCTOR
|
||||
)
|
||||
| # or
|
||||
(?'PROCEDURE_HEADER' # procedure
|
||||
PROCEDURE
|
||||
)
|
||||
| # or
|
||||
(?'FUNCTION_HEADER' # function
|
||||
FUNCTION
|
||||
)
|
||||
| # or
|
||||
(?'OPERATOR_HEADER' # operator
|
||||
OPERATOR
|
||||
)
|
||||
(?'CONSTRUCTOR_HEADER' # constructor
|
||||
CONSTRUCTOR
|
||||
)
|
||||
| (?'DESTRUCTOR_HEADER' # or destructor
|
||||
DESTRUCTOR
|
||||
)
|
||||
| (?'PROCEDURE_HEADER' # or procedure
|
||||
PROCEDURE
|
||||
)
|
||||
| (?'FUNCTION_HEADER' # or function
|
||||
FUNCTION
|
||||
)
|
||||
| (?'OPERATOR_HEADER' # or operator
|
||||
OPERATOR
|
||||
)
|
||||
)\s+
|
||||
(?'CLASS_NAME' # class/interface name
|
||||
(?:[A-Z_]\w*(?:\s*<[^>]+>)?\s*\.\s*)+ # match nested classes too
|
||||
(?:
|
||||
[A-Z_]\w*
|
||||
(?: # match generic classes too
|
||||
\s*<[^>]+>
|
||||
)?
|
||||
\s*\.\s*
|
||||
)+ # match nested classes too
|
||||
)
|
||||
(?'METHOD_NAME' # method name
|
||||
[A-Z_]\w*(?:\s*<[^>]+>)?
|
||||
[A-Z_]\w*
|
||||
(?: # match generic methods too
|
||||
\s*<[^>]+>
|
||||
)?
|
||||
)
|
||||
(?'PARAM_LIST' # optional parameter list
|
||||
\s*\( # start-of-parameter-list indicator
|
||||
[^()]* # parameter list
|
||||
\) # end-of-parameter-list indicator
|
||||
\s*\( # start-of-parameter-list indicator
|
||||
[^()]* # parameter list
|
||||
\) # end-of-parameter-list indicator
|
||||
)?
|
||||
(?('CONSTRUCTOR_HEADER') # constructors don't have a return type
|
||||
\s*
|
||||
; # end-of-statement indicator
|
||||
; # end-of-statement indicator
|
||||
)
|
||||
(?('DESTRUCTOR_HEADER') # destructors don't have a return type
|
||||
\s*
|
||||
; # end-of-statement indicator
|
||||
; # end-of-statement indicator
|
||||
)
|
||||
(?('PROCEDURE_HEADER') # procedures don't have a return type
|
||||
\s*
|
||||
; # end-of-statement indicator
|
||||
; # end-of-statement indicator
|
||||
)
|
||||
(?('FUNCTION_HEADER') # functions have a return type
|
||||
\s*: # type indicator
|
||||
\s*[^;]+ # type identifier
|
||||
; # end-of-statement indicator
|
||||
\s*: # return type indicator
|
||||
\s*[^;]+ # return type identifier
|
||||
; # end-of-statement indicator
|
||||
)
|
||||
(?('OPERATOR_HEADER') # operators have a return type
|
||||
\s*: # type indicator
|
||||
\s*[^;]+ # type identifier
|
||||
; # end-of-statement indicator
|
||||
\s*: # type indicator
|
||||
\s*[^;]+ # type identifier
|
||||
; # end-of-statement indicator
|
||||
)
|
||||
"
|
||||
"
|
||||
>
|
||||
<className>
|
||||
<nameExpr expr="(?i)(?:(CONSTRUCTOR|DESTRUCTOR|PROCEDURE|FUNCTION|OPERATOR)\s+)\K(?:(?:[A-Z_]\w*(?:\s*<[^>]+>)?\s*\.\s*)+)(?:[A-Z_]\w*)" />
|
||||
|
@ -93,18 +97,27 @@
|
|||
mainExpr="(?x) # Utilize inline comments (see `RegEx - Pattern Modifiers`)
|
||||
(?im-s) # multi-line mode on, single-line mode off
|
||||
\s+
|
||||
(?'CLASS_NAME' # class/interface name
|
||||
(?:[A-Z_]\w*(?:\s*<[^>]+>)?\s*\.\s*)+
|
||||
( # class/interface name
|
||||
(?:
|
||||
[A-Z_]\w*
|
||||
(?: # match generic classes too
|
||||
\s*<[^>]+>
|
||||
)?
|
||||
\s*\.\s*
|
||||
)+ # match nested classes too
|
||||
)
|
||||
(?'METHOD_NAME' # method name
|
||||
[A-Z_]\w*(?:\s*<[^>]+>)?
|
||||
( # method name
|
||||
[A-Z_]\w*
|
||||
(?: # match generic methods too
|
||||
\s*<[^>]+>
|
||||
)?
|
||||
)
|
||||
(?'PARAM_LIST' # optional parameter list
|
||||
( # optional parameter list
|
||||
\s*\( # start-of-parameter-list indicator
|
||||
[^()]* # parameter list
|
||||
\) # end-of-parameter-list indicator
|
||||
)?
|
||||
"
|
||||
"
|
||||
>
|
||||
<functionName>
|
||||
<funcNameExpr expr="(?i)(?:(?:[A-Z_]\w*(?:\s*<[^>]+>)?\s*\.\s*)+)\K(?:[A-Z_]\w*(?:\s*<[^>]+>)?)(?:\s*\([^()]*\))*" />
|
||||
|
@ -117,32 +130,34 @@
|
|||
mainExpr="(?x) # Utilize inline comments (see `RegEx - Pattern Modifiers`)
|
||||
(?im-s) # multi-line mode on, single-line mode off
|
||||
^\h* # optional leading whitespace
|
||||
(?:
|
||||
(?:PROCEDURE\s+ # procedure
|
||||
([A-Z_]\w*)\s* # name
|
||||
(?: # optional parameter list
|
||||
\([^()]*\)
|
||||
)?\s*
|
||||
; # end-of-statement indicator
|
||||
)
|
||||
| (?:FUNCTION\s+ # or function
|
||||
([A-Z_]\w*)\s* # name
|
||||
(?: # optional parameter list
|
||||
\([^()]*\)
|
||||
)?\s*
|
||||
:\s*[^;]+ # return type
|
||||
; # end-of-statement indicator
|
||||
)
|
||||
)
|
||||
(?:
|
||||
(?:
|
||||
PROCEDURE\s+ # procedure
|
||||
([A-Z_]\w*)\s* # name
|
||||
(?: # optional parameter list
|
||||
\([^()]*\)
|
||||
)?
|
||||
\s*; # end-of-statement indicator
|
||||
)
|
||||
| (?:
|
||||
FUNCTION\s+ # or function
|
||||
([A-Z_]\w*)\s* # name
|
||||
(?: # optional parameter list
|
||||
\([^()]*\)
|
||||
)?
|
||||
\s*: # return type indicator
|
||||
\s*[^;]+ # return type identifier
|
||||
; # end-of-statement indicator
|
||||
)
|
||||
)
|
||||
(?:\s*OVERLOAD\s*;)? # function/procedure overloading
|
||||
(?:\s*(?:REGISTER|PASCAL|CDECL|STDCALL|SAFECALL)\s*;)? # calling convention
|
||||
(?: # external function from object file
|
||||
(?:\s*(?:VARARGS)\s*;) # variadic C function with cdecl calling convention
|
||||
| (?:\s*(?:EXTERNAL)\s+[^;]+;) # or normal function
|
||||
(?:\s*(?:VARARGS)\s*;) # variadic C function with cdecl calling convention
|
||||
| (?:\s*(?:EXTERNAL)\s+[^;]+;) # or normal function
|
||||
)?
|
||||
(?!
|
||||
(?s:.*?^\h*IMPLEMENTATION\s+) # prevent matching declarations in interface section of unit
|
||||
| (?:\s*FORWARD\s*;) # prevent matching forward declarations in implementation section of unit
|
||||
(?:\s*FORWARD\s*;) # prevent matching forward declarations in implementation section of unit
|
||||
)
|
||||
"
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue