fpddcodegen.pp 40 KB

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