2019-07-29 14:33:28 +02:00
|
|
|
unit DelphiUnit;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2019-07-29 16:01:27 +02:00
|
|
|
classes,
|
|
|
|
system.json,
|
|
|
|
System.SysUtils,
|
|
|
|
System.Rtti,
|
|
|
|
System.TypInfo,
|
2019-08-02 03:44:19 +02:00
|
|
|
System.Generics.Collections,
|
|
|
|
System.Generics.Defaults
|
2019-07-29 16:01:27 +02:00
|
|
|
;
|
2019-07-29 14:33:28 +02:00
|
|
|
|
|
|
|
type
|
|
|
|
TUnitTypeDefinition = class;
|
|
|
|
|
|
|
|
TUnitFieldDefinition = class
|
|
|
|
private
|
|
|
|
FFieldName: string;
|
|
|
|
FFieldType: string;
|
|
|
|
FAttributes: TStringList;
|
|
|
|
FDescription: string;
|
|
|
|
public
|
|
|
|
property FieldName: string read FFieldName write FFieldName;
|
|
|
|
property FieldType: string read FFieldType write FFieldType;
|
|
|
|
property Description: string read FDescription write FDescription;
|
|
|
|
procedure AddAttribute(const inAttribute: string);
|
|
|
|
function GenerateInterface: string;
|
|
|
|
constructor Create;
|
|
|
|
destructor Destroy; override;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TUnitParameter = class
|
|
|
|
private
|
|
|
|
FFlags: TParamFlags;
|
|
|
|
FType: TUnitTypeDefinition;
|
|
|
|
FParamName: string;
|
|
|
|
public
|
|
|
|
property ParamName: string read FParamName write FParamName;
|
|
|
|
property Flags: TParamFlags read FFlags write FFlags;
|
|
|
|
property ParamType: TUnitTypeDefinition read FType write FType;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TUnitMethod = class
|
|
|
|
private
|
|
|
|
FAttributes: TStringList;
|
|
|
|
FMethodKind: TMethodKind;
|
|
|
|
FVisibility: TMemberVisibility;
|
|
|
|
FName: string;
|
|
|
|
FIsStatic: Boolean;
|
|
|
|
FIsClassMethod: Boolean;
|
|
|
|
FReturnType: TUnitTypeDefinition;
|
|
|
|
FParams: TObjectList<TUnitParameter>;
|
|
|
|
FVars: TObjectList<TUnitParameter>;
|
|
|
|
FContent: TStringList;
|
2019-08-02 03:44:19 +02:00
|
|
|
function MethodKindToDelphiString(var LHasReturn: Boolean): string;
|
|
|
|
procedure ParametersToDelphiString(var LParamString: string);
|
|
|
|
procedure MethodLocalVarsToDelphiString(LFuncSL: TStringList);
|
|
|
|
function GetIsConstructor: Boolean;
|
|
|
|
function GetIsDestructor: Boolean;
|
2019-07-29 14:33:28 +02:00
|
|
|
public
|
|
|
|
property Content: TStringList read FContent write FContent;
|
|
|
|
property MethodKind: TMethodKind read FMethodKind write FMethodKind;
|
|
|
|
property Visibility: TMemberVisibility read FVisibility write FVisibility;
|
|
|
|
property Name: string read FName write FName;
|
2019-08-02 03:44:19 +02:00
|
|
|
property IsConstructor: Boolean read GetIsConstructor;
|
|
|
|
property IsDestructor: Boolean read GetIsDestructor;
|
2019-07-29 14:33:28 +02:00
|
|
|
property IsClassMethod: Boolean read FIsClassMethod write FIsClassMethod;
|
|
|
|
// Static: No 'Self' parameter
|
|
|
|
property IsStatic: Boolean read FIsStatic write FIsStatic;
|
|
|
|
property ReturnType: TUnitTypeDefinition read FReturnType write FReturnType;
|
|
|
|
function GetParameters: TArray<TUnitParameter>;
|
|
|
|
procedure AddParameter(param: TUnitParameter);
|
|
|
|
procedure AddLocalVariable(inVar: TUnitParameter);
|
|
|
|
procedure AddAttribute(const inAttribute: string);
|
|
|
|
function GenerateInterface: string;
|
|
|
|
function GenerateImplementation(inOnType: TUnitTypeDefinition): string;
|
|
|
|
constructor Create;
|
|
|
|
destructor Destroy; override;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TUnitTypeDefinition = class
|
|
|
|
private
|
|
|
|
FTypeName: string;
|
|
|
|
FTypeInheritedFrom: string;
|
|
|
|
FAttributes: TStringList;
|
2019-08-02 11:48:38 +02:00
|
|
|
FTypeKind: TTypeKind;
|
|
|
|
FForwardDeclare: Boolean;
|
|
|
|
FGuid : TGUID;
|
2019-07-29 14:33:28 +02:00
|
|
|
public
|
|
|
|
Fields: TObjectList<TUnitFieldDefinition>;
|
|
|
|
FMethods: TObjectList<TUnitMethod>;
|
2019-08-02 11:48:38 +02:00
|
|
|
property Guid: TGUID read FGuid write FGuid;
|
2019-07-29 14:33:28 +02:00
|
|
|
property TypeName: string read FTypeName write FTypeName;
|
2019-08-02 11:48:38 +02:00
|
|
|
property TypeKind: TTypeKind read FTypeKind write FTypeKind;
|
2019-07-29 14:33:28 +02:00
|
|
|
property TypeInherited: string read FTypeInheritedFrom write FTypeInheritedFrom;
|
2019-08-02 11:48:38 +02:00
|
|
|
property ForwardDeclare: Boolean read FForwardDeclare write FForwardDeclare;
|
2019-07-29 14:33:28 +02:00
|
|
|
function GetMethods(): TArray<TUnitMethod>;
|
|
|
|
procedure AddAttribute(const inAttribute: string);
|
|
|
|
function GenerateInterface: string;
|
2019-08-02 11:48:38 +02:00
|
|
|
function GenerateForwardInterface: string;
|
2019-07-29 14:33:28 +02:00
|
|
|
constructor Create;
|
|
|
|
destructor Destroy; override;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TDelphiUnit = class
|
|
|
|
private
|
|
|
|
FInterfaceUses: TStringList;
|
|
|
|
FImplementationUses: TStringList;
|
2019-08-02 08:59:54 +02:00
|
|
|
FInterfaceConstant: TStringList;
|
|
|
|
FImplementationConstant: TStringList;
|
2019-07-29 14:33:28 +02:00
|
|
|
FUnitName: string;
|
2019-08-02 03:44:19 +02:00
|
|
|
FTitle: String;
|
|
|
|
FDescription: string;
|
|
|
|
FLicense: string;
|
2019-07-29 14:33:28 +02:00
|
|
|
public
|
|
|
|
TypeDefinitions: TObjectList<TUnitTypeDefinition>;
|
|
|
|
function GenerateInterfaceSectionStart: string; virtual;
|
|
|
|
function GenerateInterfaceUses: string; virtual;
|
|
|
|
function GenerateImplementationSectionStart: string; virtual;
|
|
|
|
function GenerateImplementationUses: string; virtual;
|
2019-08-02 08:59:54 +02:00
|
|
|
function GenerateImplementationConstants: string; virtual;
|
2019-08-02 11:48:38 +02:00
|
|
|
function CreateGUID: TGuid;
|
2019-07-29 14:33:28 +02:00
|
|
|
public
|
|
|
|
property UnitFile: string read FUnitName write FUnitName;
|
2019-08-02 03:44:19 +02:00
|
|
|
property Title: String read FTitle write FTitle;
|
|
|
|
property Description: string read FDescription write FDescription;
|
|
|
|
property License: string read FLicense write FLicense;
|
2019-07-29 14:33:28 +02:00
|
|
|
procedure AddInterfaceUnit(const inFilename: string); virtual;
|
2019-08-02 08:59:54 +02:00
|
|
|
procedure AddInterfaceConstant(const inName:string; const inValue:string);
|
2019-07-29 14:33:28 +02:00
|
|
|
procedure AddImplementationUnit(const inFilename: string); virtual;
|
2019-08-02 08:59:54 +02:00
|
|
|
procedure AddImplementationConstant(const inName:string; const inValue:string);
|
2019-07-29 14:33:28 +02:00
|
|
|
procedure AddType(inTypeInfo: TUnitTypeDefinition);
|
2019-08-02 03:44:19 +02:00
|
|
|
procedure SortTypeDefinitions;
|
|
|
|
function Generate: string;
|
2019-07-29 14:33:28 +02:00
|
|
|
constructor Create; virtual;
|
|
|
|
destructor Destroy; override;
|
|
|
|
end;
|
|
|
|
|
2019-08-02 08:59:54 +02:00
|
|
|
|
2019-07-29 14:33:28 +02:00
|
|
|
implementation
|
|
|
|
|
2019-08-02 03:44:19 +02:00
|
|
|
function DelphiVarName(const inVarname: string):string;
|
|
|
|
begin
|
|
|
|
Result := inVarname;
|
|
|
|
if Result.ToLower = 'type' then
|
|
|
|
Result := '&' + Result
|
|
|
|
else if Result.ToLower = 'file' then
|
|
|
|
Result := '&' + Result;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2019-07-29 14:33:28 +02:00
|
|
|
{ TDelphiUnit }
|
|
|
|
|
2019-08-02 08:59:54 +02:00
|
|
|
procedure TDelphiUnit.AddImplementationConstant(const inName, inValue: string);
|
|
|
|
begin
|
|
|
|
FImplementationConstant.AddPair(inName, inValue);
|
|
|
|
end;
|
|
|
|
|
2019-07-29 14:33:28 +02:00
|
|
|
procedure TDelphiUnit.AddImplementationUnit(const inFilename: string);
|
|
|
|
var
|
|
|
|
IntIndex : Integer;
|
|
|
|
begin
|
|
|
|
IntIndex := FInterfaceUses.IndexOf(inFilename);
|
|
|
|
if IntIndex < 0 then
|
|
|
|
FImplementationUses.Add(inFilename);
|
|
|
|
end;
|
|
|
|
|
2019-08-02 08:59:54 +02:00
|
|
|
procedure TDelphiUnit.AddInterfaceConstant(const inName, inValue: string);
|
|
|
|
begin
|
|
|
|
FInterfaceConstant.AddPair(inName, inValue);
|
|
|
|
end;
|
|
|
|
|
2019-07-29 14:33:28 +02:00
|
|
|
procedure TDelphiUnit.AddInterfaceUnit(const inFilename: string);
|
|
|
|
var
|
|
|
|
ImpIndex : Integer;
|
|
|
|
begin
|
|
|
|
ImpIndex := FImplementationUses.IndexOf(inFilename);
|
|
|
|
if ImpIndex >= 0 then
|
|
|
|
FImplementationUses.Delete(ImpIndex);
|
|
|
|
|
|
|
|
FInterfaceUses.Add(inFilename);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TDelphiUnit.AddType(inTypeInfo: TUnitTypeDefinition);
|
|
|
|
begin
|
|
|
|
TypeDefinitions.Add(inTypeInfo);
|
|
|
|
end;
|
|
|
|
|
|
|
|
constructor TDelphiUnit.Create;
|
|
|
|
begin
|
|
|
|
FInterfaceUses := TStringList.Create;
|
|
|
|
FInterfaceUses.Duplicates := dupIgnore;
|
2019-08-02 08:59:54 +02:00
|
|
|
FInterfaceConstant := TStringList.Create;
|
|
|
|
FInterfaceConstant.Duplicates := dupIgnore;
|
|
|
|
FImplementationConstant := TStringList.Create;
|
|
|
|
FImplementationConstant.Duplicates := dupIgnore;
|
2019-07-29 14:33:28 +02:00
|
|
|
FImplementationUses := TStringList.Create;
|
|
|
|
FImplementationUses.Duplicates := dupIgnore;
|
|
|
|
TypeDefinitions := TObjectList<TUnitTypeDefinition>.Create;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TDelphiUnit.Destroy;
|
|
|
|
begin
|
|
|
|
FreeAndNil(FInterfaceUses);
|
|
|
|
FreeAndNil(FImplementationUses);
|
2019-08-02 08:59:54 +02:00
|
|
|
FreeAndNil(FInterfaceConstant);
|
|
|
|
FreeAndNil(FImplementationConstant);
|
2019-07-29 14:33:28 +02:00
|
|
|
FreeAndNil(TypeDefinitions);
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2019-08-02 08:59:54 +02:00
|
|
|
function TDelphiUnit.GenerateImplementationConstants: string;
|
|
|
|
var
|
|
|
|
SL : TStringList;
|
|
|
|
i : Integer;
|
|
|
|
begin
|
|
|
|
SL := TStringList.Create;
|
|
|
|
try
|
|
|
|
if FImplementationConstant.Count > 0 then
|
|
|
|
begin
|
|
|
|
SL.Add('const');
|
|
|
|
for i := 0 to FImplementationConstant.Count - 1 do
|
|
|
|
begin
|
|
|
|
SL.Add(' ' + FImplementationConstant.Names[i] + ' = ' + FImplementationConstant.ValueFromIndex[i] + ';');
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
Result := SL.Text;
|
|
|
|
finally
|
|
|
|
FreeAndNil(SL);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2019-07-29 14:33:28 +02:00
|
|
|
function TDelphiUnit.GenerateImplementationSectionStart: string;
|
|
|
|
var
|
2019-07-29 16:01:27 +02:00
|
|
|
LImplementationSection: TStringList;
|
2019-07-29 14:33:28 +02:00
|
|
|
begin
|
2019-07-29 16:01:27 +02:00
|
|
|
LImplementationSection := TStringList.Create;
|
2019-07-29 14:33:28 +02:00
|
|
|
try
|
2019-07-29 16:01:27 +02:00
|
|
|
LImplementationSection.Add('');
|
|
|
|
LImplementationSection.Add('implementation');
|
|
|
|
LImplementationSection.Add('');
|
|
|
|
Result := LImplementationSection.Text;
|
2019-07-29 14:33:28 +02:00
|
|
|
finally
|
2019-07-29 16:01:27 +02:00
|
|
|
FreeAndNil(LImplementationSection);
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TDelphiUnit.GenerateImplementationUses: string;
|
|
|
|
var
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL: TStringList;
|
2019-07-29 14:33:28 +02:00
|
|
|
i: Integer;
|
|
|
|
begin
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL := TStringList.Create;
|
2019-07-29 14:33:28 +02:00
|
|
|
try
|
|
|
|
if FImplementationUses.Count > 0 then
|
|
|
|
begin
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL.Add('uses');
|
2019-07-29 14:33:28 +02:00
|
|
|
for i := 0 to FImplementationUses.Count - 1 do
|
|
|
|
begin
|
|
|
|
if i = 0 then
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL.Add(' ' + FImplementationUses[i])
|
2019-07-29 14:33:28 +02:00
|
|
|
else
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL.Add(' , ' + FImplementationUses[i]);
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL.Add(' ;');
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL.Add('');
|
|
|
|
Result := LUsesSL.Text;
|
2019-07-29 14:33:28 +02:00
|
|
|
finally
|
2019-07-29 16:01:27 +02:00
|
|
|
FreeAndNil(LUsesSL);
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TDelphiUnit.GenerateInterfaceSectionStart: string;
|
|
|
|
var
|
2019-07-29 16:01:27 +02:00
|
|
|
LInterfaceSection: TStringList;
|
2019-07-29 14:33:28 +02:00
|
|
|
begin
|
2019-07-29 16:01:27 +02:00
|
|
|
LInterfaceSection := TStringList.Create;
|
2019-07-29 14:33:28 +02:00
|
|
|
try
|
2019-07-29 16:01:27 +02:00
|
|
|
LInterfaceSection.Add('unit ' + UnitFile + ';');
|
|
|
|
LInterfaceSection.Add('');
|
|
|
|
LInterfaceSection.Add('interface');
|
|
|
|
LInterfaceSection.Add('');
|
|
|
|
Result := LInterfaceSection.Text;
|
2019-07-29 14:33:28 +02:00
|
|
|
finally
|
2019-07-29 16:01:27 +02:00
|
|
|
FreeAndNil(LInterfaceSection);
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TDelphiUnit.GenerateInterfaceUses: string;
|
|
|
|
var
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL: TStringList;
|
2019-07-29 14:33:28 +02:00
|
|
|
i: Integer;
|
|
|
|
begin
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL := TStringList.Create;
|
2019-07-29 14:33:28 +02:00
|
|
|
try
|
|
|
|
if FInterfaceUses.Count > 0 then
|
|
|
|
begin
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL.Add('uses');
|
2019-07-29 14:33:28 +02:00
|
|
|
for i := 0 to FInterfaceUses.Count - 1 do
|
|
|
|
begin
|
|
|
|
if i = 0 then
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL.Add(' ' + FInterfaceUses[i])
|
2019-07-29 14:33:28 +02:00
|
|
|
else
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL.Add(' , ' + FInterfaceUses[i]);
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL.Add(' ;');
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
2019-07-29 16:01:27 +02:00
|
|
|
LUsesSL.Add('');
|
|
|
|
Result := LUsesSL.Text;
|
2019-07-29 14:33:28 +02:00
|
|
|
finally
|
2019-07-29 16:01:27 +02:00
|
|
|
FreeAndNil(LUsesSL);
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2019-08-02 03:44:19 +02:00
|
|
|
function TDelphiUnit.Generate:string;
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
j: Integer;
|
|
|
|
LMethod: TUnitMethod;
|
|
|
|
LMvcFile: TStringList;
|
2019-08-02 11:48:38 +02:00
|
|
|
LForwardAlreadyDeclared : Boolean;
|
2019-08-02 03:44:19 +02:00
|
|
|
begin
|
2019-08-02 11:48:38 +02:00
|
|
|
LForwardAlreadyDeclared := False;
|
2019-08-02 03:44:19 +02:00
|
|
|
LMvcFile := TStringList.Create;
|
|
|
|
try
|
|
|
|
LMvcFile.Add(GenerateInterfaceSectionStart);
|
|
|
|
LMvcFile.Add(GenerateInterfaceUses);
|
|
|
|
LMvcFile.Add('(*');
|
|
|
|
LMvcFile.Add('Title: ' + Title);
|
|
|
|
LMvcFile.Add('Description: ' + Description);
|
|
|
|
LMvcFile.Add('License: ' + License);
|
|
|
|
LMvcFile.Add('*)');
|
|
|
|
LMvcFile.Add('');
|
|
|
|
LMvcFile.Add('type');
|
|
|
|
|
|
|
|
SortTypeDefinitions;
|
|
|
|
|
2019-08-02 08:59:54 +02:00
|
|
|
if FInterfaceConstant.Count > 0 then
|
|
|
|
begin
|
|
|
|
LMvcFile.Add('const');
|
|
|
|
for i := 0 to FInterfaceConstant.Count - 1 do
|
|
|
|
begin
|
|
|
|
LMvcFile.Add(' ' + FInterfaceConstant.Names[i] + ' = ' + FInterfaceConstant.ValueFromIndex[i] + ';');
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2019-08-02 11:48:38 +02:00
|
|
|
for i := 0 to TypeDefinitions.Count - 1 do
|
|
|
|
begin
|
|
|
|
if TypeDefinitions[i].ForwardDeclare then
|
|
|
|
begin
|
|
|
|
if not LForwardAlreadyDeclared then
|
|
|
|
LMvcFile.Add(' // Forward Declarations');
|
|
|
|
LMvcFile.Add(TypeDefinitions[i].GenerateForwardInterface);
|
|
|
|
LForwardAlreadyDeclared := True;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2019-08-02 03:44:19 +02:00
|
|
|
for i := 0 to TypeDefinitions.Count - 1 do
|
|
|
|
begin
|
|
|
|
LMvcFile.Add(TypeDefinitions[i].GenerateInterface);
|
|
|
|
end;
|
2019-08-02 08:59:54 +02:00
|
|
|
|
2019-08-02 03:44:19 +02:00
|
|
|
LMvcFile.Add(GenerateImplementationSectionStart);
|
|
|
|
LMvcFile.Add(GenerateImplementationUses);
|
|
|
|
LMvcFile.Add('');
|
2019-08-02 08:59:54 +02:00
|
|
|
GenerateImplementationConstants;
|
2019-08-02 03:44:19 +02:00
|
|
|
for j := 0 to TypeDefinitions.Count - 1 do
|
|
|
|
begin
|
|
|
|
for LMethod in TypeDefinitions[j].GetMethods do
|
|
|
|
begin
|
|
|
|
LMvcFile.Add(LMethod.GenerateImplementation(TypeDefinitions[j]));
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
LMvcFile.Add('end.');
|
|
|
|
Result := LMvcFile.Text;
|
|
|
|
finally
|
|
|
|
FreeAndNil(LMvcFile);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2019-08-02 11:48:38 +02:00
|
|
|
function TDelphiUnit.CreateGUID:TGuid;
|
|
|
|
var
|
|
|
|
guid : TGUID;
|
|
|
|
begin
|
|
|
|
System.SysUtils.CreateGuid(guid);
|
|
|
|
Result := guid;
|
|
|
|
end;
|
|
|
|
|
2019-08-02 03:44:19 +02:00
|
|
|
procedure TDelphiUnit.SortTypeDefinitions;
|
|
|
|
begin
|
|
|
|
{ TODO : Make this much more advanced to handle dependency ordering of declarations }
|
|
|
|
|
|
|
|
TypeDefinitions.Sort(TComparer<TUnitTypeDefinition>.Construct(function (const L, R: TUnitTypeDefinition): integer
|
|
|
|
begin
|
|
|
|
if L.TypeName = 'TMyMVCController' then
|
|
|
|
Result := 1
|
|
|
|
else if R.TypeName = 'TMyMVCController' then
|
|
|
|
Result := -1
|
|
|
|
else
|
|
|
|
Result := CompareText(L.TypeName, R.TypeName);
|
|
|
|
end));
|
|
|
|
end;
|
|
|
|
|
2019-07-29 14:33:28 +02:00
|
|
|
{ TTypeDefinition }
|
|
|
|
|
|
|
|
procedure TUnitTypeDefinition.AddAttribute(const inAttribute: string);
|
|
|
|
begin
|
|
|
|
FAttributes.Add(inAttribute);
|
|
|
|
end;
|
|
|
|
|
|
|
|
constructor TUnitTypeDefinition.Create;
|
|
|
|
begin
|
|
|
|
FAttributes := TStringList.Create;
|
|
|
|
Fields := TObjectList<TUnitFieldDefinition>.Create;
|
|
|
|
FMethods := TObjectList<TUnitMethod>.Create;
|
2019-08-02 11:48:38 +02:00
|
|
|
FTypeKind := tkClass;
|
|
|
|
FForwardDeclare := False;
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TUnitTypeDefinition.Destroy;
|
|
|
|
begin
|
|
|
|
FreeAndNil(FAttributes);
|
|
|
|
FreeAndNil(Fields);
|
|
|
|
FreeAndNil(FMethods);
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2019-08-02 11:48:38 +02:00
|
|
|
function TUnitTypeDefinition.GenerateForwardInterface: string;
|
|
|
|
begin
|
|
|
|
if FTypeKind = tkClass then
|
|
|
|
Result := ' ' + TypeName + ' : class;'
|
|
|
|
else if FTypeKind = tkInterface then
|
|
|
|
Result := ' ' + TypeName + ' : interface;'
|
|
|
|
else
|
|
|
|
Result := ' ' + TypeName + 'xxxx';
|
|
|
|
end;
|
|
|
|
|
2019-07-29 14:33:28 +02:00
|
|
|
function TUnitTypeDefinition.GenerateInterface: string;
|
|
|
|
var
|
2019-07-29 16:01:27 +02:00
|
|
|
LInterfaceSL: TStringList;
|
2019-07-29 14:33:28 +02:00
|
|
|
i: Integer;
|
|
|
|
j: Integer;
|
|
|
|
begin
|
2019-07-29 16:01:27 +02:00
|
|
|
LInterfaceSL := TStringList.Create;
|
2019-07-29 14:33:28 +02:00
|
|
|
try
|
|
|
|
for i := 0 to FAttributes.Count - 1 do
|
|
|
|
begin
|
2019-07-29 16:01:27 +02:00
|
|
|
LInterfaceSL.Add(FAttributes[i]);
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
2019-08-02 11:48:38 +02:00
|
|
|
if FTypeKind = tkClass then
|
|
|
|
begin
|
|
|
|
if TypeInherited.Length > 0 then
|
|
|
|
LInterfaceSL.Add(' ' + TypeName + ' = class(' + TypeInherited + ')')
|
|
|
|
else
|
|
|
|
LInterfaceSL.Add(' ' + TypeName + ' = class');
|
|
|
|
end
|
|
|
|
else if FTypeKind = tkInterface then
|
|
|
|
begin
|
|
|
|
if TypeInherited.Length > 0 then
|
|
|
|
begin
|
|
|
|
LInterfaceSL.Add(' ' + TypeName + ' = interface(' + TypeInherited + ')');
|
|
|
|
LInterfaceSL.Add(' [' + GUIDToString(FGuid).QuotedString + ']');
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
LInterfaceSL.Add(' ' + TypeName + ' = interface');
|
|
|
|
LInterfaceSL.Add(' [' + GUIDToString(FGuid).QuotedString + ']');
|
|
|
|
end;
|
|
|
|
end;
|
2019-07-29 14:33:28 +02:00
|
|
|
|
|
|
|
for j := 0 to Fields.Count - 1 do
|
|
|
|
begin
|
2019-07-29 16:01:27 +02:00
|
|
|
LInterfaceSL.Add(Fields[j].GenerateInterface);
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
|
|
|
|
|
|
|
for j := 0 to FMethods.Count - 1 do
|
|
|
|
begin
|
2019-07-29 16:01:27 +02:00
|
|
|
LInterfaceSL.Add(TrimRight(FMethods[j].GenerateInterface));
|
|
|
|
LInterfaceSL.Add('');
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
|
|
|
|
2019-07-29 16:01:27 +02:00
|
|
|
LInterfaceSL.Add(' end;');
|
2019-07-29 14:33:28 +02:00
|
|
|
|
2019-07-29 16:01:27 +02:00
|
|
|
Result := LInterfaceSL.Text;
|
2019-07-29 14:33:28 +02:00
|
|
|
finally
|
2019-07-29 16:01:27 +02:00
|
|
|
FreeAndNil(LInterfaceSL);
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TUnitTypeDefinition.GetMethods: TArray<TUnitMethod>;
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
begin
|
|
|
|
SetLength(Result, FMethods.Count);
|
|
|
|
for i := 0 to FMethods.Count - 1 do
|
|
|
|
begin
|
|
|
|
Result[i] := FMethods[i];
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ TFieldDefinition }
|
|
|
|
|
|
|
|
procedure TUnitFieldDefinition.AddAttribute(const inAttribute: string);
|
|
|
|
begin
|
|
|
|
FAttributes.Add(inAttribute);
|
|
|
|
end;
|
|
|
|
|
|
|
|
constructor TUnitFieldDefinition.Create;
|
|
|
|
begin
|
|
|
|
FAttributes := TStringList.Create;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TUnitFieldDefinition.Destroy;
|
|
|
|
begin
|
|
|
|
FreeAndNil(FAttributes);
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TUnitFieldDefinition.GenerateInterface: string;
|
|
|
|
var
|
2019-08-02 03:44:19 +02:00
|
|
|
i : Integer;
|
|
|
|
SL : TStringList;
|
|
|
|
LType : string;
|
2019-07-29 14:33:28 +02:00
|
|
|
begin
|
|
|
|
SL := TStringList.Create;
|
|
|
|
try
|
2019-08-02 03:44:19 +02:00
|
|
|
LType := FFieldType;
|
2019-07-29 14:33:28 +02:00
|
|
|
for i := 0 to FAttributes.Count - 1 do
|
|
|
|
begin
|
|
|
|
SL.Add(' ' + FAttributes[i]);
|
|
|
|
end;
|
2019-08-02 03:44:19 +02:00
|
|
|
|
2019-07-29 14:33:28 +02:00
|
|
|
if Description.Length > 0 then
|
|
|
|
SL.Add(' [MVCDoc(' + QuotedStr(Description) + ')]');
|
|
|
|
|
2019-08-02 03:44:19 +02:00
|
|
|
SL.Add(' ' + DelphiVarName(FFieldName) + ' : ' + LType + ';');
|
2019-07-29 14:33:28 +02:00
|
|
|
Result := SL.Text;
|
|
|
|
finally
|
|
|
|
FreeAndNil(SL);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ TUnitMethod }
|
|
|
|
|
|
|
|
procedure TUnitMethod.AddAttribute(const inAttribute: string);
|
|
|
|
begin
|
|
|
|
FAttributes.Add(inAttribute);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TUnitMethod.AddLocalVariable(inVar: TUnitParameter);
|
|
|
|
begin
|
|
|
|
FVars.Add(inVar);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TUnitMethod.AddParameter(param: TUnitParameter);
|
|
|
|
begin
|
|
|
|
FParams.Add(param);
|
|
|
|
end;
|
|
|
|
|
|
|
|
constructor TUnitMethod.Create;
|
|
|
|
begin
|
|
|
|
FParams := TObjectList<TUnitParameter>.Create;
|
|
|
|
FAttributes := TStringList.Create;
|
|
|
|
FVars := TObjectList<TUnitParameter>.Create;
|
|
|
|
FContent := TStringList.Create;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TUnitMethod.Destroy;
|
|
|
|
begin
|
|
|
|
FreeAndNil(FParams);
|
|
|
|
FreeAndNil(FAttributes);
|
|
|
|
FreeAndNil(FVars);
|
|
|
|
FreeAndNil(FContent);
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2019-08-02 03:44:19 +02:00
|
|
|
procedure TUnitMethod.MethodLocalVarsToDelphiString(LFuncSL: TStringList);
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
begin
|
|
|
|
if FVars.Count > 0 then
|
|
|
|
begin
|
|
|
|
LFuncSL.Add('var');
|
|
|
|
for i := 0 to FVars.Count - 1 do
|
|
|
|
begin
|
|
|
|
LFuncSL.Add(' ' + FVars[i].ParamName + ' : ' + FVars[i].ParamType.TypeName + ';');
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TUnitMethod.ParametersToDelphiString(var LParamString: string);
|
2019-07-29 14:33:28 +02:00
|
|
|
var
|
2019-07-29 16:01:27 +02:00
|
|
|
LParam: TUnitParameter;
|
|
|
|
LParamFlagString: string;
|
2019-08-02 03:44:19 +02:00
|
|
|
LParamName: string;
|
|
|
|
begin
|
|
|
|
LParamString := '(';
|
|
|
|
for LParam in GetParameters do
|
|
|
|
begin
|
|
|
|
LParamFlagString := '';
|
|
|
|
if pfConst in LParam.Flags then
|
|
|
|
LParamFlagString := 'const'
|
|
|
|
else if pfVar in LParam.Flags then
|
|
|
|
LParamFlagString := 'var'
|
|
|
|
else if pfOut in LParam.Flags then
|
|
|
|
LParamFlagString := 'out'
|
|
|
|
else if pfArray in LParam.Flags then
|
|
|
|
LParamFlagString := 'array of';
|
|
|
|
if LParamFlagString.Length > 0 then
|
|
|
|
LParamFlagString := LParamFlagString + ' ';
|
|
|
|
|
|
|
|
LParamName := DelphiVarName(LParam.ParamName);
|
|
|
|
LParamString := LParamString + LParamFlagString + LParamName + ': ' + LParam.FType.FTypeName + '; ';
|
|
|
|
end;
|
|
|
|
if LParamString.EndsWith('; ') then
|
|
|
|
LParamString := LParamString.Remove(LParamString.Length - 2);
|
|
|
|
LParamString := LParamString + ')';
|
|
|
|
if LParamString = '()' then
|
|
|
|
LParamString := '';
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TUnitMethod.MethodKindToDelphiString(var LHasReturn: Boolean): string;
|
2019-07-29 14:33:28 +02:00
|
|
|
begin
|
|
|
|
case MethodKind of
|
|
|
|
mkProcedure:
|
2019-08-02 03:44:19 +02:00
|
|
|
Result := 'procedure';
|
2019-07-29 14:33:28 +02:00
|
|
|
mkFunction:
|
|
|
|
begin
|
2019-08-02 03:44:19 +02:00
|
|
|
Result := 'function';
|
2019-07-29 16:01:27 +02:00
|
|
|
LHasReturn := True;
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
|
|
|
mkDestructor:
|
2019-08-02 03:44:19 +02:00
|
|
|
Result := 'destructor';
|
2019-07-29 14:33:28 +02:00
|
|
|
mkConstructor:
|
2019-08-02 03:44:19 +02:00
|
|
|
Result := 'constructor';
|
2019-07-29 14:33:28 +02:00
|
|
|
mkClassFunction:
|
|
|
|
begin
|
2019-08-02 03:44:19 +02:00
|
|
|
Result := 'class function';
|
2019-07-29 16:01:27 +02:00
|
|
|
LHasReturn := True;
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
|
|
|
mkClassProcedure:
|
2019-08-02 03:44:19 +02:00
|
|
|
Result := 'class procedure';
|
2019-07-29 14:33:28 +02:00
|
|
|
mkClassConstructor:
|
2019-08-02 03:44:19 +02:00
|
|
|
Result := 'class constructor';
|
2019-07-29 14:33:28 +02:00
|
|
|
mkClassDestructor:
|
2019-08-02 03:44:19 +02:00
|
|
|
Result := 'class destructor';
|
2019-07-29 14:33:28 +02:00
|
|
|
else
|
2019-08-02 03:44:19 +02:00
|
|
|
Result := 'unknown';
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
2019-08-02 03:44:19 +02:00
|
|
|
end;
|
|
|
|
|
|
|
|
function TUnitMethod.GenerateImplementation(inOnType: TUnitTypeDefinition): string;
|
|
|
|
var
|
|
|
|
LProcTypeString: string;
|
|
|
|
LHasReturn: Boolean;
|
|
|
|
LParamString: string;
|
|
|
|
LClassNameProcIn: string;
|
|
|
|
LFuncSL: TStringList;
|
|
|
|
begin
|
|
|
|
LHasReturn := False;
|
|
|
|
LClassNameProcIn := '';
|
|
|
|
LProcTypeString := MethodKindToDelphiString(LHasReturn);
|
2019-07-29 14:33:28 +02:00
|
|
|
|
|
|
|
if Assigned(inOnType) then
|
2019-07-29 16:01:27 +02:00
|
|
|
LClassNameProcIn := inOnType.TypeName + '.';
|
2019-08-02 03:44:19 +02:00
|
|
|
ParametersToDelphiString(LParamString);
|
2019-07-29 14:33:28 +02:00
|
|
|
|
2019-07-29 16:01:27 +02:00
|
|
|
if LHasReturn then
|
|
|
|
Result := LProcTypeString + ' ' + LClassNameProcIn + FName + LParamString + ': ' + ReturnType.FTypeName + ';'
|
2019-07-29 14:33:28 +02:00
|
|
|
else
|
2019-07-29 16:01:27 +02:00
|
|
|
Result := LProcTypeString + ' ' + LClassNameProcIn + FName + LParamString + ';';
|
2019-07-29 14:33:28 +02:00
|
|
|
|
2019-07-29 16:01:27 +02:00
|
|
|
LFuncSL := TStringList.Create;
|
2019-07-29 14:33:28 +02:00
|
|
|
try
|
2019-07-29 16:01:27 +02:00
|
|
|
LFuncSL.Text := Result;
|
2019-08-02 03:44:19 +02:00
|
|
|
|
|
|
|
MethodLocalVarsToDelphiString(LFuncSL);
|
|
|
|
|
2019-07-29 16:01:27 +02:00
|
|
|
LFuncSL.Add('begin');
|
|
|
|
LFuncSL.Add(Content.Text);
|
|
|
|
LFuncSL.Add('end;');
|
2019-07-29 14:33:28 +02:00
|
|
|
|
2019-07-29 16:01:27 +02:00
|
|
|
Result := LFuncSL.Text;
|
2019-07-29 14:33:28 +02:00
|
|
|
finally
|
2019-07-29 16:01:27 +02:00
|
|
|
FreeAndNil(LFuncSL);
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TUnitMethod.GenerateInterface: string;
|
|
|
|
var
|
2019-07-29 16:01:27 +02:00
|
|
|
LProcTypeString: string;
|
|
|
|
LHasReturn: Boolean;
|
|
|
|
LParamString: string;
|
|
|
|
LAttributeString: string;
|
2019-07-29 14:33:28 +02:00
|
|
|
begin
|
2019-07-29 16:01:27 +02:00
|
|
|
LHasReturn := False;
|
2019-07-29 14:33:28 +02:00
|
|
|
|
2019-08-02 03:44:19 +02:00
|
|
|
LProcTypeString := MethodKindToDelphiString(LHasReturn);
|
2019-07-29 14:33:28 +02:00
|
|
|
|
2019-08-02 03:44:19 +02:00
|
|
|
ParametersToDelphiString(LParamString);
|
2019-07-29 14:33:28 +02:00
|
|
|
|
2019-07-29 16:01:27 +02:00
|
|
|
if LHasReturn then
|
|
|
|
Result := ' ' + LProcTypeString + ' ' + FName + LParamString + ': ' + ReturnType.FTypeName + ';'
|
2019-07-29 14:33:28 +02:00
|
|
|
else
|
2019-07-29 16:01:27 +02:00
|
|
|
Result := ' ' + LProcTypeString + ' ' + FName + LParamString + ';';
|
2019-07-29 14:33:28 +02:00
|
|
|
|
2019-07-29 16:01:27 +02:00
|
|
|
LAttributeString := FAttributes.Text;
|
|
|
|
Result := LAttributeString + Result;
|
2019-07-29 14:33:28 +02:00
|
|
|
end;
|
|
|
|
|
2019-08-02 03:44:19 +02:00
|
|
|
function TUnitMethod.GetIsConstructor: Boolean;
|
|
|
|
begin
|
|
|
|
Result := MethodKind = mkConstructor;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TUnitMethod.GetIsDestructor: Boolean;
|
|
|
|
begin
|
|
|
|
Result := MethodKind = mkDestructor;
|
|
|
|
end;
|
|
|
|
|
2019-07-29 14:33:28 +02:00
|
|
|
function TUnitMethod.GetParameters: TArray<TUnitParameter>;
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
begin
|
|
|
|
setLength(Result, FParams.Count);
|
|
|
|
for i := 0 to FParams.Count - 1 do
|
|
|
|
begin
|
|
|
|
Result[i] := FParams[i];
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
|
|
|