fpddcodegen.pp 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2007 by Michael Van Canneyt, member of the
  4. Free Pascal development team
  5. Data Dictionary Code Generator Implementation.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit fpddcodegen;
  13. {$mode objfpc}{$H+}
  14. interface
  15. uses
  16. Classes, SysUtils, DB, fpDataDict;
  17. Type
  18. TPropType = (ptAuto,
  19. ptBoolean,
  20. ptShortint, ptByte,
  21. ptSmallInt, ptWord,
  22. ptLongint, ptCardinal,
  23. ptInt64, ptQWord,
  24. ptShortString, ptAnsiString, ptWideString,
  25. ptSingle, ptDouble, ptExtended, ptComp, ptCurrency,
  26. ptDateTime,
  27. ptEnumerated, ptSet, ptStream, ptTStrings,
  28. ptCustom);
  29. TVisibility = (vPrivate,vProtected,vPublic,vPublished);
  30. TPropAccess = (paReadWrite,paReadonly,paWriteonly);
  31. TFieldPropDefs = Class;
  32. { TFieldPropDef }
  33. TFieldPropDef = Class (TCollectionItem)
  34. private
  35. FEnabled: Boolean;
  36. FFieldName: String;
  37. FFieldType: TFieldType;
  38. FPropAccess: TPropAccess;
  39. FPropDef: String;
  40. FPropType : TPropType;
  41. FPRopSize: Integer;
  42. FPropName : String;
  43. FPropVis: TVisibility;
  44. function GetPropName: String;
  45. function GetPropType: TPropType;
  46. function GetPropTypeStored: boolean;
  47. procedure SetPropName(const AValue: String);
  48. Protected
  49. Procedure InitFromField(F : TField); virtual;
  50. Procedure InitFromDDFieldDef(F : TDDFieldDef);virtual;
  51. Public
  52. Constructor Create(ACollection : TCollection) ; override;
  53. Procedure Assign(ASource : TPersistent); override;
  54. Function FieldPropDefs : TFieldPropDefs;
  55. Function HasGetter : Boolean; Virtual; // Always false.
  56. Function HasSetter : Boolean; Virtual; // True for streams/strings
  57. Function ObjPasTypeDef : String; virtual; // Object pascal definition of type
  58. Function ObjPasReadDef : String; virtual; // Object pascal definition of getter
  59. Function ObjPasWriteDef : String; virtual; // Object pascal definition of setter
  60. Published
  61. Property Enabled : Boolean Read FEnabled Write FEnabled;
  62. Property FieldName : String Read FFieldName Write FFieldName;
  63. Property FieldType : TFieldType Read FFieldType Write FFieldType;
  64. Property PropertyName : String Read GetPropName Write SetPropName;
  65. Property PropertyType : TPropType Read GetPropType Write FPropType Stored GetPropTypeStored;
  66. Property PropertySize : Integer Read FPRopSize Write FPropSize;
  67. Property PropertyDef : String Read FPropDef Write FPropDef;
  68. Property PropertyVisibility : TVisibility Read FPropVis Write FPropVis;
  69. Property PropertyAccess : TPropAccess Read FPropAccess Write FPropAccess;
  70. end;
  71. { TFieldPropDefs }
  72. TFieldPropDefs = Class (TCollection)
  73. private
  74. function GetPropDef(Index : integer): TFieldPropDef;
  75. procedure SetPropDef(Index : integer; const AValue: TFieldPropDef);
  76. Public
  77. Function AddDef(AName : String) : TFieldPropDef;
  78. Procedure FromDataset(Dataset : TDataset; DoClear : Boolean = True);
  79. Procedure FromDDFieldDefs(Defs : TDDFieldDefs; DoClear : Boolean = True);
  80. Function IndexOfPropName(AName : String) : Integer;
  81. Function IndexOfFieldName(AName : String) : Integer;
  82. Function FindPropName(AName : String) : TFieldPropDef;
  83. Function FindFieldName(AName : String) : TFieldPropDef;
  84. Property PropDefs[Index : integer] : TFieldPropDef Read GetPropDef write SetPropDef; Default;
  85. end;
  86. { TFieldPropDefs }
  87. TCodeOption = (coInterface,coImplementation,coUnit);
  88. TCodeOptions = Set of TCodeOption;
  89. { TCodeGeneratorOptions }
  90. TCodeGeneratorOptions = Class(TPersistent)
  91. private
  92. FOptions: TCodeOptions;
  93. FUnitName: String;
  94. procedure SetUnitname(const AValue: String);
  95. Protected
  96. procedure SetOPtions(const AValue: TCodeOptions); virtual;
  97. Public
  98. Constructor create; virtual;
  99. Procedure Assign(ASource : TPersistent); override;
  100. Published
  101. Property Options : TCodeOptions Read FOptions Write SetOPtions;
  102. Property UnitName : String Read FUnitName Write SetUnitname;
  103. end;
  104. TCodeGeneratorOptionsClass = Class of TCodeGeneratorOptions;
  105. { TDDCustomCodeGenerator }
  106. TDDCustomCodeGenerator = Class(TComponent)
  107. FCodeOptions: TCodeGeneratorOptions;
  108. Private
  109. FIndent: Integer;
  110. FCurrentIndent :String;
  111. Protected
  112. // Utility routines to add lines to the code. Will prepend indent.
  113. procedure AddLn(Strings: TStrings); overload;
  114. procedure AddLn(Strings: TStrings; Line: String); overload;
  115. procedure AddLn(Strings: TStrings; Fmt: String; Args: array of const); overload;
  116. // Increase indent by defined amount
  117. procedure IncIndent;
  118. // Decrease indent by defined amount
  119. procedure DecIndent;
  120. // Start a method implementation. Writes the declaration. No Begin.
  121. procedure BeginMethod(STrings: TStrings; const Decl: String); Virtual;
  122. // End a method implementation. Writes the final end;
  123. procedure EndMethod(STrings: TStrings; const Decl: String);Virtual;
  124. // The following must be overridden by descendents
  125. Procedure DoGenerateInterface(Strings: TStrings); virtual;
  126. Procedure DoGenerateImplementation(Strings: TStrings); virtual;
  127. // Override this to return an instance of the proper class.
  128. Function CreateOptions : TCodeGeneratorOptions; virtual;
  129. // Override to return minimal uses clause for interface section.
  130. Function GetInterfaceUsesClause : String; virtual;
  131. // Override to return minimal uses clause for implementation section.
  132. Function GetImplementationUsesClause : String; virtual;
  133. // Must override to return real fielddefs
  134. function GetFieldDefs: TFieldPropDefs; virtual;
  135. // Must override to return real fielddefs
  136. procedure SetFieldDefs(const AValue: TFieldPropDefs); virtual;
  137. // Must override to return real SQL
  138. function GetSQL: TStrings; virtual;
  139. // Must override to set real SQL
  140. procedure SetSQL(const AValue: TStrings); virtual;
  141. Public
  142. Constructor Create(AOWner : TComponent); override;
  143. Destructor Destroy; override;
  144. Procedure GenerateCode(Stream : TStream);
  145. Procedure GenerateCode(Strings: TStrings);
  146. Class Function NeedsSQL : Boolean; virtual;
  147. Class Function NeedsFieldDefs : Boolean; virtual;
  148. Function ShowConfigDialog : Boolean;
  149. Property Fields : TFieldPropDefs Read GetFieldDefs Write SetFieldDefs;
  150. Property SQL : TStrings Read GetSQL Write SetSQL;
  151. Published
  152. Property CodeOptions : TCodeGeneratorOptions Read FCodeOptions Write FCodeOptions;
  153. Property Indent : Integer Read FIndent Write FIndent Default 2;
  154. end;
  155. { TClassCodeGeneratorOptions }
  156. TClassCodeGeneratorOptions = Class(TCodeGeneratorOptions)
  157. private
  158. FAncestorClass: String;
  159. FClassName: String;
  160. procedure SetAncestorClass(const AValue: String);
  161. Protected
  162. procedure SetClassName(const AValue: String); virtual;
  163. // Set to default value. Publish if needed.
  164. Property AncestorClass : String Read FAncestorClass Write SetAncestorClass;
  165. Public
  166. Procedure Assign(ASource : TPersistent); override;
  167. Published
  168. Property ObjectClassName : String Read FClassName Write SetClassName;
  169. end;
  170. { TDDClassCodeGenerator }
  171. TDDClassCodeGenerator = Class(TDDCustomCodeGenerator)
  172. private
  173. FAncestorClass : String;
  174. FClassName: String;
  175. FFieldDefs: TFieldPropDefs;
  176. FOptions: TCodeOptions;
  177. FStreamClass: String;
  178. FStringsClass: String;
  179. FUnitName: String;
  180. function GetOpts: TClassCodeGeneratorOptions;
  181. procedure SetAncestorClass(const AValue: String);
  182. procedure SetClassName(const AValue: String);
  183. procedure SetUnitname(const AValue: String);
  184. procedure WritePropertyGetterImpl(Strings: TStrings; F: TFieldPropDef);
  185. procedure WritePropertySetterImpl(Strings: TStrings; F: TFieldPropDef);
  186. Protected
  187. // Overrides from base class
  188. Function GetFieldDefs: TFieldPropDefs; override;
  189. procedure SetFieldDefs(const AValue: TFieldPropDefs); override;
  190. Function CreateOptions : TCodeGeneratorOptions; override;
  191. Procedure DoGenerateInterface(Strings: TStrings); override;
  192. Procedure DoGenerateImplementation(Strings: TStrings); override;
  193. // General code things.
  194. // Override to create TFieldpropdefs descendent instance.
  195. Function CreateFieldPropDefs : TFieldPropDefs; virtual;
  196. // Set to default value. Publish if needed.
  197. //
  198. // Interface routines
  199. //
  200. // Create class declaration.
  201. procedure CreateDeclaration(Strings: TStrings); virtual;
  202. // Create class head. Override to add after class start.
  203. procedure CreateClassHead(Strings: TStrings); virtual;
  204. // Create class end. Override to add before class end.
  205. procedure CreateClassEnd(Strings : TStrings); virtual;
  206. // Called right after section start is written.
  207. procedure WriteVisibilityStart(V: TVisibility; Strings: TStrings); virtual;
  208. // Writes a property declaration.
  209. Function PropertyDeclaration(Strings: TStrings; Def: TFieldPropDef) : String; virtual;
  210. // Writes private fields for class.
  211. procedure WritePrivateFields(Strings: TStrings); virtual;
  212. //
  213. // Implementation routines
  214. //
  215. // Create class implementation
  216. procedure CreateImplementation(Strings: TStrings); virtual;
  217. // Write implementation of constructor
  218. procedure WriteConstructorImplementation(Strings: TStrings); Virtual;
  219. // Write implementation of Destructor
  220. procedure WriteDestructorImplementation(Strings: TStrings); Virtual;
  221. // Write initialization of property (in constructor)
  222. procedure WriteFieldCreate(Strings: TStrings; F: TFieldPropDef); Virtual;
  223. // Write Finalization of property (in destructor)
  224. procedure WriteFieldDestroy(Strings: TStrings; F: TFieldPropDef); Virtual;
  225. //
  226. // Routines used in both Implementation/Interface
  227. //
  228. // Write property getter declaration
  229. Function PropertyGetterDeclaration(Def: TFieldPropDef; Impl : Boolean) : String; virtual;
  230. // Write property setter declaration
  231. Function PropertySetterDeclaration(Def: TFieldPropDef; Impl : Boolean) : String; virtual;
  232. // Determines whether a constructor/destructor pair is written.
  233. // By default one is written if ptStream/ptStrings is detected.
  234. Function NeedsConstructor : Boolean; virtual;
  235. // By default, this calls NeedsConstructor.
  236. Function NeedsDestructor : Boolean; virtual;
  237. // Override this to return the constructor declaration.
  238. Function ConstructorDeclaration(Impl : Boolean) : String; Virtual;
  239. // Override this to return the destructor declaration
  240. Function DestructorDeclaration(Impl : Boolean) : String; Virtual;
  241. //
  242. // Properties
  243. //
  244. // Class name used to instantiate TStrings instances.
  245. Property StringsClass : String Read FStringsClass Write FStringsClass;
  246. // Class name used to instantiate TStream instances.
  247. Property StreamClass : String Read FStreamClass Write FStreamClass;
  248. // Easy access to options
  249. Property ClassOptions : TClassCodeGeneratorOptions Read GetOpts;
  250. Public
  251. Constructor Create(AOwner : TComponent); override;
  252. Destructor Destroy; override;
  253. Procedure GenerateClass(Strings : TStrings); virtual;
  254. Procedure GenerateClass(Stream : TStream);
  255. Published
  256. Property Fields;
  257. end;
  258. ECodeGenerator = Class(Exception);
  259. { TExportFormatItem }
  260. TDDCustomCodeGeneratorClass = Class of TDDCustomCodeGenerator;
  261. TCodeGeneratorConfigureEvent = Function (Generator : TDDCustomCodeGenerator) : Boolean of object;
  262. { TCodeGeneratorItem }
  263. TCodeGeneratorItem = Class(TCollectionItem)
  264. private
  265. FClass: TDDCustomCodeGeneratorClass;
  266. FDescription: String;
  267. FName: String;
  268. FOnConfigure: TCodeGeneratorConfigureEvent;
  269. Procedure SetName(const AValue: String);
  270. Public
  271. Property GeneratorClass : TDDCustomCodeGeneratorClass Read FClass Write FClass;
  272. Published
  273. Property Name : String Read FName Write SetName;
  274. Property Description : String Read FDescription Write FDescription;
  275. Property OnConfigureDialog : TCodeGeneratorConfigureEvent Read FOnConfigure Write FOnConfigure;
  276. end;
  277. { TCodeGenerators }
  278. TCodeGenerators = Class(TCollection)
  279. private
  280. function GetGen(Index : Integer): TCodeGeneratorItem;
  281. procedure SetGen(Index : Integer; const AValue: TCodeGeneratorItem);
  282. Public
  283. // Registration/Unregistration
  284. Function RegisterCodeGenerator(Const AName, ADescription : String; AClass : TDDCustomCodeGeneratorClass) : TCodeGeneratorItem;
  285. Procedure UnRegisterCodeGenerator(AClass : TDDCustomCodeGeneratorClass);
  286. Procedure UnRegisterCodeGenerator(Const AName : String);
  287. // Searching
  288. Function IndexOfCodeGenerator(Const AName : String): Integer;
  289. Function IndexOfCodeGenerator(AClass : TDDCustomCodeGeneratorClass): Integer;
  290. Function FindCodeGenerator(Const AName : String) : TCodeGeneratorItem;
  291. Function FindCodeGenerator(AClass : TDDCustomCodeGeneratorClass) : TCodeGeneratorItem;
  292. // Shows configuration dialog, if one was configured for this class
  293. Function ConfigureCodeGenerator(AGenerator : TDDCustomCodeGenerator) : Boolean;
  294. Function GeneratorByName(Const AName : String) : TCodeGeneratorItem;
  295. Property Generators[Index : Integer] : TCodeGeneratorItem Read GetGen Write SetGen; default;
  296. end;
  297. Function CodeGenerators : TCodeGenerators;
  298. // Easy access functions
  299. Function RegisterCodeGenerator(Const AName,ADescription : String; AClass : TDDCustomCodeGeneratorClass) : TCodeGeneratorItem;
  300. Procedure UnRegisterCodeGenerator(AClass : TDDCustomCodeGeneratorClass);
  301. Procedure UnRegisterCodeGenerator(Const AName : String);
  302. Type
  303. TFieldPropTypeMap = Array[TFieldType] of TPropType;
  304. TPropertyVisibilityMap = Array[TPropType] of TVisibility;
  305. Var
  306. FieldToPropTypeMap : TFieldPropTypeMap = (
  307. ptCustom, ptAnsiString, ptSmallInt, ptLongInt, ptWord,
  308. ptBoolean, ptDouble, ptCurrency, ptCurrency, ptDateTime, ptDateTime, ptDateTime,
  309. ptCustom, ptCustom, ptLongInt, ptStream, ptTStrings, ptStream, ptTStrings,
  310. ptCustom, ptCustom, ptCustom, ptCustom, ptAnsiString,
  311. ptWideString, ptInt64, ptCustom, ptCustom, ptCustom,
  312. ptCustom, ptCustom, ptCustom, ptCustom, ptCustom,
  313. ptCustom, ptAnsiString, ptDateTime, ptCurrency, ptWideString, ptWideString);
  314. PropTypeToVisibilityMap : TPropertyVisibilityMap = (
  315. vPrivate,
  316. vPublished,
  317. vPublished, vPublished,
  318. vPublished, vPublished,
  319. vPublished, vPublished,
  320. vPublished, vPublished,
  321. vPublished, vPublished, vPublished,
  322. vPublished, vPublished, vPublished, vPublished, vPublished,
  323. vPublished,
  324. vPublished, vPublished, vPublic, vPublished,
  325. vPrivate);
  326. Const
  327. ptInteger = ptLongint;
  328. ptString = ptAnsiString;
  329. Const
  330. PropTypeNames : Array[TPropType] of string
  331. = ('',
  332. 'Boolean',
  333. 'ShortInt', 'Byte',
  334. 'SmallInt', 'Word',
  335. 'Longint', 'Cardinal',
  336. 'Int64', 'QWord',
  337. 'String', 'AnsiString', 'WideString',
  338. 'Single', 'Double' , 'Extended', 'Comp', 'Currency',
  339. 'TDateTime',
  340. '','', 'TStream', 'TStrings',
  341. '');
  342. Resourcestring
  343. SErrInvalidIdentifier = '"%s" is not a valid object pascal identifier.';
  344. SErrGeneratorExists = 'A code generator with name "%s" already exists';
  345. SUnknownGenerator = 'Unknown code generator name : "%s"';
  346. Function MakeIdentifier (S : String) : String;
  347. Function CreateString(S : String) : String;
  348. Procedure CheckIdentifier(AValue : String; AllowEmpty : Boolean = True);
  349. implementation
  350. Function CreateString(S : String) : String;
  351. begin
  352. Result:=StringReplace(S,'''','''''',[rfReplaceAll]);
  353. Result:=''''+Result+'''';
  354. end;
  355. Procedure CheckIdentifier(AValue : String; AllowEmpty : Boolean = True);
  356. begin
  357. If ((AValue='') and Not AllowEmpty) or Not IsValidIdent(AValue) then
  358. Raise ECodeGenerator.CreateFmt(SErrInvalidIdentifier,[AValue]);
  359. end;
  360. Var
  361. CodeGens : TCodeGenerators;
  362. function CodeGenerators: TCodeGenerators;
  363. begin
  364. If (CodeGens=Nil) then
  365. CodeGens:=TCodeGenerators.Create(TCodeGeneratorItem);
  366. Result:=CodeGens;
  367. end;
  368. Procedure DoneCodeGenerators;
  369. begin
  370. FreeAndNil(CodeGens);
  371. end;
  372. function RegisterCodeGenerator(const AName, ADescription: String;
  373. AClass: TDDCustomCodeGeneratorClass): TCodeGeneratorItem;
  374. begin
  375. CodeGenerators.RegisterCodeGenerator(AName,ADescription,AClass);
  376. end;
  377. procedure UnRegisterCodeGenerator(AClass: TDDCustomCodeGeneratorClass);
  378. begin
  379. CodeGenerators.UnRegisterCodeGenerator(AClass);
  380. end;
  381. procedure UnRegisterCodeGenerator(const AName: String);
  382. begin
  383. CodeGenerators.UnRegisterCodeGenerator(AName);
  384. end;
  385. Function MakeIdentifier (S : String) : String;
  386. Var
  387. I : Integer;
  388. begin
  389. Result:=S;
  390. For I:=Length(Result) downto 0 do
  391. If Not ((Upcase(Result[i]) in ['_','A'..'Z'])
  392. or ((I>0) and (Result[i] in (['0'..'9'])))) then
  393. Delete(Result,i,1);
  394. end;
  395. { TFieldPropDef }
  396. function TFieldPropDef.GetPropName: String;
  397. begin
  398. Result:=FPropName;
  399. If (Result='') then
  400. Result:=MakeIdentifier(FFieldName);
  401. end;
  402. function TFieldPropDef.GetPropType: TPropType;
  403. begin
  404. Result:=FPropType;
  405. If (Result=ptAuto) then
  406. Result:=FieldToPropTypeMap[FieldType];
  407. end;
  408. function TFieldPropDef.GetPropTypeStored: boolean;
  409. begin
  410. Result:=(FPropType<>ptAuto)
  411. end;
  412. procedure TFieldPropDef.SetPropName(const AValue: String);
  413. begin
  414. If (AValue<>FPropName) then
  415. begin
  416. CheckIdentifier(AValue);
  417. FPropName:=AValue;
  418. end;
  419. end;
  420. procedure TFieldPropDef.InitFromField(F: TField);
  421. begin
  422. FieldType:=F.DataType;
  423. PropertySize:=F.Size;
  424. end;
  425. procedure TFieldPropDef.InitFromDDFieldDef(F: TDDFieldDef);
  426. begin
  427. FieldType:=F.FieldType;
  428. PropertySize:=F.Size;
  429. end;
  430. constructor TFieldPropDef.Create(ACollection: TCollection);
  431. begin
  432. inherited Create(ACollection);
  433. FPropVis:=vPublished
  434. end;
  435. procedure TFieldPropDef.Assign(ASource: TPersistent);
  436. Var
  437. PD : TFieldPropDef;
  438. begin
  439. if (ASource is TFieldPropDef) then
  440. begin
  441. PD:=ASource as TFieldPropDef;
  442. FEnabled:=PD.Enabled;
  443. FFieldName:=PD.FFieldName;
  444. FFieldType:=PD.FFIeldType;
  445. FPropAccess:=PD.FPropAccess;
  446. FPropDef:=PD.FPropDef;
  447. FPropType:=PD.FPropType;
  448. FPRopSize:=PD.FPropSize;
  449. FPropName:=PD.FPropName;
  450. FPropVis:=PD.FPropVis;
  451. end
  452. else
  453. inherited Assign(ASource);
  454. end;
  455. function TFieldPropDef.FieldPropDefs: TFieldPropDefs;
  456. begin
  457. Result:=Collection as TFieldPropDefs;
  458. end;
  459. function TFieldPropDef.HasGetter: Boolean;
  460. begin
  461. Result:=False;
  462. end;
  463. function TFieldPropDef.HasSetter: Boolean;
  464. begin
  465. Result:=(PropertyAccess in [paReadWrite,paWriteOnly])
  466. and (PropertyType in [ptStream,ptTStrings]);
  467. end;
  468. function TFieldPropDef.ObjPasTypeDef: String;
  469. begin
  470. If PropertyType in [ptCustom,ptSet,ptEnumerated] then
  471. Result:=PropertyDef
  472. else
  473. begin
  474. Result:=PropTypeNames[PropertyType];
  475. If PropertyType=ptShortString then
  476. Result:=Result+Format('String[%d]',[PropertySize]);
  477. end;
  478. end;
  479. function TFieldPropDef.ObjPasReadDef: String;
  480. begin
  481. If HasGetter then
  482. Result:='Get'+PropertyName
  483. else
  484. Result:='F'+PropertyName;
  485. end;
  486. function TFieldPropDef.ObjPasWriteDef: String;
  487. begin
  488. If HasSetter then
  489. Result:='Set'+PropertyName
  490. else
  491. Result:='F'+PropertyName;
  492. end;
  493. { TFieldPropDefs }
  494. function TFieldPropDefs.GetPropDef(Index : integer): TFieldPropDef;
  495. begin
  496. Result:=TFieldPropDef(Items[index]);
  497. end;
  498. procedure TFieldPropDefs.SetPropDef(Index : integer; const AValue: TFieldPropDef);
  499. begin
  500. Items[Index]:=AValue;
  501. end;
  502. function TFieldPropDefs.AddDef(AName: String): TFieldPropDef;
  503. begin
  504. Result:=Add As TFieldPropDef;
  505. Result.FieldName:=AName;
  506. end;
  507. procedure TFieldPropDefs.FromDataset(Dataset: TDataset; DoClear: Boolean = True);
  508. Var
  509. I : Integer;
  510. D : TFieldPropDef;
  511. F : TField;
  512. begin
  513. If DoClear then
  514. Clear;
  515. For I:=0 to Dataset.Fields.Count-1 do
  516. begin
  517. F:=Dataset.Fields[I];
  518. D:=AddDef(F.FieldName);
  519. D.Enabled:=True;
  520. D.InitFromField(F);
  521. end;
  522. end;
  523. procedure TFieldPropDefs.FromDDFieldDefs(Defs: TDDFieldDefs; DoClear: Boolean = True);
  524. Var
  525. I : Integer;
  526. D : TFieldPropDef;
  527. F : TDDFieldDef;
  528. begin
  529. If DoClear then
  530. Clear;
  531. For I:=0 to Defs.Count-1 do
  532. begin
  533. F:=Defs[I];
  534. D:=AddDef(F.FieldName);
  535. D.Enabled:=True;
  536. D.InitFromDDFieldDef(F);
  537. end;
  538. end;
  539. function TFieldPropDefs.IndexOfPropName(AName: String): Integer;
  540. begin
  541. Result:=Count-1;
  542. While (Result>=0) and (CompareText(GetPropDef(Result).PropertyName,AName)<>0) do
  543. Dec(Result);
  544. end;
  545. function TFieldPropDefs.IndexOfFieldName(AName: String): Integer;
  546. begin
  547. Result:=Count-1;
  548. While (Result>=0) and (CompareText(GetPropDef(Result).FieldName,AName)<>0) do
  549. Dec(Result);
  550. end;
  551. function TFieldPropDefs.FindPropName(AName: String): TFieldPropDef;
  552. Var
  553. I : Integer;
  554. begin
  555. I:=IndexOfPropName(AName);
  556. If (I<>-1) then
  557. Result:=GetpropDef(I)
  558. else
  559. Result:=Nil;
  560. end;
  561. function TFieldPropDefs.FindFieldName(AName: String): TFieldPropDef;
  562. Var
  563. I : Integer;
  564. begin
  565. I:=IndexOfFieldName(AName);
  566. If (I<>-1) then
  567. Result:=GetpropDef(I)
  568. else
  569. Result:=Nil;
  570. end;
  571. { TDDClassCodeGenerator }
  572. procedure TDDClassCodeGenerator.SetClassName(const AValue: String);
  573. begin
  574. end;
  575. procedure TDDClassCodeGenerator.SetAncestorClass(const AValue: String);
  576. begin
  577. FAncestorClass:=AValue;
  578. end;
  579. function TDDClassCodeGenerator.GetOpts: TClassCodeGeneratorOptions;
  580. begin
  581. Result:=CodeOptions as TClassCodeGeneratorOptions;
  582. end;
  583. procedure TDDClassCodeGenerator.SetFieldDefs(const AValue: TFieldPropDefs);
  584. begin
  585. if FFieldDefs=AValue then exit;
  586. FFieldDefs:=AValue;
  587. end;
  588. procedure TDDClassCodeGenerator.SetUnitname(const AValue: String);
  589. begin
  590. FUnitName:=AValue;
  591. end;
  592. function TDDClassCodeGenerator.CreateFieldPropDefs: TFieldPropDefs;
  593. begin
  594. Result:=TFieldPropDefs.Create(TFieldPropDef);
  595. end;
  596. constructor TDDClassCodeGenerator.Create(AOwner: TComponent);
  597. begin
  598. inherited Create(AOwner);
  599. FFieldDefs:=CreateFieldPropDefs;
  600. end;
  601. destructor TDDClassCodeGenerator.Destroy;
  602. begin
  603. FreeAndNil(FFieldDefs);
  604. inherited Destroy;
  605. end;
  606. procedure TDDClassCodeGenerator.GenerateClass(Strings: TStrings);
  607. begin
  608. IncIndent;
  609. Try
  610. AddLn(Strings,'// Declaration');
  611. AddLn(Strings,'Type');
  612. AddLn(Strings);
  613. CreateDeclaration(Strings);
  614. AddLn(Strings);
  615. AddLn(Strings,'// Implementation');
  616. AddLn(Strings);
  617. CreateDeclaration(Strings);
  618. Finally
  619. DecIndent;
  620. end;
  621. end;
  622. Procedure TDDClassCodeGenerator.CreateDeclaration(Strings : TStrings);
  623. Const
  624. VisibilityNames : Array [TVisibility] of string
  625. = ('Private','Protected','Public','Published');
  626. Var
  627. V : TVisibility;
  628. I : Integer;
  629. F : TFieldPropDef;
  630. begin
  631. CreateClassHead(Strings);
  632. AddLn(Strings,VisibilityNames[vPrivate]);
  633. WritePrivateFields(Strings);
  634. For v:=Low(TVisibility) to High(TVisibility) do
  635. begin
  636. AddLn(Strings,VisibilityNames[v]);
  637. IncIndent;
  638. Try
  639. WriteVisibilityStart(V,Strings);
  640. For I:=0 to Fields.Count-1 do
  641. begin
  642. F:=Fields[i];
  643. if F.Enabled and (F.PropertyVisibility=v) then
  644. AddLn(Strings,PropertyDeclaration(Strings,F)+';');
  645. end;
  646. Finally
  647. Decindent;
  648. end;
  649. end;
  650. CreateClassEnd(Strings);
  651. end;
  652. Procedure TDDClassCodeGenerator.WritePrivateFields(Strings : TStrings);
  653. Var
  654. I : Integer;
  655. F : TFieldPropDef;
  656. begin
  657. IncIndent;
  658. Try
  659. For I:=0 to Fields.Count-1 do
  660. begin
  661. F:=Fields[i];
  662. if F.Enabled then
  663. AddLn(Strings,'F%s : %s;',[F.PropertyName,F.ObjPasTypeDef]);
  664. end;
  665. Finally
  666. DecIndent;
  667. end;
  668. end;
  669. Procedure TDDClassCodeGenerator.CreateImplementation(Strings : TStrings);
  670. Var
  671. B : Boolean;
  672. I : Integer;
  673. F : TFieldPropDef;
  674. begin
  675. AddLn(Strings,' { %s } ',[ClassOptions.ObjectClassName]);
  676. AddLn(Strings);
  677. If NeedsConstructor then
  678. begin
  679. Addln(Strings,' { Constructor and destructor }');
  680. Addln(Strings);
  681. WriteConstructorImplementation(Strings);
  682. WriteDestructorImplementation(Strings);
  683. end;
  684. B:=False;
  685. For I:=0 to Fields.Count-1 do
  686. begin
  687. F:=Fields[i];
  688. if F.Enabled and F.HasGetter then
  689. begin
  690. If not B then
  691. begin
  692. B:=True;
  693. Addln(Strings,' { Property Getters }');
  694. Addln(Strings);
  695. end;
  696. WritePropertyGetterImpl(Strings,F);
  697. end;
  698. end;
  699. B:=False;
  700. For I:=0 to Fields.Count-1 do
  701. begin
  702. F:=Fields[i];
  703. if F.Enabled and F.HasGetter then
  704. begin
  705. If not B then
  706. begin
  707. B:=True;
  708. Addln(Strings,' { Property Setters }');
  709. Addln(Strings);
  710. end;
  711. WritePropertySetterImpl(Strings,F);
  712. end;
  713. end;
  714. end;
  715. Procedure TDDClassCodeGenerator.WritePropertyGetterImpl(Strings : TStrings; F : TFieldPropDef);
  716. Var
  717. S : String;
  718. begin
  719. S:=PropertyGetterDeclaration(F,True);
  720. BeginMethod(Strings,S);
  721. AddLn(Strings,'begin');
  722. IncIndent;
  723. Try
  724. AddLn(Strings,Format('Result:=F%s',[F.PropertyName]));
  725. Finally
  726. DecIndent;
  727. end;
  728. EndMethod(Strings,S);
  729. end;
  730. Procedure TDDClassCodeGenerator.WritePropertySetterImpl(Strings : TStrings; F : TFieldPropDef);
  731. Var
  732. S : String;
  733. begin
  734. S:=PropertyGetterDeclaration(F,True);
  735. BeginMethod(Strings,S);
  736. AddLn(Strings,'begin');
  737. IncIndent;
  738. Try
  739. Case F.PropertyType of
  740. ptTStrings :
  741. S:=Format('F%s.Assign(AValue);',[F.PropertyName]);
  742. ptStream :
  743. S:=Format('F%s.CopyFrom(AValue,0);',[F.PropertyName]);
  744. else
  745. S:=Format('F%s:=AValue',[F.PropertyName]);
  746. end;
  747. AddLn(Strings,S);
  748. Finally
  749. DecIndent;
  750. end;
  751. EndMethod(Strings,S);
  752. end;
  753. function TDDClassCodeGenerator.GetFieldDefs: TFieldPropDefs;
  754. begin
  755. Result:=FFieldDefs;
  756. end;
  757. function TDDClassCodeGenerator.CreateOptions: TCodeGeneratorOptions;
  758. begin
  759. Result:=TClassCodeGeneratorOptions.Create;
  760. end;
  761. procedure TDDClassCodeGenerator.DoGenerateInterface(Strings: TStrings);
  762. begin
  763. AddLn(Strings,'Type');
  764. AddLn(Strings);
  765. IncIndent;
  766. Try
  767. CreateDeclaration(Strings);
  768. Finally
  769. DecIndent;
  770. end;
  771. end;
  772. procedure TDDClassCodeGenerator.DoGenerateImplementation(Strings: TStrings);
  773. begin
  774. CreateImplementation(Strings);
  775. end;
  776. Procedure TDDClassCodeGenerator.WriteConstructorImplementation(Strings : TStrings);
  777. Var
  778. I : Integer;
  779. F : TFieldPropDef;
  780. S : String;
  781. begin
  782. S:=ConstructorDeclaration(True);
  783. BeginMethod(Strings,S);
  784. AddLn(Strings,'begin');
  785. IncIndent;
  786. Try
  787. For I:=0 to Fields.Count-1 do
  788. begin
  789. F:=Fields[i];
  790. if F.Enabled then
  791. WriteFieldCreate(Strings,F);
  792. end;
  793. Finally
  794. DecIndent;
  795. end;
  796. EndMethod(Strings,S);
  797. end;
  798. Procedure TDDClassCodeGenerator.WriteDestructorImplementation(Strings : TStrings);
  799. Var
  800. I : Integer;
  801. F : TFieldPropDef;
  802. S : String;
  803. begin
  804. S:=DestructorDeclaration(True);
  805. BeginMethod(Strings,S);
  806. AddLn(Strings,'begin');
  807. IncIndent;
  808. Try
  809. For I:=0 to Fields.Count-1 do
  810. begin
  811. F:=Fields[i];
  812. if F.Enabled then
  813. WriteFieldDestroy(Strings,F);
  814. end;
  815. AddLn(Strings,'Inherited;');
  816. Finally
  817. DecIndent;
  818. end;
  819. EndMethod(Strings,S);
  820. end;
  821. Procedure TDDClassCodeGenerator.WriteFieldCreate(Strings : TStrings;F : TFieldPropDef);
  822. Var
  823. S : String;
  824. begin
  825. Case F.PropertyType of
  826. ptTStrings :
  827. begin
  828. S:=Format('F%s:=%s.Create;',[F.PropertyName,StringsClass]);
  829. AddLn(Strings,S);
  830. end;
  831. ptStream :
  832. begin
  833. S:=Format('F%s:=%s.Create;',[F.PropertyName,StreamClass]);
  834. AddLn(Strings,S);
  835. end;
  836. ptCustom :
  837. begin
  838. AddLn(Strings,'// Add Creation for '+F.PropertyName);
  839. end;
  840. end;
  841. end;
  842. Procedure TDDClassCodeGenerator.WriteFieldDestroy(Strings : TStrings;F : TFieldPropDef);
  843. Var
  844. S : String;
  845. begin
  846. Case F.PropertyType of
  847. ptTStrings,
  848. ptStream :
  849. begin
  850. S:=Format('FreeAndNil(F%s);',[F.PropertyName]);
  851. AddLn(Strings,S);
  852. end;
  853. ptCustom :
  854. begin
  855. AddLn(Strings,'// Add destroy for '+F.PropertyName);
  856. end;
  857. end;
  858. end;
  859. Procedure TDDClassCodeGenerator.CreateClassHead(Strings : TStrings);
  860. begin
  861. Addln(Strings,'{ %s }',[ClassOptions.ObjectClassName]);
  862. AddLn(Strings);
  863. AddLn(Strings,'%s = Class(%s)',[ClassOptions.ObjectClassName,ClassOptions.AncestorClass]);
  864. end;
  865. Procedure TDDClassCodeGenerator.CreateClassEnd(Strings : TStrings);
  866. begin
  867. AddLn(Strings,'end;');
  868. AddLn(Strings);
  869. end;
  870. Procedure TDDClassCodeGenerator.WriteVisibilityStart(V : TVisibility; Strings : TStrings);
  871. Var
  872. I : Integer;
  873. F : TFieldPropDef;
  874. begin
  875. If (v=vPrivate) then
  876. begin
  877. For I:=0 to Fields.Count-1 do
  878. begin
  879. F:=Fields[i];
  880. If F.Enabled then
  881. begin
  882. if (F.Hasgetter) then
  883. AddLn(Strings,PropertyGetterDeclaration(F,False));
  884. if (Fields[i].HasSetter) then
  885. AddLn(Strings,PropertySetterDeclaration(F,False));
  886. end;
  887. end;
  888. end
  889. else if v=vPublic then
  890. begin
  891. If NeedsConstructor then
  892. begin
  893. AddLn(Strings,ConstructorDeclaration(False));
  894. Addln(Strings,DestructorDeclaration(False));
  895. end;
  896. end
  897. // Do nothing
  898. end;
  899. Function TDDClassCodeGenerator.PropertyDeclaration(Strings : TStrings; Def : TFieldPropDef) : String;
  900. begin
  901. Result:='Property '+Def.PropertyName+' ';
  902. Result:=Result+': '+Def.ObjPasTypeDef;
  903. If Def.PropertyAccess in [paReadWrite,paReadOnly] then
  904. Result:=Result+' Read '+Def.ObjPasReadDef;
  905. If Def.PropertyAccess in [paReadWrite,paWriteOnly] then
  906. Result:=Result+' Write '+Def.ObjPasWriteDef;
  907. end;
  908. Function TDDClassCodeGenerator.PropertyGetterDeclaration(Def : TFieldPropDef; Impl : Boolean) : String;
  909. begin
  910. Result:='Function ';
  911. If Impl then
  912. Result:=Result+Classoptions.ObjectClassName+'.';
  913. If Impl then
  914. Result:=Result+Def.ObjPasReadDef+' : '+Def.ObjPasTypeDef+';';
  915. end;
  916. Function TDDClassCodeGenerator.PropertySetterDeclaration(Def : TFieldPropDef; Impl : Boolean) : String;
  917. begin
  918. Result:='Procedure ';
  919. If Impl then
  920. Result:=Result+ClassOptions.ObjectClassName+'.';
  921. Result:=Result+Def.ObjPasReadDef+' (AValue : '+Def.ObjPasTypeDef+');';
  922. end;
  923. function TDDClassCodeGenerator.NeedsConstructor: Boolean;
  924. Var
  925. I : Integer;
  926. F : TFieldPropDef;
  927. begin
  928. Result:=False;
  929. I:=Fields.Count-1;
  930. While (Not Result) and (I>=0) do
  931. begin
  932. F:=Fields[i];
  933. Result:=F.Enabled and (F.PropertyType in [ptStream,ptTStrings]);
  934. Dec(I);
  935. end;
  936. end;
  937. function TDDClassCodeGenerator.NeedsDestructor: Boolean;
  938. begin
  939. Result:=NeedsConstructor;
  940. end;
  941. Function TDDClassCodeGenerator.ConstructorDeclaration(Impl : Boolean) : String;
  942. begin
  943. Result:='Constructor ';
  944. If Impl then
  945. Result:=Result+ClassOptions.ObjectClassName+'.';
  946. Result:=Result+'Create;';
  947. end;
  948. Function TDDClassCodeGenerator.DestructorDeclaration(Impl : Boolean) : String;
  949. begin
  950. Result:='Destructor ';
  951. If Impl then
  952. Result:=Result+ClassOptions.ObjectClassName+'.';
  953. Result:=Result+'Destroy; Override;';
  954. end;
  955. procedure TDDClassCodeGenerator.GenerateClass(Stream: TStream);
  956. Var
  957. L : TStringList;
  958. begin
  959. L:=TStringList.Create;
  960. try
  961. GenerateClass(L);
  962. L.SaveToStream(Stream);
  963. finally
  964. L.Free;
  965. end;
  966. end;
  967. { TDDCustomCodeGenerator }
  968. procedure TDDCustomCodeGenerator.IncIndent;
  969. begin
  970. FCurrentIndent:=FCurrentIndent+StringOfChar(' ',FIndent);
  971. end;
  972. procedure TDDCustomCodeGenerator.DecIndent;
  973. begin
  974. Delete(FCurrentIndent,1,FIndent);
  975. end;
  976. procedure TDDCustomCodeGenerator.DoGenerateInterface(Strings: TStrings);
  977. begin
  978. end;
  979. procedure TDDCustomCodeGenerator.DoGenerateImplementation(Strings: TStrings);
  980. begin
  981. end;
  982. function TDDCustomCodeGenerator.GetFieldDefs: TFieldPropDefs;
  983. begin
  984. end;
  985. procedure TDDCustomCodeGenerator.SetFieldDefs(const AValue: TFieldPropDefs);
  986. begin
  987. end;
  988. function TDDCustomCodeGenerator.GetSQL: TStrings;
  989. begin
  990. Result:=Nil;
  991. end;
  992. procedure TDDCustomCodeGenerator.SetSQL(const AValue: TStrings);
  993. begin
  994. // Do nothing
  995. end;
  996. constructor TDDCustomCodeGenerator.Create(AOWner: TComponent);
  997. begin
  998. inherited Create(AOWner);
  999. FCodeOptions:=CreateOptions;
  1000. FIndent:=2;
  1001. end;
  1002. destructor TDDCustomCodeGenerator.Destroy;
  1003. begin
  1004. FreeAndNil(FCodeOptions);
  1005. inherited Destroy;
  1006. end;
  1007. procedure TDDCustomCodeGenerator.AddLn(Strings : TStrings);
  1008. begin
  1009. Strings.Add('');
  1010. end;
  1011. procedure TDDCustomCodeGenerator.AddLn(Strings : TStrings; Line : String);
  1012. begin
  1013. Strings.Add(FCurrentIndent+Line);
  1014. end;
  1015. procedure TDDCustomCodeGenerator.AddLn(Strings : TStrings; Fmt : String; Args : Array Of Const);
  1016. begin
  1017. Strings.Add(FCurrentIndent+Format(Fmt,Args));
  1018. end;
  1019. function TDDCustomCodeGenerator.CreateOptions: TCodeGeneratorOptions;
  1020. begin
  1021. Result:=TCodeGeneratorOptions.Create;
  1022. end;
  1023. function TDDCustomCodeGenerator.GetInterfaceUsesClause: String;
  1024. begin
  1025. Result:='Classes, SysUtils';
  1026. end;
  1027. function TDDCustomCodeGenerator.GetImplementationUsesClause: String;
  1028. begin
  1029. Result:='';
  1030. end;
  1031. procedure TDDCustomCodeGenerator.GenerateCode(Stream: TStream);
  1032. Var
  1033. L : TStringList;
  1034. begin
  1035. L:=TStringList.Create;
  1036. try
  1037. GenerateCode(L);
  1038. L.SaveToStream(Stream);
  1039. finally
  1040. L.Free;
  1041. end;
  1042. end;
  1043. procedure TDDCustomCodeGenerator.GenerateCode(Strings: TStrings);
  1044. Procedure MaybeAddUsesClause(S : String);
  1045. begin
  1046. If (S<>'') then
  1047. begin
  1048. If S[Length(S)]<>';' then
  1049. S:=S+';';
  1050. AddLn(Strings,'Uses '+S);
  1051. AddLn(Strings);
  1052. end;
  1053. end;
  1054. Var
  1055. S : String;
  1056. begin
  1057. FCurrentIndent:='';
  1058. if (coUnit in CodeOptions.Options) then
  1059. begin
  1060. Addln(Strings,'Unit '+CodeOptions.UnitName+';');
  1061. Addln(Strings);
  1062. Addln(Strings,'Interface');
  1063. Addln(Strings);
  1064. S:=GetInterfaceUsesClause;
  1065. MaybeAddUsesClause(S);
  1066. end;
  1067. if coInterface in CodeOptions.Options then
  1068. begin
  1069. DoGenerateInterface(Strings);
  1070. Addln(Strings);
  1071. end;
  1072. FCurrentIndent:='';
  1073. if coUnit in CodeOptions.options then
  1074. begin
  1075. if coImplementation in CodeOptions.Options then
  1076. begin
  1077. Addln(Strings,'Implementation');
  1078. S:=GetImplementationUsesClause;
  1079. MaybeAddUsesClause(S);
  1080. end;
  1081. end;
  1082. if coImplementation in CodeOptions.Options then
  1083. begin
  1084. Addln(Strings);
  1085. DoGenerateImplementation(Strings);
  1086. end;
  1087. Addln(Strings);
  1088. if (coUnit in CodeOptions.options) then
  1089. Addln(Strings,'end.');
  1090. end;
  1091. class function TDDCustomCodeGenerator.NeedsSQL: Boolean;
  1092. begin
  1093. Result:=False;
  1094. end;
  1095. class function TDDCustomCodeGenerator.NeedsFieldDefs: Boolean;
  1096. begin
  1097. Result:=False;
  1098. end;
  1099. function TDDCustomCodeGenerator.ShowConfigDialog: Boolean;
  1100. begin
  1101. end;
  1102. Procedure TDDCustomCodeGenerator.BeginMethod(STrings : TStrings; Const Decl : String);
  1103. begin
  1104. AddLn(Strings,Decl);
  1105. AddLn(Strings);
  1106. end;
  1107. Procedure TDDCustomCodeGenerator.EndMethod(STrings : TStrings; Const Decl : String);
  1108. begin
  1109. AddLn(Strings,'end;');
  1110. Addln(Strings);
  1111. Addln(Strings);
  1112. end;
  1113. { TCodeGeneratorItem }
  1114. procedure TCodeGeneratorItem.SetName(const AValue: String);
  1115. Var
  1116. G : TCodeGeneratorItem;
  1117. begin
  1118. if (FName=AValue) then
  1119. exit;
  1120. If (AValue<>'') then
  1121. begin
  1122. G:=TCodeGenerators(Collection).FindCodeGenerator(AValue);
  1123. If (G<>Nil) and (G<>Self) then
  1124. Raise ECodeGenerator.CreateFmt(SErrGeneratorExists,[AValue]);
  1125. end;
  1126. FName:=AValue;
  1127. end;
  1128. { TCodeGenerators }
  1129. function TCodeGenerators.GetGen(Index: Integer): TCodeGeneratorItem;
  1130. begin
  1131. Result:=TCodeGeneratorItem(Items[Index]);
  1132. end;
  1133. procedure TCodeGenerators.SetGen(Index: Integer;
  1134. const AValue: TCodeGeneratorItem);
  1135. begin
  1136. Items[Index]:=AValue;
  1137. end;
  1138. function TCodeGenerators.RegisterCodeGenerator(const AName, ADescription : String;
  1139. AClass: TDDCustomCodeGeneratorClass): TCodeGeneratorItem;
  1140. begin
  1141. If (IndexOfCodeGenerator(AName)<>-1) then
  1142. Raise ECodeGenerator.CreateFmt(SErrGeneratorExists,[AName]);
  1143. Result:=Add as TCodeGeneratorItem;
  1144. Result.Name:=AName;
  1145. Result.Description:=ADescription;
  1146. Result.GeneratorClass:=AClass;
  1147. end;
  1148. procedure TCodeGenerators.UnRegisterCodeGenerator(AClass: TDDCustomCodeGeneratorClass);
  1149. begin
  1150. FindCodeGenerator(AClass).Free;
  1151. end;
  1152. procedure TCodeGenerators.UnRegisterCodeGenerator(const AName: String);
  1153. begin
  1154. FindCodeGenerator(AName).Free;
  1155. end;
  1156. function TCodeGenerators.IndexOfCodeGenerator(const AName: String): Integer;
  1157. begin
  1158. Result:=Count-1;
  1159. While (Result>=0) and (CompareText(GetGen(Result).Name,AName)<>0) do
  1160. Dec(Result);
  1161. end;
  1162. function TCodeGenerators.IndexOfCodeGenerator(AClass: TDDCustomCodeGeneratorClass): Integer;
  1163. begin
  1164. Result:=Count-1;
  1165. While (Result>=0) and (GetGen(Result).GeneratorClass<>AClass) do
  1166. Dec(Result);
  1167. end;
  1168. function TCodeGenerators.FindCodeGenerator(const AName: String): TCodeGeneratorItem;
  1169. Var
  1170. I : Integer;
  1171. begin
  1172. I:=IndexOfCodeGenerator(AName);
  1173. If (I=-1) then
  1174. Result:=Nil
  1175. else
  1176. Result:=GetGen(I);
  1177. end;
  1178. function TCodeGenerators.FindCodeGenerator(AClass: TDDCustomCodeGeneratorClass): TCodeGeneratorItem;
  1179. Var
  1180. I : Integer;
  1181. begin
  1182. I:=IndexOfCodeGenerator(AClass);
  1183. If (I=-1) then
  1184. Result:=Nil
  1185. else
  1186. Result:=GetGen(I);
  1187. end;
  1188. function TCodeGenerators.ConfigureCodeGenerator(
  1189. AGenerator: TDDCustomCodeGenerator): Boolean;
  1190. Var
  1191. G : TCodeGeneratorItem;
  1192. begin
  1193. Result:=True;
  1194. G:=FindCodeGenerator(TDDCustomCodeGeneratorClass(AGenerator.ClassType));
  1195. If Assigned(G) and Assigned(G.OnConfigureDialog) then
  1196. Result:=G.OnConfigureDialog(AGenerator);
  1197. end;
  1198. function TCodeGenerators.GeneratorByName(const AName: String): TCodeGeneratorItem;
  1199. begin
  1200. Result:=FindCodeGenerator(AName);
  1201. If (Result=Nil) then
  1202. Raise ECodegenerator.CreateFmt(SUnknownGenerator,[AName]);
  1203. end;
  1204. { TCodeGeneratorOptions }
  1205. procedure TCodeGeneratorOptions.SetOPtions(const AValue: TCodeOptions);
  1206. begin
  1207. FOptions:=AValue;
  1208. end;
  1209. constructor TCodeGeneratorOptions.create;
  1210. begin
  1211. FOptions:=[coInterface,coImplementation,coUnit];
  1212. UnitName:='Unit1';
  1213. end;
  1214. procedure TCodeGeneratorOptions.Assign(ASource: TPersistent);
  1215. Var
  1216. CG : TCodeGeneratorOptions;
  1217. begin
  1218. If ASource is TCodeGeneratorOptions then
  1219. begin
  1220. CG:=ASource as TCodeGeneratorOptions;
  1221. FOptions:=CG.FOptions;
  1222. FUnitName:=CG.UnitName;
  1223. end
  1224. else
  1225. inherited Assign(ASource);
  1226. end;
  1227. procedure TCodeGeneratorOptions.SetUnitname(const AValue: String);
  1228. begin
  1229. if FUnitName=AValue then exit;
  1230. CheckIdentifier(AValue,False);
  1231. FUnitName:=AValue;
  1232. end;
  1233. { TClassCodeGeneratorOptions }
  1234. procedure TClassCodeGeneratorOptions.SetClassName(const AValue: String);
  1235. begin
  1236. if FClassName=AValue then
  1237. exit;
  1238. CheckIdentifier(AValue,False);
  1239. FClassName:=AValue;
  1240. end;
  1241. procedure TClassCodeGeneratorOptions.Assign(ASource: TPersistent);
  1242. Var
  1243. CO : TClassCodeGeneratorOptions;
  1244. begin
  1245. If ASource is TClassCodeGeneratorOptions then
  1246. begin
  1247. CO:=ASource as TClassCodeGeneratorOptions;
  1248. FClassName:=CO.FClassName;
  1249. FAncestorClass:=CO.FAncestorClass;
  1250. end;
  1251. inherited Assign(ASource);
  1252. end;
  1253. procedure TClassCodeGeneratorOptions.SetAncestorClass(const AValue: String);
  1254. begin
  1255. if (FAncestorClass=AValue) then
  1256. Exit;
  1257. CheckIdentifier(AValue,False);
  1258. FAncestorClass:=AValue;
  1259. end;
  1260. Finalization
  1261. DoneCodeGenerators;
  1262. end.