12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757 |
- {
- 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,
- ptDateTime, ptDateTime, ptCustom, ptCustom, ptCustom, ptCustom);
-
- 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.
|