Repository URL to install this package:
|
Version:
3.2.0 ▾
|
{
This file is part of the Free Pascal run time library.
Copyright (c) 2007 by Michael Van Canneyt, member of the
Free Pascal development team
Data Dictionary Code Generator Implementation.
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
unit FPDDCodeGen;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, DB, fpDataDict;
Type
TPropType = (ptAuto,
ptBoolean,
ptShortint, ptByte,
ptSmallInt, ptWord,
ptLongint, ptCardinal,
ptInt64, ptQWord,
ptShortString, ptAnsiString, ptWideString, ptUnicodeString, ptUtf8String,
ptSingle, ptDouble, ptExtended, ptComp, ptCurrency,
ptDateTime,
ptEnumerated, ptSet, ptStream, ptTStrings,
ptCustom);
TVisibility = (vPrivate,vProtected,vPublic,vPublished);
TVisibilities = Set of TVisibility;
TPropAccess = (paReadWrite,paReadonly,paWriteonly);
TPropSetter = (psRead,psWrite);
TPropSetters = set of TPropSetter;
TFieldPropDefs = Class;
{ TFieldPropDef }
TFieldPropDef = Class (TCollectionItem)
private
FEnabled: Boolean;
FFieldName: String;
FFieldType: TFieldType;
FPropAccess: TPropAccess;
FPropDef: String;
FPropSetters: TPropSetters;
FPropType : TPropType;
FPRopSize: Integer;
FPropName : String;
FPropVis: TVisibility;
function GetPropName: String;
function GetPropType: TPropType;
function GetPropTypeStored: boolean;
Protected
Procedure InitFromField(F : TField); virtual;
Procedure InitFromDDFieldDef(F : TDDFieldDef);virtual;
procedure SetFieldType(AValue: TFieldType); virtual;
procedure SetPropName(const AValue: String); virtual;
Public
Constructor Create(ACollection : TCollection) ; override;
Procedure Assign(ASource : TPersistent); override;
Function FieldPropDefs : TFieldPropDefs;
Function HasGetter : Boolean; Virtual; // Checks Propsetters for psRead
Function HasSetter : Boolean; Virtual; // True for streams/strings or if Propsetters has pswrite
Function ObjPasTypeDef : String; virtual; // Object pascal definition of type
Function ObjPasReadDef : String; virtual; // Object pascal definition of getter
Function ObjPasWriteDef : String; virtual; // Object pascal definition of setter
Published
Property Enabled : Boolean Read FEnabled Write FEnabled;
Property FieldName : String Read FFieldName Write FFieldName;
Property FieldType : TFieldType Read FFieldType Write SetFieldType;
Property PropertyName : String Read GetPropName Write SetPropName;
Property PropertyType : TPropType Read GetPropType Write FPropType Stored GetPropTypeStored;
Property PropertySize : Integer Read FPRopSize Write FPropSize;
Property PropertyDef : String Read FPropDef Write FPropDef;
Property PropertyVisibility : TVisibility Read FPropVis Write FPropVis;
Property PropertyAccess : TPropAccess Read FPropAccess Write FPropAccess;
Property PropSetters : TPropSetters Read FPropSetters Write FPropSetters;
end;
{ TFieldPropDefs }
TFieldPropDefs = Class (TCollection)
private
function GetPropDef(Index : integer): TFieldPropDef;
procedure SetPropDef(Index : integer; const AValue: TFieldPropDef);
Public
Function AddDef(AName : String) : TFieldPropDef;
Procedure FromDataset(Dataset : TDataset; DoClear : Boolean = True);
Procedure FromDDFieldDefs(Defs : TDDFieldDefs; DoClear : Boolean = True);
Function IndexOfPropName(AName : String) : Integer;
Function IndexOfFieldName(AName : String) : Integer;
Function FindPropName(AName : String) : TFieldPropDef;
Function FindFieldName(AName : String) : TFieldPropDef;
Property PropDefs[Index : integer] : TFieldPropDef Read GetPropDef write SetPropDef; Default;
end;
{ TFieldPropDefs }
TCodeOption = (coInterface,coImplementation,coUnit);
TCodeOptions = Set of TCodeOption;
{ TCodeGeneratorOptions }
TCodeGeneratorOptions = Class(TPersistent)
private
FImplementationUnits: String;
FInterfaceUnits: String;
FOptions: TCodeOptions;
FUnitName: String;
FExtraSetterLine : string;
procedure SetImplementationUnits(const AValue: String);
procedure SetInterfaceUnits(const AValue: String);
procedure SetUnitname(const AValue: String);
Protected
procedure SetOPtions(const AValue: TCodeOptions); virtual;
Public
Constructor create; virtual;
Procedure Assign(ASource : TPersistent); override;
Published
// Line of code that will be added to each property setter. Use %PROPNAME% to include property name in the line.
Property ExtraSetterLine : String Read FExtraSetterLine Write FExtraSetterLine;
// options
Property Options : TCodeOptions Read FOptions Write SetOPtions;
// Name of unit if a unit is generated.
Property UnitName : String Read FUnitName Write SetUnitname;
// Comma-separated list of units that will be put in the interface units clause
Property InterfaceUnits : String Read FInterfaceUnits Write SetInterfaceUnits;
// Comma-separated list of units that will be put in the implementation units clause
Property ImplementationUnits : String Read FImplementationUnits Write SetImplementationUnits;
end;
TCodeGeneratorOptionsClass = Class of TCodeGeneratorOptions;
{ TDDCustomCodeGenerator }
TCodeEvent = Procedure(Sender : TObject; Strings : TStrings) of object;
TDDCustomCodeGenerator = Class(TComponent)
FCodeOptions: TCodeGeneratorOptions;
Private
FIndent: Integer;
FCurrentIndent :String;
Protected
// Utility routines to add lines to the code. Will prepend indent.
procedure AddLn(Strings: TStrings); overload;
procedure AddLn(Strings: TStrings; Line: String); overload;
procedure AddLn(Strings: TStrings; Fmt: String; Args: array of const); overload;
// Create a pascal code string. Surround by quotes or not
Function CreatePascalString(S : String; Quote : Boolean = True) : String;
// Increase indent by defined amount
procedure IncIndent;
// Decrease indent by defined amount
procedure DecIndent;
// Start a method implementation. Writes the declaration. No Begin.
procedure BeginMethod(STrings: TStrings; const Decl: String); Virtual;
// End a method implementation. Writes the final end;
procedure EndMethod(STrings: TStrings; const Decl: String);Virtual;
// The following must be overridden by descendents
Procedure DoGenerateInterface(Strings: TStrings); virtual;
Procedure DoGenerateImplementation(Strings: TStrings); virtual;
// Override this to return an instance of the proper class.
Function CreateOptions : TCodeGeneratorOptions; virtual;
// Override to return minimal uses clause for interface section.
Function GetInterfaceUsesClause : String; virtual;
// Override to return minimal uses clause for implementation section.
Function GetImplementationUsesClause : String; virtual;
// Must override to return real fielddefs
function GetFieldDefs: TFieldPropDefs; virtual;
// Must override to return real fielddefs
procedure SetFieldDefs(const AValue: TFieldPropDefs); virtual;
// Must override to return real SQL
function GetSQL: TStrings; virtual;
// Must override to set real SQL
procedure SetSQL(const AValue: TStrings); virtual;
Public
Constructor Create(AOWner : TComponent); override;
Destructor Destroy; override;
Procedure GenerateCode(Stream : TStream);
Procedure GenerateCode(Strings: TStrings);
Class Function NeedsSQL : Boolean; virtual;
Class Function NeedsFieldDefs : Boolean; virtual;
Function ShowConfigDialog : Boolean;
Property Fields : TFieldPropDefs Read GetFieldDefs Write SetFieldDefs;
Property SQL : TStrings Read GetSQL Write SetSQL;
Published
Property CodeOptions : TCodeGeneratorOptions Read FCodeOptions Write FCodeOptions;
Property Indent : Integer Read FIndent Write FIndent Default 2;
end;
{ TClassCodeGeneratorOptions }
TClassCodeGeneratorOptions = Class(TCodeGeneratorOptions)
private
FAncestorClass: String;
FClassName: String;
procedure SetAncestorClass(const AValue: String);
Protected
procedure SetClassName(const AValue: String); virtual;
// Set to default value. Publish if needed.
Property AncestorClass : String Read FAncestorClass Write SetAncestorClass;
Public
Procedure Assign(ASource : TPersistent); override;
// Classname without T prepended
Function CleanObjectClassName : String;
Published
Property ObjectClassName : String Read FClassName Write SetClassName;
end;
{ TDDClassCodeGenerator }
TDDClassCodeGenerator = Class(TDDCustomCodeGenerator)
private
FAfterClassDeclaration: TCodeEvent;
FAfterClassImplementation: TCodeEvent;
FAfterDestructOrImplementation: TCodeEvent;
FAfterTypeSection: TCodeEvent;
FAncestorClass : String;
FBeforeClassDeclaration: TCodeEvent;
FBeforeClassImplementation: TCodeEvent;
FBeforeConstructOrImplementation: TCodeEvent;
FBeforeTypeSection: TCodeEvent;
FFieldDefs: TFieldPropDefs;
FStreamClass: String;
FStringsClass: String;
FUnitName: String;
procedure DoBeforeGetter(Strings: TStrings);
function GetOpts: TClassCodeGeneratorOptions;
procedure SetAncestorClass(const AValue: String);
procedure SetClassName(const AValue: String);
procedure SetUnitname(const AValue: String);
Protected
// Overrides from base class
Function GetFieldDefs: TFieldPropDefs; override;
procedure SetFieldDefs(const AValue: TFieldPropDefs); override;
Function CreateOptions : TCodeGeneratorOptions; override;
Procedure DoBeforeTypeSection(Strings: TStrings); virtual;
Procedure DoAfterTypeSection(Strings: TStrings); virtual;
Procedure DoBeforeClassDeclaration(Strings: TStrings); virtual;
Procedure DoAfterClassDeclaration(Strings: TStrings); virtual;
Procedure DoBeforeConstructor(Strings: TStrings); virtual;
Procedure DoAfterDestructor(Strings: TStrings); virtual;
Procedure DoBeforeClassImplementation(Strings : TStrings); virtual;
Procedure DoAfterClassImplementation(Strings: TStrings); virtual;
Procedure DoGenerateInterface(Strings: TStrings); override;
Procedure DoGenerateImplementation(Strings: TStrings); override;
// Override this if you want to add interfaces to the class.
Function GetClassInterfaces : String; virtual;
// General code things.
// Override to create TFieldpropdefs descendent instance.
Function CreateFieldPropDefs : TFieldPropDefs; virtual;
// Set to default value. Publish if needed.
//
// Interface routines
//
// Write property getter implementation
procedure WritePropertyGetterImpl(Strings: TStrings; F: TFieldPropDef); virtual;
// Write property setter implementation
procedure WritePropertySetterImpl(Strings: TStrings; F: TFieldPropDef); virtual;
// Create class declaration.
procedure CreateDeclaration(Strings: TStrings); virtual;
// Create class head. Override to add after class start.
procedure CreateClassHead(Strings: TStrings); virtual;
// Create class end. Override to add before class end.
procedure CreateClassEnd(Strings : TStrings); virtual;
// Called right after section start is written.
procedure WriteVisibilityStart(V: TVisibility; Strings: TStrings); virtual;
// Called at the end of section.
procedure WriteVisibilityEnd(V: TVisibility; Strings: TStrings); virtual;
// Should a property declaration be written ? Checks enabled and visibility
function AllowPropertyDeclaration(F: TFieldPropDef; AVisibility: TVisibilities): Boolean; virtual;
// Writes a property declaration. Only called if AllowPropertyDeclaration returned true
procedure WritePropertyDeclaration(Strings: TStrings; F: TFieldPropDef); virtual;
// Creates a property declaration.
Function PropertyDeclaration(Strings: TStrings; Def: TFieldPropDef) : String; virtual;
// Writes private fields for class.
procedure WritePrivateFields(Strings: TStrings); virtual;
//
// Implementation routines
//
// Create class implementation
procedure CreateImplementation(Strings: TStrings); virtual;
// Write implementation of constructor
procedure WriteConstructorImplementation(Strings: TStrings); Virtual;
// Write implementation of Destructor
procedure WriteDestructorImplementation(Strings: TStrings); Virtual;
// Write initialization of property (in constructor)
procedure WriteFieldCreate(Strings: TStrings; F: TFieldPropDef); Virtual;
// Write Finalization of property (in destructor)
procedure WriteFieldDestroy(Strings: TStrings; F: TFieldPropDef); Virtual;
//
// Routines used in both Implementation/Interface
//
// Write property getter declaration
Function PropertyGetterDeclaration(Def: TFieldPropDef; Impl : Boolean) : String; virtual;
// Write property setter declaration
Function PropertySetterDeclaration(Def: TFieldPropDef; Impl : Boolean) : String; virtual;
// Determines whether a constructor/destructor pair is written.
// By default one is written if ptStream/ptStrings is detected.
Function NeedsConstructor : Boolean; virtual;
// By default, this calls NeedsConstructor.
Function NeedsDestructor : Boolean; virtual;
// Override this to return the constructor declaration.
Function ConstructorDeclaration(Impl : Boolean) : String; Virtual;
// Override this to return the destructor declaration
Function DestructorDeclaration(Impl : Boolean) : String; Virtual;
//
// Properties
//
// Class name used to instantiate TStrings instances.
Property StringsClass : String Read FStringsClass Write FStringsClass;
// Class name used to instantiate TStream instances.
Property StreamClass : String Read FStreamClass Write FStreamClass;
// Easy access to options
Property ClassOptions : TClassCodeGeneratorOptions Read GetOpts;
Public
Constructor Create(AOwner : TComponent); override;
Destructor Destroy; override;
Procedure GenerateClass(Strings : TStrings); virtual;
Procedure GenerateClass(Stream : TStream);
Published
Property Fields;
Property AfterTypeSection : TCodeEvent Read FAfterTypeSection Write FAfterTypeSection;
Property BeforeTypeSection : TCodeEvent Read FBeforeTypeSection Write FBeforeTypeSection;
Property AfterClassDeclaration : TCodeEvent Read FAfterClassDeclaration Write FAfterClassDeclaration;
Property BeforeClassDeclaration : TCodeEvent Read FBeforeClassDeclaration Write FBeforeClassDeclaration;
Property AfterClassImplementation : TCodeEvent Read FAfterClassImplementation Write FAfterClassImplementation;
Property BeforeClassImplementation : TCodeEvent Read FBeforeClassImplementation Write FBeforeClassImplementation;
Property AfterDestructorImplementation : TCodeEvent Read FAfterDestructOrImplementation Write FAfterDestructOrImplementation;
Property BeforeConstructorImplementation : TCodeEvent Read FBeforeConstructOrImplementation Write FBeforeConstructOrImplementation;
end;
ECodeGenerator = Class(Exception);
{ TExportFormatItem }
TDDCustomCodeGeneratorClass = Class of TDDCustomCodeGenerator;
TCodeGeneratorConfigureEvent = Function (Generator : TDDCustomCodeGenerator) : Boolean of object;
{ TCodeGeneratorItem }
TCodeGeneratorItem = Class(TCollectionItem)
private
FClass: TDDCustomCodeGeneratorClass;
FDescription: String;
FName: String;
FOnConfigure: TCodeGeneratorConfigureEvent;
Procedure SetName(const AValue: String);
Public
Property GeneratorClass : TDDCustomCodeGeneratorClass Read FClass Write FClass;
Published
Property Name : String Read FName Write SetName;
Property Description : String Read FDescription Write FDescription;
Property OnConfigureDialog : TCodeGeneratorConfigureEvent Read FOnConfigure Write FOnConfigure;
end;
{ TCodeGenerators }
TCodeGenerators = Class(TCollection)
private
function GetGen(Index : Integer): TCodeGeneratorItem;
procedure SetGen(Index : Integer; const AValue: TCodeGeneratorItem);
Public
// Registration/Unregistration
Function RegisterCodeGenerator(Const AName, ADescription : String; AClass : TDDCustomCodeGeneratorClass) : TCodeGeneratorItem;
Procedure UnRegisterCodeGenerator(AClass : TDDCustomCodeGeneratorClass);
Procedure UnRegisterCodeGenerator(Const AName : String);
// Searching
Function IndexOfCodeGenerator(Const AName : String): Integer;
Function IndexOfCodeGenerator(AClass : TDDCustomCodeGeneratorClass): Integer;
Function FindCodeGenerator(Const AName : String) : TCodeGeneratorItem;
Function FindCodeGenerator(AClass : TDDCustomCodeGeneratorClass) : TCodeGeneratorItem;
// Shows configuration dialog, if one was configured for this class
Function ConfigureCodeGenerator(AGenerator : TDDCustomCodeGenerator) : Boolean;
Function GeneratorByName(Const AName : String) : TCodeGeneratorItem;
Property Generators[Index : Integer] : TCodeGeneratorItem Read GetGen Write SetGen; default;
end;
Function CodeGenerators : TCodeGenerators;
// Easy access functions
Function RegisterCodeGenerator(Const AName,ADescription : String; AClass : TDDCustomCodeGeneratorClass) : TCodeGeneratorItem;
Procedure UnRegisterCodeGenerator(AClass : TDDCustomCodeGeneratorClass);
Procedure UnRegisterCodeGenerator(Const AName : String);
Type
TFieldPropTypeMap = Array[TFieldType] of TPropType;
TPropertyVisibilityMap = Array[TPropType] of TVisibility;
Var
FieldToPropTypeMap : TFieldPropTypeMap = (
ptCustom, ptAnsiString, ptSmallInt, ptLongInt, ptWord,
ptBoolean, ptDouble, ptCurrency, ptCurrency, ptDateTime, ptDateTime, ptDateTime,
ptCustom, ptCustom, ptLongInt, ptStream, ptTStrings, ptStream, ptTStrings,
ptCustom, ptCustom, ptCustom, ptCustom, ptAnsiString,
ptWideString, ptInt64, ptCustom, ptCustom, ptCustom,
ptCustom, ptCustom, ptCustom, ptCustom, ptCustom,
ptCustom, ptAnsiString, ptDateTime, ptCurrency, ptWideString, ptWideString);
PropTypeToVisibilityMap : TPropertyVisibilityMap = (
vPrivate,
vPublished,
vPublished, vPublished,
vPublished, vPublished,
vPublished, vPublished,
vPublished, vPublished,
vPublished, vPublished, vPublished, vPublished, vPublished,
vPublished, vPublished, vPublished, vPublished, vPublished,
vPublished,
vPublished, vPublished, vPublic, vPublished,
vPrivate);
Const
ptInteger = ptLongint;
ptString = ptAnsiString;
Const
PropTypeNames : Array[TPropType] of string
= ('',
'Boolean',
'ShortInt', 'Byte',
'SmallInt', 'Word',
'Longint', 'Cardinal',
'Int64', 'QWord',
'String', 'AnsiString', 'WideString', 'UnicodeString', 'Utf8String',
'Single', 'Double' , 'Extended', 'Comp', 'Currency',
'TDateTime',
'','', 'TStream', 'TStrings',
'');
Resourcestring
SErrInvalidIdentifier = '"%s" is not a valid object pascal identifier.';
SErrGeneratorExists = 'A code generator with name "%s" already exists';
SUnknownGenerator = 'Unknown code generator name : "%s"';
Function MakeIdentifier (S : String) : String;
Function CreateString(S : String) : String;
Procedure CheckIdentifier(AValue : String; AllowEmpty : Boolean = True);
implementation
Function CreateString(S : String) : String;
begin
Result:=StringReplace(S,'''','''''',[rfReplaceAll]);
Result:=''''+Result+'''';
end;
Procedure CheckIdentifier(AValue : String; AllowEmpty : Boolean = True);
begin
If ((AValue='') and Not AllowEmpty) or Not IsValidIdent(AValue) then
Raise ECodeGenerator.CreateFmt(SErrInvalidIdentifier,[AValue]);
end;
Var
CodeGens : TCodeGenerators;
function CodeGenerators: TCodeGenerators;
begin
If (CodeGens=Nil) then
CodeGens:=TCodeGenerators.Create(TCodeGeneratorItem);
Result:=CodeGens;
end;
Procedure DoneCodeGenerators;
begin
FreeAndNil(CodeGens);
end;
function RegisterCodeGenerator(const AName, ADescription: String;
AClass: TDDCustomCodeGeneratorClass): TCodeGeneratorItem;
begin
CodeGenerators.RegisterCodeGenerator(AName,ADescription,AClass);
end;
procedure UnRegisterCodeGenerator(AClass: TDDCustomCodeGeneratorClass);
begin
CodeGenerators.UnRegisterCodeGenerator(AClass);
end;
procedure UnRegisterCodeGenerator(const AName: String);
begin
CodeGenerators.UnRegisterCodeGenerator(AName);
end;
Function MakeIdentifier (S : String) : String;
Var
I : Integer;
begin
Result:=S;
For I:=Length(Result) downto 0 do
If Not ((Upcase(Result[i]) in ['_','A'..'Z'])
or ((I>0) and (Result[i] in (['0'..'9'])))) then
Delete(Result,i,1);
end;
{ TFieldPropDef }
function TFieldPropDef.GetPropName: String;
begin
Result:=FPropName;
If (Result='') then
Result:=MakeIdentifier(FFieldName);
end;
function TFieldPropDef.GetPropType: TPropType;
begin
Result:=FPropType;
If (Result=ptAuto) then
Result:=FieldToPropTypeMap[FieldType];
end;
function TFieldPropDef.GetPropTypeStored: boolean;
begin
Result:=(FPropType<>ptAuto)
end;
procedure TFieldPropDef.SetFieldType(AValue: TFieldType);
begin
if FFieldType=AValue then Exit;
FFieldType:=AValue;
end;
procedure TFieldPropDef.SetPropName(const AValue: String);
begin
If (AValue<>FPropName) then
begin
CheckIdentifier(AValue);
FPropName:=AValue;
end;
end;
procedure TFieldPropDef.InitFromField(F: TField);
begin
FieldType:=F.DataType;
PropertySize:=F.Size;
end;
procedure TFieldPropDef.InitFromDDFieldDef(F: TDDFieldDef);
begin
FieldType:=F.FieldType;
PropertySize:=F.Size;
end;
constructor TFieldPropDef.Create(ACollection: TCollection);
begin
inherited Create(ACollection);
FPropVis:=vPublished
end;
procedure TFieldPropDef.Assign(ASource: TPersistent);
Var
PD : TFieldPropDef;
begin
if (ASource is TFieldPropDef) then
begin
PD:=ASource as TFieldPropDef;
FEnabled:=PD.Enabled;
FFieldName:=PD.FFieldName;
FFieldType:=PD.FFIeldType;
FPropAccess:=PD.FPropAccess;
FPropDef:=PD.FPropDef;
FPropType:=PD.FPropType;
FPRopSize:=PD.FPropSize;
FPropName:=PD.FPropName;
FPropVis:=PD.FPropVis;
end
else
inherited Assign(ASource);
end;
function TFieldPropDef.FieldPropDefs: TFieldPropDefs;
begin
Result:=Collection as TFieldPropDefs;
end;
function TFieldPropDef.HasGetter: Boolean;
begin
Result:=psRead in PropSetters;
end;
function TFieldPropDef.HasSetter: Boolean;
begin
Result:=(PropertyAccess in [paReadWrite,paWriteOnly])
and ((PropertyType in [ptStream,ptTStrings]) or (psWrite in Propsetters));
end;
function TFieldPropDef.ObjPasTypeDef: String;
begin
If PropertyType in [ptCustom,ptSet,ptEnumerated] then
Result:=PropertyDef
else
begin
Result:=PropTypeNames[PropertyType];
If PropertyType=ptShortString then
Result:=Result+Format('String[%d]',[PropertySize]);
end;
end;
function TFieldPropDef.ObjPasReadDef: String;
begin
If HasGetter then
Result:='Get'+PropertyName
else
Result:='F'+PropertyName;
end;
function TFieldPropDef.ObjPasWriteDef: String;
begin
If HasSetter then
Result:='Set'+PropertyName
else
Result:='F'+PropertyName;
end;
{ TFieldPropDefs }
function TFieldPropDefs.GetPropDef(Index : integer): TFieldPropDef;
begin
Result:=TFieldPropDef(Items[index]);
end;
procedure TFieldPropDefs.SetPropDef(Index : integer; const AValue: TFieldPropDef);
begin
Items[Index]:=AValue;
end;
function TFieldPropDefs.AddDef(AName: String): TFieldPropDef;
begin
Result:=Add As TFieldPropDef;
Result.FieldName:=AName;
end;
procedure TFieldPropDefs.FromDataset(Dataset: TDataset; DoClear: Boolean = True);
Var
I : Integer;
D : TFieldPropDef;
F : TField;
begin
If DoClear then
Clear;
For I:=0 to Dataset.Fields.Count-1 do
begin
F:=Dataset.Fields[I];
D:=AddDef(F.FieldName);
D.Enabled:=True;
D.InitFromField(F);
end;
end;
procedure TFieldPropDefs.FromDDFieldDefs(Defs: TDDFieldDefs; DoClear: Boolean = True);
Var
I : Integer;
D : TFieldPropDef;
F : TDDFieldDef;
begin
If DoClear then
Clear;
For I:=0 to Defs.Count-1 do
begin
F:=Defs[I];
D:=AddDef(F.FieldName);
D.Enabled:=True;
D.InitFromDDFieldDef(F);
end;
end;
function TFieldPropDefs.IndexOfPropName(AName: String): Integer;
begin
Result:=Count-1;
While (Result>=0) and (CompareText(GetPropDef(Result).PropertyName,AName)<>0) do
Dec(Result);
end;
function TFieldPropDefs.IndexOfFieldName(AName: String): Integer;
begin
Result:=Count-1;
While (Result>=0) and (CompareText(GetPropDef(Result).FieldName,AName)<>0) do
Dec(Result);
end;
function TFieldPropDefs.FindPropName(AName: String): TFieldPropDef;
Var
I : Integer;
begin
I:=IndexOfPropName(AName);
If (I<>-1) then
Result:=GetpropDef(I)
else
Result:=Nil;
end;
function TFieldPropDefs.FindFieldName(AName: String): TFieldPropDef;
Var
I : Integer;
begin
I:=IndexOfFieldName(AName);
If (I<>-1) then
Result:=GetpropDef(I)
else
Result:=Nil;
end;
{ TDDClassCodeGenerator }
procedure TDDClassCodeGenerator.SetClassName(const AValue: String);
begin
end;
procedure TDDClassCodeGenerator.SetAncestorClass(const AValue: String);
begin
FAncestorClass:=AValue;
end;
function TDDClassCodeGenerator.GetOpts: TClassCodeGeneratorOptions;
begin
Result:=CodeOptions as TClassCodeGeneratorOptions;
end;
procedure TDDClassCodeGenerator.SetFieldDefs(const AValue: TFieldPropDefs);
begin
if FFieldDefs=AValue then exit;
FFieldDefs:=AValue;
end;
procedure TDDClassCodeGenerator.SetUnitname(const AValue: String);
begin
FUnitName:=AValue;
end;
function TDDClassCodeGenerator.CreateFieldPropDefs: TFieldPropDefs;
begin
Result:=TFieldPropDefs.Create(TFieldPropDef);
end;
constructor TDDClassCodeGenerator.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FFieldDefs:=CreateFieldPropDefs;
StringsClass:='TStringList';
StreamClass:='TMemoryStream';
end;
destructor TDDClassCodeGenerator.Destroy;
begin
FreeAndNil(FFieldDefs);
inherited Destroy;
end;
procedure TDDClassCodeGenerator.GenerateClass(Strings: TStrings);
begin
IncIndent;
Try
DoBeforeTypeSection(Strings);
AddLn(Strings,'// Declaration');
AddLn(Strings,'Type');
AddLn(Strings);
DoBeforeClassDeclaration(Strings);
CreateDeclaration(Strings);
DoAfterClassDeclaration(Strings);
AddLn(Strings);
DoAfterTypeSection(Strings);
AddLn(Strings,'// Implementation');
AddLn(Strings);
DoBeforeClassImplementation(Strings);
CreateImplementation(Strings);
DoAfterClassImplementation(Strings);
Finally
DecIndent;
end;
end;
function TDDClassCodeGenerator.AllowPropertyDeclaration(F: TFieldPropDef;
AVisibility: TVisibilities): Boolean;
begin
Result:=Assigned(f) and F.Enabled and ((AVisibility=[]) or (F.PropertyVisibility in AVisibility));
end;
procedure TDDClassCodeGenerator.WritePropertyDeclaration(Strings: TStrings;
F: TFieldPropDef);
begin
AddLn(Strings,PropertyDeclaration(Strings,F)+';');
end;
procedure TDDClassCodeGenerator.CreateDeclaration(Strings: TStrings);
Const
VisibilityNames : Array [TVisibility] of string
= ('Private','Protected','Public','Published');
Var
V : TVisibility;
I : Integer;
F : TFieldPropDef;
begin
CreateClassHead(Strings);
AddLn(Strings,VisibilityNames[vPrivate]);
WritePrivateFields(Strings);
For v:=Low(TVisibility) to High(TVisibility) do
begin
AddLn(Strings,VisibilityNames[v]);
IncIndent;
Try
WriteVisibilityStart(V,Strings);
For I:=0 to Fields.Count-1 do
begin
F:=Fields[i];
if AllowPropertyDeclaration(F,[V]) then
WritePropertyDeclaration(Strings,F);
end;
WriteVisibilityEnd(V,Strings);
Finally
Decindent;
end;
end;
CreateClassEnd(Strings);
end;
procedure TDDClassCodeGenerator.WritePrivateFields(Strings: TStrings);
Var
I : Integer;
F : TFieldPropDef;
begin
IncIndent;
Try
For I:=0 to Fields.Count-1 do
begin
F:=Fields[i];
if AllowPropertyDeclaration(F,[]) then
AddLn(Strings,'F%s : %s;',[F.PropertyName,F.ObjPasTypeDef]);
end;
Finally
DecIndent;
end;
end;
procedure TDDClassCodeGenerator.DoBeforeGetter(Strings: TStrings);
begin
end;
procedure TDDClassCodeGenerator.CreateImplementation(Strings: TStrings);
Var
B : Boolean;
I : Integer;
F : TFieldPropDef;
begin
AddLn(Strings,' { %s } ',[ClassOptions.ObjectClassName]);
AddLn(Strings);
DoBeforeConstructor(Strings);
If NeedsConstructor or NeedsDestructor then
Addln(Strings,' { Constructor and destructor }');
If NeedsConstructor then
begin
Addln(Strings);
WriteConstructorImplementation(Strings);
end;
If NeedsDestructor then
begin
Addln(Strings);
WriteDestructorImplementation(Strings);
end;
DoAfterDestructor(Strings);
B:=False;
For I:=0 to Fields.Count-1 do
begin
F:=Fields[i];
if AllowPropertyDeclaration(F,[]) and F.HasGetter then
begin
If not B then
begin
B:=True;
Addln(Strings,' { Property Getters }');
Addln(Strings);
end;
WritePropertyGetterImpl(Strings,F);
end;
end;
B:=False;
For I:=0 to Fields.Count-1 do
begin
F:=Fields[i];
if AllowPropertyDeclaration(F,[]) and F.HasSetter then
begin
If not B then
begin
B:=True;
Addln(Strings,' { Property Setters }');
Addln(Strings);
end;
WritePropertySetterImpl(Strings,F);
end;
end;
end;
procedure TDDClassCodeGenerator.WritePropertyGetterImpl(Strings: TStrings;
F: TFieldPropDef);
Var
S : String;
begin
S:=PropertyGetterDeclaration(F,True);
BeginMethod(Strings,S);
AddLn(Strings,'begin');
IncIndent;
Try
AddLn(Strings,Format('Result:=F%s;',[F.PropertyName]));
Finally
DecIndent;
end;
EndMethod(Strings,S);
end;
procedure TDDClassCodeGenerator.WritePropertySetterImpl(Strings: TStrings;
F: TFieldPropDef);
Var
S : String;
L : Integer;
begin
S:=PropertySetterDeclaration(F,True);
BeginMethod(Strings,S);
AddLn(Strings,'begin');
IncIndent;
Try
AddLn(Strings,Format('if (F%s=AValue) then exit;',[F.PropertyName]));
Case F.PropertyType of
ptTStrings :
S:=Format('F%s.Assign(AValue);',[F.PropertyName]);
ptStream :
S:=Format('F%s.CopyFrom(AValue,0);',[F.PropertyName]);
else
S:=Format('F%s:=AValue;',[F.PropertyName]);
end;
AddLn(Strings,S);
S:=CodeOptions.ExtraSetterLine;
L:=Length(S);
if (L>0) then
begin
S:=StringReplace(S,'%PROPNAME%',F.PropertyName,[rfReplaceAll,rfIgnoreCase]);
L:=Length(S);
if (S[L]<>';') then
S:=S+';';
AddLn(Strings,S);
end;
Finally
DecIndent;
end;
EndMethod(Strings,S);
end;
function TDDClassCodeGenerator.GetFieldDefs: TFieldPropDefs;
begin
Result:=FFieldDefs;
end;
function TDDClassCodeGenerator.CreateOptions: TCodeGeneratorOptions;
begin
Result:=TClassCodeGeneratorOptions.Create;
end;
procedure TDDClassCodeGenerator.DoBeforeTypeSection(Strings: TStrings);
begin
If Assigned(BeforeTypeSection) then
BeforeTypeSection(Self,Strings);
end;
procedure TDDClassCodeGenerator.DoAfterTypeSection(Strings: TStrings);
begin
If Assigned(AfterTypeSection) then
AfterTypeSection(Self,Strings);
end;
procedure TDDClassCodeGenerator.DoBeforeClassDeclaration(Strings: TStrings);
begin
if Assigned(BeforeClassDeclaration) then
BeforeClassDeclaration(Self,Strings);
end;
procedure TDDClassCodeGenerator.DoAfterClassDeclaration(Strings: TStrings);
begin
if Assigned(AfterClassDeclaration) then
AfterClassDeclaration(Self,Strings);
end;
procedure TDDClassCodeGenerator.DoBeforeConstructor(Strings: TStrings);
begin
If Assigned(BeforeConstructorImplementation) then
BeforeConstructorImplementation(Self,Strings);
end;
procedure TDDClassCodeGenerator.DoAfterDestructor(Strings: TStrings);
begin
If Assigned(AfterDestructorImplementation) then
AfterDestructorImplementation(Self,Strings);
end;
procedure TDDClassCodeGenerator.DoBeforeClassImplementation(Strings: TStrings);
begin
If Assigned(BeforeClassImplementation) then
BeforeClassImplementation(Self,Strings);
end;
procedure TDDClassCodeGenerator.DoAfterClassImplementation(Strings: TStrings);
begin
If Assigned(AfterClassImplementation) then
AfterClassImplementation(Self,Strings);
end;
procedure TDDClassCodeGenerator.DoGenerateInterface(Strings: TStrings);
begin
DoBeforeTypeSection(Strings);
AddLn(Strings,'Type');
AddLn(Strings);
IncIndent;
Try
DoBeforeClassDeclaration(Strings);
CreateDeclaration(Strings);
DoAfterClassDeclaration(Strings);
Finally
DecIndent;
end;
DoAfterTypeSection(Strings);
end;
procedure TDDClassCodeGenerator.DoGenerateImplementation(Strings: TStrings);
begin
DoBeforeClassImplementation(Strings);
CreateImplementation(Strings);
DoAfterClassImplementation(Strings);
end;
function TDDClassCodeGenerator.GetClassInterfaces: String;
begin
Result:='';
end;
procedure TDDClassCodeGenerator.WriteConstructorImplementation(Strings: TStrings
);
Var
I : Integer;
F : TFieldPropDef;
S : String;
begin
S:=ConstructorDeclaration(True);
BeginMethod(Strings,S);
AddLn(Strings,'begin');
AddLn(Strings,' inherited;');
IncIndent;
Try
For I:=0 to Fields.Count-1 do
begin
F:=Fields[i];
if F.Enabled then
WriteFieldCreate(Strings,F);
end;
Finally
DecIndent;
end;
EndMethod(Strings,S);
end;
procedure TDDClassCodeGenerator.WriteDestructorImplementation(Strings: TStrings
);
Var
I : Integer;
F : TFieldPropDef;
S : String;
begin
S:=DestructorDeclaration(True);
BeginMethod(Strings,S);
AddLn(Strings,'begin');
IncIndent;
Try
For I:=0 to Fields.Count-1 do
begin
F:=Fields[i];
if F.Enabled then
WriteFieldDestroy(Strings,F);
end;
AddLn(Strings,'Inherited;');
Finally
DecIndent;
end;
EndMethod(Strings,S);
end;
procedure TDDClassCodeGenerator.WriteFieldCreate(Strings: TStrings;
F: TFieldPropDef);
Var
S : String;
begin
Case F.PropertyType of
ptTStrings :
begin
S:=Format('F%s:=%s.Create;',[F.PropertyName,StringsClass]);
AddLn(Strings,S);
end;
ptStream :
begin
S:=Format('F%s:=%s.Create;',[F.PropertyName,StreamClass]);
AddLn(Strings,S);
end;
ptCustom :
begin
AddLn(Strings,'// Add Creation for '+F.PropertyName);
end;
end;
end;
procedure TDDClassCodeGenerator.WriteFieldDestroy(Strings: TStrings;
F: TFieldPropDef);
Var
S : String;
begin
Case F.PropertyType of
ptTStrings,
ptStream :
begin
S:=Format('FreeAndNil(F%s);',[F.PropertyName]);
AddLn(Strings,S);
end;
ptCustom :
begin
AddLn(Strings,'// Add destroy for '+F.PropertyName);
end;
end;
end;
procedure TDDClassCodeGenerator.CreateClassHead(Strings: TStrings);
Var
S : String;
begin
Addln(Strings,'{ %s }',[ClassOptions.ObjectClassName]);
AddLn(Strings);
S:=GetClassInterfaces;
if (S<>'') then
S:=','+S;
AddLn(Strings,'%s = Class(%s%s)',[ClassOptions.ObjectClassName,ClassOptions.AncestorClass,S])
end;
procedure TDDClassCodeGenerator.CreateClassEnd(Strings: TStrings);
begin
AddLn(Strings,'end;');
AddLn(Strings);
end;
procedure TDDClassCodeGenerator.WriteVisibilityStart(V: TVisibility;
Strings: TStrings);
Var
I : Integer;
F : TFieldPropDef;
begin
If (v=vPrivate) then
begin
For I:=0 to Fields.Count-1 do
begin
F:=Fields[i];
If AllowPropertyDeclaration(F,[]) then
begin
if (F.Hasgetter) then
AddLn(Strings,PropertyGetterDeclaration(F,False));
if (F.HasSetter) then
AddLn(Strings,PropertySetterDeclaration(F,False));
end;
end;
end
else if v=vPublic then
begin
If NeedsConstructor then
AddLn(Strings,ConstructorDeclaration(False));
If NeedsDestructor then
Addln(Strings,DestructorDeclaration(False));
end
// Do nothing
end;
procedure TDDClassCodeGenerator.WriteVisibilityEnd(V: TVisibility;
Strings: TStrings);
begin
// Do nothing
end;
function TDDClassCodeGenerator.PropertyDeclaration(Strings: TStrings;
Def: TFieldPropDef): String;
begin
Result:='Property '+Def.PropertyName+' ';
Result:=Result+': '+Def.ObjPasTypeDef;
If Def.PropertyAccess in [paReadWrite,paReadOnly] then
Result:=Result+' Read '+Def.ObjPasReadDef;
If Def.PropertyAccess in [paReadWrite,paWriteOnly] then
Result:=Result+' Write '+Def.ObjPasWriteDef;
end;
function TDDClassCodeGenerator.PropertyGetterDeclaration(Def: TFieldPropDef;
Impl: Boolean): String;
begin
Result:='Function ';
If Impl then
Result:=Result+Classoptions.ObjectClassName+'.';
Result:=Result+Def.ObjPasReadDef+' : '+Def.ObjPasTypeDef+';';
end;
function TDDClassCodeGenerator.PropertySetterDeclaration(Def: TFieldPropDef;
Impl: Boolean): String;
begin
Result:='Procedure ';
If Impl then
Result:=Result+ClassOptions.ObjectClassName+'.';
Result:=Result+Def.ObjPasWriteDef+' (AValue : '+Def.ObjPasTypeDef+');';
end;
function TDDClassCodeGenerator.NeedsConstructor: Boolean;
Var
I : Integer;
F : TFieldPropDef;
begin
Result:=False;
I:=Fields.Count-1;
While (Not Result) and (I>=0) do
begin
F:=Fields[i];
Result:=F.Enabled and (F.PropertyType in [ptStream,ptTStrings]);
Dec(I);
end;
end;
function TDDClassCodeGenerator.NeedsDestructor: Boolean;
begin
Result:=NeedsConstructor;
end;
function TDDClassCodeGenerator.ConstructorDeclaration(Impl: Boolean): String;
begin
Result:='Constructor ';
If Impl then
Result:=Result+ClassOptions.ObjectClassName+'.';
Result:=Result+'Create;';
end;
function TDDClassCodeGenerator.DestructorDeclaration(Impl: Boolean): String;
begin
Result:='Destructor ';
If Impl then
Result:=Result+ClassOptions.ObjectClassName+'.';
Result:=Result+'Destroy;';
if not Impl then
Result:=Result+' Override;';
end;
procedure TDDClassCodeGenerator.GenerateClass(Stream: TStream);
Var
L : TStringList;
begin
L:=TStringList.Create;
try
GenerateClass(L);
L.SaveToStream(Stream);
finally
L.Free;
end;
end;
{ TDDCustomCodeGenerator }
procedure TDDCustomCodeGenerator.IncIndent;
begin
FCurrentIndent:=FCurrentIndent+StringOfChar(' ',FIndent);
end;
procedure TDDCustomCodeGenerator.DecIndent;
begin
Delete(FCurrentIndent,1,FIndent);
end;
procedure TDDCustomCodeGenerator.DoGenerateInterface(Strings: TStrings);
begin
end;
procedure TDDCustomCodeGenerator.DoGenerateImplementation(Strings: TStrings);
begin
end;
function TDDCustomCodeGenerator.GetFieldDefs: TFieldPropDefs;
begin
end;
procedure TDDCustomCodeGenerator.SetFieldDefs(const AValue: TFieldPropDefs);
begin
end;
function TDDCustomCodeGenerator.GetSQL: TStrings;
begin
Result:=Nil;
end;
procedure TDDCustomCodeGenerator.SetSQL(const AValue: TStrings);
begin
// Do nothing
end;
constructor TDDCustomCodeGenerator.Create(AOWner: TComponent);
begin
inherited Create(AOWner);
FCodeOptions:=CreateOptions;
FIndent:=2;
end;
destructor TDDCustomCodeGenerator.Destroy;
begin
FreeAndNil(FCodeOptions);
inherited Destroy;
end;
procedure TDDCustomCodeGenerator.AddLn(Strings : TStrings);
begin
Strings.Add('');
end;
procedure TDDCustomCodeGenerator.AddLn(Strings : TStrings; Line : String);
begin
Strings.Add(FCurrentIndent+Line);
end;
procedure TDDCustomCodeGenerator.AddLn(Strings: TStrings; Fmt: String;
Args: array of const);
begin
Strings.Add(FCurrentIndent+Format(Fmt,Args));
end;
function TDDCustomCodeGenerator.CreatePascalString(S: String; Quote: Boolean): String;
Var
SW : String;
begin
SW:=StringReplace(S,'''','''''',[rfReplaceAll]);
SW:=StringReplace(SW,#13#10,'''#13#10''',[rfReplaceAll]);
SW:=StringReplace(SW,#10,'''#10''',[rfReplaceAll]);
SW:=StringReplace(SW,#13,'''#13''',[rfReplaceAll]);
If Quote then
SW:=''''+SW+'''';
Result:=SW;
end;
function TDDCustomCodeGenerator.CreateOptions: TCodeGeneratorOptions;
begin
Result:=TCodeGeneratorOptions.Create;
end;
function TDDCustomCodeGenerator.GetInterfaceUsesClause: String;
begin
Result:='Classes, SysUtils';
If (CodeOptions.InterfaceUnits<>'') then
Result:=Result+','+CodeOptions.InterfaceUnits;
end;
function TDDCustomCodeGenerator.GetImplementationUsesClause: String;
begin
Result:=CodeOptions.ImplementationUnits;
end;
procedure TDDCustomCodeGenerator.GenerateCode(Stream: TStream);
Var
L : TStringList;
begin
L:=TStringList.Create;
try
GenerateCode(L);
L.SaveToStream(Stream);
finally
L.Free;
end;
end;
procedure TDDCustomCodeGenerator.GenerateCode(Strings: TStrings);
Procedure MaybeAddUsesClause(S : String);
begin
If (S<>'') then
begin
If S[Length(S)]<>';' then
S:=S+';';
AddLn(Strings,'Uses '+S);
AddLn(Strings);
end;
end;
Var
S : String;
begin
FCurrentIndent:='';
if (coUnit in CodeOptions.Options) then
begin
Addln(Strings,'Unit '+CodeOptions.UnitName+';');
Addln(Strings);
Addln(Strings, '{$mode objfpc}{$H+}');
Addln(Strings);
Addln(Strings,'Interface');
Addln(Strings);
S:=GetInterfaceUsesClause;
MaybeAddUsesClause(S);
end;
if coInterface in CodeOptions.Options then
begin
DoGenerateInterface(Strings);
Addln(Strings);
end;
FCurrentIndent:='';
if coUnit in CodeOptions.options then
begin
if coImplementation in CodeOptions.Options then
begin
Addln(Strings,'Implementation');
S:=GetImplementationUsesClause;
MaybeAddUsesClause(S);
end;
end;
if coImplementation in CodeOptions.Options then
begin
Addln(Strings);
DoGenerateImplementation(Strings);
end;
Addln(Strings);
if (coUnit in CodeOptions.options) then
Addln(Strings,'end.');
end;
class function TDDCustomCodeGenerator.NeedsSQL: Boolean;
begin
Result:=False;
end;
class function TDDCustomCodeGenerator.NeedsFieldDefs: Boolean;
begin
Result:=False;
end;
function TDDCustomCodeGenerator.ShowConfigDialog: Boolean;
begin
end;
procedure TDDCustomCodeGenerator.BeginMethod(STrings: TStrings;
const Decl: String);
begin
AddLn(Strings,Decl);
AddLn(Strings);
end;
procedure TDDCustomCodeGenerator.EndMethod(STrings: TStrings; const Decl: String
);
begin
AddLn(Strings,'end;');
Addln(Strings);
Addln(Strings);
end;
{ TCodeGeneratorItem }
procedure TCodeGeneratorItem.SetName(const AValue: String);
Var
G : TCodeGeneratorItem;
begin
if (FName=AValue) then
exit;
If (AValue<>'') then
begin
G:=TCodeGenerators(Collection).FindCodeGenerator(AValue);
If (G<>Nil) and (G<>Self) then
Raise ECodeGenerator.CreateFmt(SErrGeneratorExists,[AValue]);
end;
FName:=AValue;
end;
{ TCodeGenerators }
function TCodeGenerators.GetGen(Index: Integer): TCodeGeneratorItem;
begin
Result:=TCodeGeneratorItem(Items[Index]);
end;
procedure TCodeGenerators.SetGen(Index: Integer;
const AValue: TCodeGeneratorItem);
begin
Items[Index]:=AValue;
end;
function TCodeGenerators.RegisterCodeGenerator(const AName, ADescription : String;
AClass: TDDCustomCodeGeneratorClass): TCodeGeneratorItem;
begin
If (IndexOfCodeGenerator(AName)<>-1) then
Raise ECodeGenerator.CreateFmt(SErrGeneratorExists,[AName]);
Result:=Add as TCodeGeneratorItem;
Result.Name:=AName;
Result.Description:=ADescription;
Result.GeneratorClass:=AClass;
end;
procedure TCodeGenerators.UnRegisterCodeGenerator(AClass: TDDCustomCodeGeneratorClass);
begin
FindCodeGenerator(AClass).Free;
end;
procedure TCodeGenerators.UnRegisterCodeGenerator(const AName: String);
begin
FindCodeGenerator(AName).Free;
end;
function TCodeGenerators.IndexOfCodeGenerator(const AName: String): Integer;
begin
Result:=Count-1;
While (Result>=0) and (CompareText(GetGen(Result).Name,AName)<>0) do
Dec(Result);
end;
function TCodeGenerators.IndexOfCodeGenerator(AClass: TDDCustomCodeGeneratorClass): Integer;
begin
Result:=Count-1;
While (Result>=0) and (GetGen(Result).GeneratorClass<>AClass) do
Dec(Result);
end;
function TCodeGenerators.FindCodeGenerator(const AName: String): TCodeGeneratorItem;
Var
I : Integer;
begin
I:=IndexOfCodeGenerator(AName);
If (I=-1) then
Result:=Nil
else
Result:=GetGen(I);
end;
function TCodeGenerators.FindCodeGenerator(AClass: TDDCustomCodeGeneratorClass): TCodeGeneratorItem;
Var
I : Integer;
begin
I:=IndexOfCodeGenerator(AClass);
If (I=-1) then
Result:=Nil
else
Result:=GetGen(I);
end;
function TCodeGenerators.ConfigureCodeGenerator(
AGenerator: TDDCustomCodeGenerator): Boolean;
Var
G : TCodeGeneratorItem;
begin
Result:=True;
G:=FindCodeGenerator(TDDCustomCodeGeneratorClass(AGenerator.ClassType));
If Assigned(G) and Assigned(G.OnConfigureDialog) then
Result:=G.OnConfigureDialog(AGenerator);
end;
function TCodeGenerators.GeneratorByName(const AName: String): TCodeGeneratorItem;
begin
Result:=FindCodeGenerator(AName);
If (Result=Nil) then
Raise ECodegenerator.CreateFmt(SUnknownGenerator,[AName]);
end;
{ TCodeGeneratorOptions }
procedure TCodeGeneratorOptions.SetOPtions(const AValue: TCodeOptions);
begin
FOptions:=AValue;
end;
constructor TCodeGeneratorOptions.create;
begin
FOptions:=[coInterface,coImplementation,coUnit];
UnitName:='Unit1';
end;
procedure TCodeGeneratorOptions.Assign(ASource: TPersistent);
Var
CG : TCodeGeneratorOptions;
begin
If ASource is TCodeGeneratorOptions then
begin
CG:=ASource as TCodeGeneratorOptions;
FInterfaceUnits:=CG.InterfaceUnits;
FImplementationUnits:=CG.ImplementationUnits;
FOptions:=CG.FOptions;
FUnitName:=CG.UnitName;
FExtraSetterLine:=CG.ExtraSetterLine;
end
else
inherited Assign(ASource);
end;
procedure TCodeGeneratorOptions.SetUnitname(const AValue: String);
begin
if FUnitName=AValue then exit;
CheckIdentifier(AValue,False);
FUnitName:=AValue;
end;
procedure TCodeGeneratorOptions.SetInterfaceUnits(const AValue: String);
begin
if FInterfaceUnits=AValue then exit;
FInterfaceUnits:=AValue;
// Do some checks here
end;
procedure TCodeGeneratorOptions.SetImplementationUnits(const AValue: String);
begin
if FImplementationUnits=AValue then exit;
FImplementationUnits:=AValue;
end;
{ TClassCodeGeneratorOptions }
procedure TClassCodeGeneratorOptions.SetClassName(const AValue: String);
begin
if FClassName=AValue then
exit;
CheckIdentifier(AValue,False);
FClassName:=AValue;
end;
procedure TClassCodeGeneratorOptions.Assign(ASource: TPersistent);
Var
CO : TClassCodeGeneratorOptions;
begin
If ASource is TClassCodeGeneratorOptions then
begin
CO:=ASource as TClassCodeGeneratorOptions;
FClassName:=CO.FClassName;
FAncestorClass:=CO.FAncestorClass;
end;
inherited Assign(ASource);
end;
function TClassCodeGeneratorOptions.CleanObjectClassName: String;
Var
S : String;
begin
S:=ObjectClassName;
if (Length(S)>1) and (S[1]='T') then
Delete(S,1,1);
Result:=S;
end;
procedure TClassCodeGeneratorOptions.SetAncestorClass(const AValue: String);
begin
if (FAncestorClass=AValue) then
Exit;
CheckIdentifier(AValue,False);
FAncestorClass:=AValue;
end;
Finalization
DoneCodeGenerators;
end.