1{
2    This file is part of the Free Component Library
3
4    WEBIDL to pascal code converter
5    Copyright (c) 2018 by Michael Van Canneyt michael@freepascal.org
6
7    See the file COPYING.FPC, included in this distribution,
8    for details about the copyright.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
14 **********************************************************************}
15unit webidltopas;
16
17{$mode objfpc}{$H+}
18
19interface
20
21uses
22  Classes, SysUtils, contnrs, WebIDLParser, WebIDLScanner, WebIDLDefs, pascodegen;
23
24Type
25
26  { TWebIDLToPas }
27
28  { TPasData }
29
30  TPasData = Class(TObject)
31  private
32    FPasName: String;
33  Public
34    Constructor Create(APasName : String);
35    Property PasName : String read FPasName;
36  end;
37
38  TConversionOption = (coDictionaryAsClass,coUseNativeTypeAliases,coExternalConst,coExpandUnionTypeArgs,coaddOptionsToheader);
39  TConversionOptions = Set of TConversionOption;
40
41  TWebIDLToPas = Class(TPascalCodeGenerator)
42  private
43    FClassPrefix: String;
44    FClassSuffix: String;
45    FContext: TWebIDLContext;
46    FDictionaryClassParent: String;
47    FFieldPrefix: String;
48    FIncludeImplementationCode: TStrings;
49    FIncludeInterfaceCode: TStrings;
50    FInputFileName: String;
51    FOptions: TConversionOptions;
52    FOutputFileName: String;
53    FTypeAliases: TStrings;
54    FVerbose: Boolean;
55    FWebIDLVersion: TWebIDLVersion;
56    FPasNameList : TFPObjectList;
57    FAutoTypes : TStrings;
58    procedure SetIncludeImplementationCode(AValue: TStrings);
59    procedure SetIncludeInterfaceCode(AValue: TStrings);
60    procedure SetTypeAliases(AValue: TStrings);
61  Protected
62    procedure AddOptionsToHeader;
63    Procedure Parse; virtual;
64    Procedure WritePascal; virtual;
65    function CreateParser(aContext: TWebIDLContext; S: TWebIDLScanner): TWebIDLParser; virtual;
66    function CreateScanner(S: TStream): TWebIDLScanner;virtual;
67    Function CreateContext : TWebIDLContext; virtual;
68    Function BaseUnits : String; override;
69    // Auxiliary routines
70    procedure Getoptions(L: TStrings); virtual;
71    procedure ProcessDefinitions; virtual;
72    function CreatePasName(aName: String): TPasData;virtual;
73    procedure AllocatePasNames(aList: TIDLDefinitionList; ParentName: String='');virtual;
74    Function AllocatePasName(D: TIDLDefinition; ParentName: String='') : TPasData;virtual;
75    procedure EnsureUniqueNames(ML: TIDLDefinitionList);virtual;
76    function WriteFunctionImplicitTypes(aList: TIDLDefinitionList): Integer;virtual;
77    function WriteAttributeImplicitTypes(aList: TIDLDefinitionList): Integer;virtual;
78    function WriteDictionaryMemberImplicitTypes(aList: TIDLDefinitionList): Integer;virtual;
79    function AddSequenceDef(ST: TIDLSequenceTypeDefDefinition): Boolean; virtual;
80    function GetName(ADef: TIDLDefinition): String;virtual;
81    function GetTypeName(Const aTypeName: String; ForTypeDef: Boolean=False): String;virtual;
82    function GetTypeName(aTypeDef: TIDLTypeDefDefinition; ForTypeDef: Boolean=False): String;virtual;
83    function CheckUnionTypeDefinition(D: TIDLDefinition): TIDLUnionTypeDefDefinition;virtual;
84    procedure AddArgumentToOverloads(aList: TFPObjectlist; AName, ATypeName: String);virtual;
85    procedure AddUnionOverloads(aList: TFPObjectlist; AName: String;  UT: TIDLUnionTypeDefDefinition);virtual;
86    procedure AddArgumentToOverloads(aList: TFPObjectlist; adef: TIDLArgumentDefinition);virtual;
87    procedure AddOverloads(aList: TFPObjectlist; adef: TIDLFunctionDefinition; aIdx: Integer);virtual;
88    function CloneNonPartialArgumentList(aList: TFPObjectlist; ADest: TFPObjectlist= Nil; AsPartial: Boolean=True): integer;virtual;
89    function GetOverloads(aDef: TIDLFunctionDefinition): TFPObjectlist;virtual;
90    function GetArguments(aList: TIDLDefinitionList; ForceBrackets: Boolean): String;virtual;
91    function HaveConsts(aList: TIDLDefinitionList): Boolean;virtual;
92    // Actual code generation routines
93    // Lists. Return the number of actually written defs.
94    function WriteCallBackDefs(aList: TIDLDefinitionList): Integer; virtual;
95    Function WriteDictionaryDefs(aList: TIDLDefinitionList) : Integer;virtual;
96    Function WriteForwardClassDefs(aList: TIDLDefinitionList) : Integer;virtual;
97    Function WriteInterfaceDefs(aList: TIDLDefinitionList) : Integer;virtual;
98    Function WriteMethodDefs(aList: TIDLDefinitionList) : Integer;virtual;
99    Function WriteTypeDefs(aList: TIDLDefinitionList) : Integer;virtual;
100    Function WriteEnumDefs(aList: TIDLDefinitionList) : Integer;virtual;
101    function WriteConsts(aList: TIDLDefinitionList): Integer;virtual;
102    function WriteProperties(aList: TIDLDefinitionList): Integer;
103    function WritePlainFields(aList: TIDLDefinitionList): Integer;virtual;
104    function WriteDictionaryFields(aList: TIDLDefinitionList): Integer;virtual;
105    function WritePrivateReadOnlyFields(aList: TIDLDefinitionList): Integer;virtual;
106    // Actual definitions. Return true if a definition was written.
107    Function WriteForwardClassDef(D: TIDLStructuredDefinition) : Boolean;virtual;
108    function WriteFunctionTypeDefinition(aDef: TIDLFunctionDefinition): Boolean;virtual;
109    function WriteFunctionDefinition(aDef: TIDLFunctionDefinition): Boolean;virtual;
110    function WriteTypeDef(aDef: TIDLTypeDefDefinition): Boolean; virtual;
111    function WriteRecordDef(aDef: TIDLRecordDefinition): Boolean; virtual;
112    function WriteEnumDef(aDef: TIDLEnumDefinition): Boolean; virtual;
113    function WriteDictionaryField(aField: TIDLDictionaryMemberDefinition): Boolean;virtual;
114    Function WritePrivateReadOnlyField(aAttr: TIDLAttributeDefinition) : Boolean;virtual;
115    Function WriteField(aAttr: TIDLAttributeDefinition) : Boolean;virtual;
116    Function WriteReadonlyProperty(aAttr: TIDLAttributeDefinition) : Boolean;virtual;
117    Function WriteConst(aConst: TIDLConstDefinition) : Boolean ;virtual;
118    function WriteInterfaceDef(Intf: TIDLInterfaceDefinition): Boolean; virtual;
119    function WriteDictionaryDef(aDict: TIDLDictionaryDefinition): Boolean; virtual;
120    // Additional
121    procedure WriteAliasTypeDef(aDef: TIDLTypeDefDefinition);virtual;
122    procedure WritePromiseDef(aDef: TIDLPromiseTypeDefDefinition);virtual;
123    procedure WriteSequenceDef(aDef: TIDLSequenceTypeDefDefinition);virtual;
124    procedure WriteUnionDef(aDef: TIDLUnionTypeDefDefinition);virtual;
125    // Extra interface/Implementation code.
126    procedure WriteImplementation; virtual;
127    procedure WriteIncludeInterfaceCode; virtual;
128    Property Context : TWebIDLContext Read FContext;
129  Public
130    Constructor Create(Aowner : TComponent); override;
131    Destructor Destroy; override;
132    Procedure Execute;
133  Published
134    Property InputFileName : String Read FInputFileName Write FInputFileName;
135    Property OutputFileName : String Read FOutputFileName Write FOutputFileName;
136    Property Verbose : Boolean Read FVerbose Write FVerbose;
137    Property FieldPrefix : String Read FFieldPrefix Write FFieldPrefix;
138    Property ClassPrefix : String Read FClassPrefix Write FClassPrefix;
139    Property ClassSuffix : String Read FClassSuffix Write FClassSuffix;
140    Property Options : TConversionOptions Read FOptions Write FOptions;
141    Property WebIDLVersion : TWebIDLVersion Read FWebIDLVersion Write FWebIDLVersion;
142    Property TypeAliases : TStrings Read FTypeAliases Write SetTypeAliases;
143    Property IncludeInterfaceCode : TStrings Read FIncludeInterfaceCode Write SetIncludeInterfaceCode;
144    Property IncludeImplementationCode : TStrings Read FIncludeImplementationCode Write SetIncludeImplementationCode;
145    Property DictionaryClassParent : String Read FDictionaryClassParent Write FDictionaryClassParent;
146  end;
147
148implementation
149
150uses typinfo;
151
152{ TPasData }
153
154constructor TPasData.Create(APasName: String);
155begin
156  FPasName:=APasName;
157end;
158
159{ TWebIDLToPas }
160
161function TWebIDLToPas.CreateContext: TWebIDLContext;
162begin
163  Result:=TWebIDLContext.Create(True);
164end;
165
166function TWebIDLToPas.CreateScanner(S : TStream) :  TWebIDLScanner;
167
168begin
169  Result:=TWebIDLScanner.Create(S);
170end;
171
172function TWebIDLToPas.CreateParser(aContext : TWebIDLContext;S : TWebIDLScanner) :  TWebIDLParser;
173
174begin
175  Result:=TWebIDLParser.Create(aContext,S);
176  Result.Version:=FWebIDLVersion;
177end;
178
179procedure TWebIDLToPas.Parse;
180
181Var
182  F : TFileStream;
183  S : TWebIDLScanner;
184  P : TWebIDLParser;
185
186begin
187  P:=Nil;
188  F:=TFileStream.Create(InputFileName,fmOpenRead or fmShareDenyWrite);
189  try
190    S:=CreateScanner(F);
191    P:=CreateParser(Context,S);
192    P.Parse;
193  finally
194    P.Free;
195    S.Free;
196    F.Free;
197  end;
198end;
199
200function TWebIDLToPas.GetName(ADef: TIDLDefinition): String;
201
202begin
203  If Assigned(ADef) and (TObject(ADef.Data) is TPasData) then
204    Result:=TPasData(ADef.Data).PasName
205  else
206    Result:=ADef.Name;
207end;
208
209function TWebIDLToPas.HaveConsts(aList: TIDLDefinitionList): Boolean;
210
211Var
212  D : TIDLDefinition;
213
214begin
215  Result:=False;
216  For D in aList do
217    if D is TIDLConstDefinition then
218      Exit(True);
219end;
220
221function TWebIDLToPas.WritePrivateReadOnlyFields(aList: TIDLDefinitionList): Integer;
222
223Var
224  D : TIDLDefinition;
225  A : TIDLAttributeDefinition absolute D;
226
227begin
228  Result:=0;
229  For D in aList do
230    if (D is TIDLAttributeDefinition) then
231      if (aoReadOnly in A.Options) then
232        if WritePrivateReadOnlyField(A) then
233          Inc(Result);
234end;
235
236function TWebIDLToPas.WriteProperties(aList: TIDLDefinitionList): Integer;
237
238Var
239  D : TIDLDefinition;
240  A : TIDLAttributeDefinition absolute D;
241
242begin
243  Result:=0;
244  For D in aList do
245    if (D is TIDLAttributeDefinition) then
246      if (aoReadOnly in A.Options) then
247        if WriteReadOnlyProperty(A) then
248          Inc(Result);
249end;
250
251function TWebIDLToPas.WriteConst(aConst: TIDLConstDefinition): Boolean;
252
253Const
254  ConstTypes : Array[TConstType] of String =
255     ('Double','NativeInt','Boolean','JSValue','JSValue','JSValue','JSValue','String','JSValue','JSValue');
256Var
257  S : String;
258
259begin
260  Result:=True;
261  // Consts cannot be strings
262  if coExternalConst in Options then
263    begin
264    S:=ConstTypes[aConst.ConstType];
265    Addln('%s : %s;',[GetName(aConst),S])
266    end
267  else
268    begin
269    S:=aConst.Value;
270    if aConst.ConstType=ctInteger then
271      S:=StringReplace(S,'0x','$',[]);
272    Addln('%s = %s;',[GetName(aConst),S])
273    end;
274end;
275
276function TWebIDLToPas.WriteConsts(aList: TIDLDefinitionList): Integer;
277
278Var
279  D : TIDLDefinition;
280
281begin
282  EnsureSection(csConst);
283  Indent;
284  Result:=0;
285  For D in aList do
286    if D is TIDLConstDefinition then
287      if WriteConst(D as TIDLConstDefinition) then
288        Inc(Result);
289  Undent;
290end;
291
292function TWebIDLToPas.WritePlainFields(aList: TIDLDefinitionList): Integer;
293
294Var
295  D : TIDLDefinition;
296  A : TIDLAttributeDefinition absolute D;
297
298begin
299  EnsureSection(csDeclaration);
300  Indent;
301  Result:=0;
302  For D in aList do
303    if D is TIDLAttributeDefinition then
304      if Not (aoReadOnly in A.Options) then
305        if WriteField(A) then
306          Inc(Result);
307  Undent;
308end;
309
310function TWebIDLToPas.WriteDictionaryField(
311  aField: TIDLDictionaryMemberDefinition): Boolean;
312
313Var
314  Def,N,TN : String;
315
316begin
317  Result:=True;
318  N:=GetName(aField);
319  TN:=GetTypeName(aField.MemberType);
320  if TN='record' then
321    TN:='TJSObject';
322  if SameText(N,TN) then
323    N:='_'+N;
324  Def:=Format('%s : %s;',[N,TN]);
325  if (N<>aField.Name) then
326    Def:=Def+Format('external name ''%s'';',[aField.Name]);
327  AddLn(Def);
328end;
329
330function TWebIDLToPas.WriteDictionaryFields(aList: TIDLDefinitionList): Integer;
331
332Var
333  D : TIDLDefinition;
334  M : TIDLDictionaryMemberDefinition absolute D;
335
336begin
337  Indent;
338  Result:=0;
339  For D in aList do
340    if D is TIDLDictionaryMemberDefinition then
341      if WriteDictionaryField(M) then
342        Inc(Result);
343  Undent;
344end;
345
346function TWebIDLToPas.WriteMethodDefs(aList: TIDLDefinitionList): Integer;
347
348Var
349  D : TIDLDefinition;
350  FD : TIDLFunctionDefinition absolute D;
351
352begin
353  Result:=0;
354  for D in aList do
355    if D is TIDLFunctionDefinition then
356      if Not (foCallBack in FD.Options) then
357         if WriteFunctionDefinition(FD) then
358           Inc(Result);
359end;
360
361function TWebIDLToPas.AddSequenceDef(ST: TIDLSequenceTypeDefDefinition
362  ): Boolean;
363
364var
365  TN : String;
366begin
367  TN:=GetTypeName(ST);
368  Result:=FAutoTypes.IndexOf(TN)=-1;
369  if Result then
370    begin
371    FAutoTypes.Add(TN);
372    DoLog('Automatically adding %s sequence definition.',[TN]);
373    AddLn('%s = Array of %s;',[TN,GetTypeName(ST.ElementType)]);
374    ST.Data:=CreatePasName(TN);
375    end;
376end;
377
378function TWebIDLToPas.WriteFunctionImplicitTypes(aList: TIDLDefinitionList): Integer;
379
380Var
381  D,D2,D3 : TIDLDefinition;
382  FD : TIDLFunctionDefinition absolute D;
383  DA : TIDLArgumentDefinition absolute D2;
384  UT : TIDLUnionTypeDefDefinition;
385
386begin
387  Result:=0;
388  for D in aList do
389    if D is TIDLFunctionDefinition then
390      if Not (foCallBack in FD.Options) then
391        begin
392        if (FD.ReturnType is TIDLSequenceTypeDefDefinition) then
393          if AddSequenceDef(FD.ReturnType as TIDLSequenceTypeDefDefinition) then
394            Inc(Result);
395        For D2 in FD.Arguments do
396          if (DA.ArgumentType is TIDLSequenceTypeDefDefinition) then
397            begin
398            if AddSequenceDef(DA.ArgumentType as TIDLSequenceTypeDefDefinition) then
399              Inc(Result);
400            end
401          else
402            begin
403            UT:=CheckUnionTypeDefinition(DA.ArgumentType);
404            if Assigned(UT) then
405              For D3 in UT.Union do
406                if (D3 is TIDLSequenceTypeDefDefinition) then
407                  if AddSequenceDef(D3 as TIDLSequenceTypeDefDefinition) then
408                    Inc(Result);
409            end;
410        end;
411  if Result>0 then
412    AddLn('');
413end;
414
415function TWebIDLToPas.WriteAttributeImplicitTypes(aList: TIDLDefinitionList
416  ): Integer;
417Var
418  D : TIDLDefinition;
419  FA : TIDLAttributeDefinition absolute D;
420
421begin
422  Result:=0;
423  for D in aList do
424    if D is TIDLAttributeDefinition then
425      if (FA.AttributeType is TIDLSequenceTypeDefDefinition) then
426        if AddSequenceDef(FA.AttributeType as TIDLSequenceTypeDefDefinition) then
427          Inc(Result);
428end;
429
430function TWebIDLToPas.WriteDictionaryMemberImplicitTypes(
431  aList: TIDLDefinitionList): Integer;
432
433Var
434  D : TIDLDefinition;
435  FD : TIDLDictionaryMemberDefinition absolute D;
436
437begin
438  Result:=0;
439  for D in aList do
440    if D is TIDLDictionaryMemberDefinition then
441      if (FD.MemberType is TIDLSequenceTypeDefDefinition) then
442        if AddSequenceDef(FD.MemberType as TIDLSequenceTypeDefDefinition) then
443          Inc(Result);
444end;
445
446procedure TWebIDLToPas.EnsureUniqueNames(ML : TIDLDefinitionList);
447
448Var
449  L : TFPObjectHashTable;
450
451  Procedure CheckRename(aD : TIDLDefinition);
452
453  var
454    I : integer;
455    NOrig,N,N2 : String;
456    isDup : Boolean;
457    D2 : TIDLDefinition;
458
459  begin
460    NOrig:=GetName(aD);
461    N:=LowerCase(NOrig);
462    N2:=N;
463    I:=0;
464    isDup:=False;
465    Repeat
466      D2:=TIDLDefinition(L.Items[N2]);
467      if (D2<>Nil) then
468        // Overloads
469        begin
470        isDup:=((D2 is TIDLFunctionDefinition) and (ad is TIDLFunctionDefinition));
471        if IsDup then
472          D2:=Nil
473        else
474          begin
475          inc(I);
476          N2:=KeywordPrefix+N+KeywordSuffix;
477          Norig:=KeywordPrefix+NOrig+KeywordSuffix;
478          end;
479        end;
480    Until (D2=Nil);
481    if (N<>N2) then
482      begin
483      N:=GetName(aD);
484      DoLog('Renaming duplicate identifier (%s) %s to %s',[aD.ClassName,N,Norig]);
485      // Original TPasName is in list, will be freed automatically
486      aD.Data:=CreatePasName(NOrig);
487      end;
488    if not IsDup then
489      L.Add(N2,aD);
490  end;
491
492var
493  D : TIDLDefinition;
494
495begin
496  L:=TFPObjectHashTable.Create(False);
497  try
498    For D in ML Do
499      if not (D is TIDLConstDefinition) then
500        CheckRename(D);
501    For D in ML Do
502      if (D is TIDLConstDefinition) then
503        CheckRename(D);
504  finally
505    L.Free;
506  end;
507end;
508
509function TWebIDLToPas.WriteInterfaceDef(Intf: TIDLInterfaceDefinition): Boolean;
510
511Var
512  CN,PN : String;
513  Decl : String;
514  ML : TIDLDefinitionList;
515
516begin
517  Result:=True;
518  ML:=TIDLDefinitionList.Create(Nil,False);
519  try
520    Intf.GetFullMemberList(ML);
521    EnsureUniqueNames(ML);
522    CN:=GetName(Intf);
523    ClassHeader(CN);
524    WriteFunctionImplicitTypes(ML);
525    WriteAttributeImplicitTypes(ML);
526    Decl:=Format('%s = class external name %s ',[CN,MakePascalString(Intf.Name,True)]);
527    if Assigned(Intf.ParentInterface) then
528      PN:=GetName(Intf.ParentInterface)
529    else
530      PN:=GetTypeName(Intf.ParentName);
531    if PN<>'' then
532      Decl:=Decl+Format(' (%s)',[PN]);
533    AddLn(Decl);
534    AddLn('Private');
535    Indent;
536    WritePrivateReadOnlyFields(ML);
537    Undent;
538    AddLn('Public');
539    if HaveConsts(ML) then
540      begin
541      Indent;
542      PushSection(csUnknown);
543      WriteConsts(ML);
544      PopSection;
545      Undent;
546      AddLn('Public');
547      end;
548    Indent;
549    WritePlainFields(ML);
550    WriteMethodDefs(ML);
551    WriteProperties(ML);
552    Undent;
553    AddLn('end;');
554  finally
555    ML.Free;
556  end;
557end;
558
559function TWebIDLToPas.WriteDictionaryDef(aDict: TIDLDictionaryDefinition
560  ): Boolean;
561
562Var
563  CN,CP : String;
564  ML : TIDLDefinitionList;
565  PD: TIDLDictionaryDefinition;
566
567begin
568  Result:=True;
569  ML:=TIDLDefinitionList.Create(Nil,False);
570  try
571    PD:=aDict;
572    While PD<>Nil do
573      begin
574      PD.GetFullMemberList(ML);
575      PD:=PD.ParentDictionary;
576      end;
577    CN:=GetName(aDict);
578    CP:=DictionaryClassParent;
579    if CP='' then
580      CP:='TJSObject';
581    ClassHeader(CN);
582    WriteDictionaryMemberImplicitTypes(ML);
583    if (coDictionaryAsClass in Options) then
584      Addln('%s = class(%s)',[CN,CP])
585    else
586      Addln('%s = record',[CN]);
587    WriteDictionaryFields(ML);
588    AddLn('end;');
589  finally
590    ML.Free;
591  end;
592end;
593
594constructor TWebIDLToPas.Create(Aowner: TComponent);
595begin
596  inherited Create(Aowner);
597  WebIDLVersion:=v2;
598  FieldPrefix:='F';
599  ClassPrefix:='T';
600  ClassSuffix:='';
601  Switches.Add('modeswitch externalclass');
602  FTypeAliases:=TStringList.Create;
603  FPasNameList:=TFPObjectList.Create(True);
604  FAutoTypes:=TStringList.Create;
605  FIncludeInterfaceCode:=TStringList.Create;
606  FIncludeImplementationCode:=TStringList.Create;
607end;
608
609
610destructor TWebIDLToPas.Destroy;
611begin
612  FreeAndNil(FIncludeInterfaceCode);
613  FreeAndNil(FIncludeImplementationCode);
614  FreeAndNil(FAutoTypes);
615  FreeAndNil(FTypeAliases);
616  FreeAndNil(FPasNameList);
617  inherited Destroy;
618end;
619
620procedure TWebIDLToPas.WriteImplementation;
621
622Var
623  S : String;
624
625begin
626  Addln('');
627  For S in FIncludeImplementationCode do
628    Addln(S);
629  Addln('');
630end;
631
632function TWebIDLToPas.GetTypeName(aTypeDef : TIDLTypeDefDefinition; ForTypeDef : Boolean = False): String;
633
634begin
635  if ATypeDef is TIDLSequenceTypeDefDefinition then
636    begin
637    if Assigned(aTypeDef.Data) then
638      Result:=GetName(aTypeDef)
639    else
640      begin
641      Result:=GetTypeName(TIDLSequenceTypeDefDefinition(aTypeDef).ElementType,ForTypeDef);
642      Result:='T'+Result+'DynArray';
643      end
644    end
645  else
646    Result:=GetTypeName(aTypeDef.TypeName,ForTypeDef);
647end;
648
649function TWebIDLToPas.GetTypeName(const aTypeName: String; ForTypeDef: Boolean
650  ): String;
651
652
653  Function UsePascalType(Const aPascalType : string) : String;
654
655  begin
656    if (coUseNativeTypeAliases in Options) and ForTypeDef then
657      Result:=StringReplace(aTypeName,' ','',[rfReplaceAll])
658    else
659      Result:=aPascalType;
660  end;
661
662Var
663  A,TN : UTF8String;
664  D : TIDLDefinition;
665
666begin
667  Case aTypeName of
668    'union': TN:='JSValue';
669    'short': TN:=UsePascalType('Integer');
670    'long': TN:=UsePascalType('Integer');
671    'long long': TN:=UsePascalType('NativeInt');
672    'unsigned short': TN:=UsePascalType('Cardinal');
673    'unrestricted float': TN:=UsePascalType('Double');
674    'unrestricted double': TN:=UsePascalType('Double');
675    'unsigned long': TN:=UsePascalType('NativeInt');
676    'unsigned long long': TN:=UsePascalType('NativeInt');
677    'octet': TN:=UsePascalType('Byte');
678    'any' : TN:=UsePascalType('JSValue');
679    'float' : TN:=UsePascalType('Double');
680    'double' : TN:=UsePascalType('Double');
681    'DOMString',
682    'USVString',
683    'ByteString' : TN:=UsePascalType('String');
684    'object' : TN:=UsePascalType('TJSObject');
685    'Error' : TN:=UsePascalType('TJSError');
686    'DOMException' : TN:=UsePascalType('TJSError');
687    'ArrayBuffer',
688    'DataView',
689    'Int8Array',
690    'Int16Array',
691    'Int32Array',
692    'Uint8Array',
693    'Uint16Array',
694    'Uint32Array',
695    'Uint8ClampedArray',
696    'Float32Array',
697    'Float64Array' : TN:='TJS'+aTypeName;
698  else
699    TN:=aTypeName;
700    D:=FContext.FindDefinition(TN);
701    if D<>Nil then
702      TN:=GetName(D)
703    else
704      begin
705      A:=FTypeAliases.Values[TN];
706      If (A<>'') then
707        TN:=A;
708      end;
709  end;
710  Result:=TN;
711end;
712
713function TWebIDLToPas.WritePrivateReadOnlyField(aAttr: TIDLAttributeDefinition
714  ): Boolean;
715
716begin
717  AddLn('%s%s : %s; external name ''%s''; ',[FieldPrefix,GetName(aAttr),GetTypeName(aAttr.AttributeType),aAttr.Name]);
718end;
719
720function TWebIDLToPas.WriteField(aAttr: TIDLAttributeDefinition): Boolean;
721
722Var
723  Def,TN,N : String;
724
725begin
726  Result:=True;
727  N:=GetName(aAttr);
728  TN:=GetTypeName(aAttr.AttributeType);
729  if TN='record' then
730    TN:='TJSObject';
731  if SameText(N,TN) then
732    N:='_'+N;
733  Def:=Format('%s : %s;',[N,TN]);
734  if (N<>aAttr.Name) then
735    Def:=Def+Format('external name ''%s'';',[aAttr.Name]);
736  AddLn(Def);
737end;
738
739function TWebIDLToPas.WriteReadonlyProperty(aAttr: TIDLAttributeDefinition
740  ): Boolean;
741
742Var
743  TN,N,PN : String;
744
745begin
746  Result:=True;
747  N:=GetName(aAttr);
748  PN:=N;
749  TN:=GetTypeName(aAttr.AttributeType);
750  if SameText(PN,TN) then
751    PN:='_'+PN;
752  AddLn('Property %s : %s Read %s%s; ',[PN,TN,FieldPrefix,N]);
753end;
754
755
756function TWebIDLToPas.WriteForwardClassDef(D: TIDLStructuredDefinition): Boolean;
757
758begin
759  Result:=not D.IsPartial;
760  if Result then
761    AddLn('%s = Class;',[GetName(D)]);
762end;
763
764function TWebIDLToPas.WriteForwardClassDefs(aList: TIDLDefinitionList): Integer;
765
766Var
767  D : TIDLDefinition;
768
769begin
770  Result:=0;
771  Comment('Forward class definitions');
772  For D in aList do
773    if D is TIDLInterfaceDefinition then
774      if WriteForwardClassDef(D as TIDLInterfaceDefinition) then
775        Inc(Result);
776  if coDictionaryAsClass in Options then
777    For D in aList do
778      if D is TIDLDictionaryDefinition then
779        if WriteForwardClassDef(D as TIDLDictionaryDefinition) then
780          Inc(Result);
781end;
782
783procedure TWebIDLToPas.WriteSequenceDef(aDef : TIDLSequenceTypeDefDefinition);
784
785begin
786  Addln('%s = array of %s;',[GetName(aDef),GetTypeName(aDef.ElementType)])
787end;
788
789
790procedure TWebIDLToPas.WriteUnionDef(aDef : TIDLUnionTypeDefDefinition);
791
792Var
793  S : UTF8String;
794  D : TIDLDefinition;
795begin
796  S:='';
797  For D in adef.Union do
798    begin
799    if (S<>'') then
800      S:=S+', ';
801    S:=S+(D as TIDLTypeDefDefinition).TypeName;
802    end;
803  Comment('Union of '+S);
804  AddLn('%s = JSValue; ',[GetName(aDef)])
805end;
806
807
808procedure TWebIDLToPas.WritePromiseDef(aDef : TIDLPromiseTypeDefDefinition);
809
810begin
811  AddLn('%s = TJSPromise;',[GetName(aDef)]);
812end;
813
814procedure TWebIDLToPas.WriteAliasTypeDef(aDef : TIDLTypeDefDefinition);
815
816Var
817  TN : String;
818
819begin
820  TN:=GetTypeName(aDef,True);
821  AddLn('%s = %s;',[GetName(aDef),TN]);
822end;
823
824function TWebIDLToPas.WriteTypeDef(aDef: TIDLTypeDefDefinition): Boolean;
825
826begin
827  Result:=True;
828  if ADef is TIDLSequenceTypeDefDefinition then
829    WriteSequenceDef(aDef as TIDLSequenceTypeDefDefinition)
830  else if ADef is TIDLUnionTypeDefDefinition then
831    WriteUnionDef(aDef as TIDLUnionTypeDefDefinition)
832  else if ADef is TIDLPromiseTypeDefDefinition then
833    WritePromiseDef(aDef as TIDLPromiseTypeDefDefinition)
834  else if ADef is TIDLRecordDefinition then
835    WriteRecordDef(aDef as TIDLRecordDefinition)
836  else
837    WriteAliasTypeDef(aDef);
838end;
839
840function TWebIDLToPas.WriteRecordDef(aDef: TIDLRecordDefinition): Boolean;
841
842Var
843  KT,VT : String;
844
845begin
846  Result:=True;
847  KT:=GetTypeName(aDef.KeyType);
848  VT:=GetTypeName(aDef.ValueType);
849  AddLn('%s = Class(TJSObject)',[GetName(aDef)]);
850  AddLn('private');
851  Indent;
852  AddLn('function GetValue(aKey: %s): %s; external name ''[]'';',[KT,VT]);
853  AddLn('procedure SetValue(aKey: %s; const AValue: %s); external name ''[]'';',[KT,VT]);
854  undent;
855  AddLn('public');
856  Indent;
857  AddLn('property Values[Name: %s]: %s read GetProperties write SetProperties; default;',[KT,VT]);
858  undent;
859  AddLn('end;');
860end;
861
862function TWebIDLToPas.WriteTypeDefs(aList: TIDLDefinitionList): Integer;
863
864Var
865  D : TIDLDefinition;
866  TD : TIDLTypeDefDefinition absolute D;
867
868begin
869  Result:=0;
870  EnsureSection(csType);
871  for D in aList do
872    if D is TIDLTypeDefDefinition then
873      if WriteTypeDef(TD) then
874        Inc(Result);
875end;
876
877function TWebIDLToPas.WriteEnumDef(aDef: TIDLEnumDefinition): Boolean;
878
879begin
880  Result:=True;
881  AddLn('%s = String;',[GetName(aDef)]);
882end;
883
884function TWebIDLToPas.WriteEnumDefs(aList: TIDLDefinitionList): Integer;
885
886Var
887  D : TIDLDefinition;
888  ED : TIDLEnumDefinition absolute D;
889
890begin
891  Result:=0;
892  EnsureSection(csType);
893  for D in aList do
894    if D is TIDLEnumDefinition then
895      if WriteEnumDef(ED) then
896        Inc(Result);
897end;
898
899function TWebIDLToPas.GetArguments(aList: TIDLDefinitionList;
900  ForceBrackets: Boolean): String;
901
902Var
903  I : TIDLDefinition;
904  A : TIDLArgumentDefinition absolute I;
905  Arg : string;
906
907begin
908  Result:='';
909  For I in aList do
910    begin
911    Arg:=GetName(A);
912    Arg:=Arg+' : '+GetTypeName(A.ArgumentType);
913    if Result<>'' then
914      Result:=Result+'; ';
915    Result:=Result+Arg;
916    end;
917  if (Result<>'') or ForceBrackets then
918    Result:='('+Result+')';
919end;
920
921Type
922  // A partial argument list is a list which has been generated for a optional argument.
923  // Additional arguments can never be added to a partial list...
924  TIDLPartialDefinitionList = Class(TIDLDefinitionList);
925
926function TWebIDLToPas.CloneNonPartialArgumentList(aList: TFPObjectlist;
927  ADest: TFPObjectlist; AsPartial: Boolean): integer;
928
929Var
930  I,J : Integer;
931  CD : TIDLDefinition;
932  DL,CL : TIDLDefinitionList;
933
934begin
935  Result:=0;
936  if ADest=Nil then
937    ADest:=aList;
938  I:=aList.Count-1;
939  While (I>=0) do
940    begin
941    DL:=TIDLDefinitionList(alist[i]);
942    if Not (DL is TIDLPartialDefinitionList) then
943      begin
944      Inc(Result);
945      if AsPartial then
946        CL:=TIDLPartialDefinitionList.Create(Nil,True)
947      else
948        CL:=TIDLDefinitionList.Create(Nil,True);
949      aDest.Add(CL);
950      For J:=0 to DL.Count-1 do
951        begin
952        CD:=(DL.Definitions[J] as TIDLArgumentDefinition).Clone(Nil);
953        CL.Add(CD);
954        AllocatePasName(CD);
955        end;
956      end;
957    Dec(I);
958    end;
959end;
960
961procedure TWebIDLToPas.AddArgumentToOverloads(aList: TFPObjectlist; AName,ATypeName : String);
962
963Var
964  I : Integer;
965  CD : TIDLArgumentDefinition;
966  DL : TIDLDefinitionList;
967
968begin
969  For I:=0 to aList.Count-1 do
970    begin
971    DL:=TIDLDefinitionList(alist[i]);
972    if Not (DL is TIDLPartialDefinitionList) then
973      begin
974      CD:=TIDLArgumentDefinition.Create(Nil,aName);
975      CD.ArgumentType:=TIDLTypeDefDefinition.Create(CD,'');
976      CD.ArgumentType.TypeName:=aTypeName;
977      DL.Add(CD);
978      AllocatePasName(cd,'');
979      end;
980    end;
981end;
982
983procedure TWebIDLToPas.AddArgumentToOverloads(aList: TFPObjectlist; adef: TIDLArgumentDefinition);
984
985Var
986  I : Integer;
987  CD : TIDLDefinition;
988  DL : TIDLDefinitionList;
989
990begin
991  For I:=0 to aList.Count-1 do
992    begin
993    DL:=TIDLDefinitionList(alist[i]);
994    if Not (DL is TIDLPartialDefinitionList) then
995      begin
996      CD:=aDef.Clone(Nil);
997      DL.Add(CD);
998      if aDef.Data<>Nil then
999        CD.Data:=CreatePasName(TPasData(aDef.Data).PasName)
1000      else
1001        AllocatePasName(cd,'');
1002      end;
1003    end;
1004end;
1005
1006procedure TWebIDLToPas.AddUnionOverloads(aList: TFPObjectlist; AName : String; UT : TIDLUnionTypeDefDefinition);
1007
1008Var
1009  L,L2 : TFPObjectList;
1010  I,J : Integer;
1011  D : TIDLDefinitionList;
1012  Dups : TStringList;
1013
1014begin
1015  L2:=Nil;
1016  Dups:=TStringList.Create;
1017  Dups.Sorted:=True;
1018  Dups.Duplicates:=dupIgnore;
1019  L:=TFPObjectList.Create(False);
1020  try
1021    L2:=TFPObjectList.Create(False);
1022    // Collect non partial argument lists
1023    for I:=0 to AList.Count-1 do
1024      begin
1025      D:=TIDLDefinitionList(alist[i]);
1026      if Not (D is TIDLPartialDefinitionList) then
1027        L.Add(D);
1028      end;
1029    // Collect unique pascal types. Note that this can reduce the list to 1 element...
1030    For I:=0 to UT.Union.Count-1 do
1031      Dups.AddObject(GetTypeName(UT.Union[I] as TIDLTypeDefDefinition),UT.Union[I]);
1032    // First, clone list and add argument to cloned lists
1033    For I:=1 to Dups.Count-1 do
1034      begin
1035      // Clone list
1036      CloneNonPartialArgumentList(L,L2,False);
1037      // Add argument to cloned list
1038      AddArgumentToOverloads(L2,aName,Dups[i]);
1039      // Add overloads to original list
1040      For J:=0 to L2.Count-1 do
1041        aList.Add(L2[J]);
1042      L2.Clear;
1043      end;
1044    // Add first Union to original list
1045    AddArgumentToOverloads(L,aName,Dups[0]);
1046  finally
1047    Dups.Free;
1048    L2.Free;
1049    L.Free;
1050  end;
1051end;
1052
1053function TWebIDLToPas.CheckUnionTypeDefinition(D: TIDLDefinition
1054  ): TIDLUnionTypeDefDefinition;
1055
1056begin
1057  Result:=Nil;
1058  If (D is TIDLUnionTypeDefDefinition) then
1059    Result:=D as TIDLUnionTypeDefDefinition
1060  else
1061    begin
1062    D:=Context.FindDefinition((D as TIDLTypeDefDefinition).TypeName);
1063    if (D is TIDLUnionTypeDefDefinition) then
1064      Result:=D as TIDLUnionTypeDefDefinition
1065    end
1066end;
1067
1068procedure TWebIDLToPas.AddOverloads(aList: TFPObjectlist;
1069  adef: TIDLFunctionDefinition; aIdx: Integer);
1070
1071Var
1072  Arg : TIDLArgumentDefinition;
1073  D : TIDLDefinition;
1074  UT : TIDLUnionTypeDefDefinition;
1075
1076begin
1077 if aIdx>=ADef.Arguments.Count then
1078    exit;
1079  Arg:=ADef.Argument[aIdx];
1080  if Arg.IsOptional then
1081    CloneNonPartialArgumentList(aList);
1082  // Add current to list.
1083  D:=Arg.ArgumentType;
1084  UT:=Nil;
1085  if coExpandUnionTypeArgs in Options then
1086    UT:=CheckUnionTypeDefinition(D);
1087  if UT=Nil then
1088    AddArgumentToOverloads(aList,Arg)
1089  else
1090    AddUnionOverLoads(aList,Arg.Name,UT);
1091  AddOverloads(aList,aDef,aIdx+1);
1092end;
1093
1094function TWebIDLToPas.GetOverloads(aDef: TIDLFunctionDefinition): TFPObjectlist;
1095
1096begin
1097  Result:=TFPObjectList.Create;
1098  try
1099    Result.Add(TIDLDefinitionList.Create(Nil,True));
1100    AddOverloads(Result,adef,0);
1101  except
1102    Result.Free;
1103    Raise;
1104  end;
1105end;
1106
1107function TWebIDLToPas.WriteFunctionTypeDefinition(aDef: TIDLFunctionDefinition): Boolean;
1108
1109Var
1110  FN,RT,Args : String;
1111
1112begin
1113  Result:=True;
1114  FN:=GetName(aDef);
1115  RT:=GetTypeName(aDef.ReturnType,False);
1116  if (RT='void') then
1117    RT:='';
1118  Args:=GetArguments(aDef.Arguments,False);
1119  if (RT='') then
1120    AddLn('%s = Procedure %s;',[FN,Args])
1121  else
1122    AddLn('%s = function %s: %s;',[FN,Args,RT])
1123end;
1124
1125function TWebIDLToPas.WriteFunctionDefinition(aDef: TIDLFunctionDefinition): Boolean;
1126
1127Var
1128  FN,RT,Suff,Args : String;
1129  Overloads : TFPObjectList;
1130  I : Integer;
1131
1132begin
1133  Result:=True;
1134  if not (foConstructor in aDef.Options) then
1135    begin
1136    FN:=GetName(aDef);
1137    if FN<>aDef.Name then
1138      Suff:=Format('; external name ''%s''',[aDef.Name]);
1139    RT:=GetTypeName(aDef.ReturnType,False);
1140    if (RT='void') then
1141      RT:='';
1142    end
1143  else
1144    FN:='New';
1145  Overloads:=GetOverloads(ADef);
1146  try
1147    for I:=0 to aDef.Arguments.Count-1 do
1148      if aDef.Argument[i].HasEllipsis then
1149        Suff:='; varargs';
1150    if Overloads.Count>1 then
1151      Suff:=Suff+'; overload';
1152    For I:=0 to Overloads.Count-1 do
1153      begin
1154      Args:=GetArguments(TIDLDefinitionList(Overloads[i]),False);
1155      if (RT='') then
1156        begin
1157        if not (foConstructor in aDef.Options) then
1158          AddLn('Procedure %s%s%s;',[FN,Args,Suff])
1159        else
1160          AddLn('constructor %s%s%s;',[FN,Args,Suff]);
1161        end
1162      else
1163        AddLn('function %s%s: %s%s;',[FN,Args,RT,Suff])
1164      end;
1165  finally
1166    Overloads.Free;
1167  end;
1168end;
1169
1170function TWebIDLToPas.WriteCallBackDefs(aList: TIDLDefinitionList): Integer;
1171
1172Var
1173  D : TIDLDefinition;
1174  FD : TIDLFunctionDefinition absolute D;
1175
1176begin
1177  Result:=0;
1178  EnsureSection(csType);
1179  for D in aList do
1180    if D is TIDLFunctionDefinition then
1181      if (foCallBack in FD.Options) then
1182         if WriteFunctionTypeDefinition(FD) then
1183           Inc(Result);
1184end;
1185
1186function TWebIDLToPas.WriteDictionaryDefs(aList: TIDLDefinitionList): Integer;
1187
1188Var
1189  D : TIDLDefinition;
1190  DD : TIDLDictionaryDefinition absolute D;
1191
1192begin
1193  Result:=0;
1194  EnsureSection(csType);
1195  for D in aList do
1196    if D is TIDLDictionaryDefinition then
1197      if not TIDLDictionaryDefinition(D).IsPartial then
1198        if WriteDictionaryDef(DD) then
1199          Inc(Result);
1200end;
1201
1202function TWebIDLToPas.WriteInterfaceDefs(aList: TIDLDefinitionList): Integer;
1203
1204Var
1205  D : TIDLDefinition;
1206  ID : TIDLInterfaceDefinition absolute D;
1207
1208begin
1209  Result:=0;
1210  EnsureSection(csType);
1211  for D in aList do
1212    if D is TIDLInterfaceDefinition then
1213      if not TIDLInterfaceDefinition(D).IsPartial then
1214        if WriteInterfaceDef(ID) then
1215          Inc(Result);
1216end;
1217
1218procedure TWebIDLToPas.Getoptions(L : TStrings);
1219
1220Var
1221  S : String;
1222  I : Integer;
1223
1224begin
1225  L.Add('Automatically generated file by '+ClassName+' on '+FormatDateTime('yyyy-mm-dd hh:nn:ss',Now));
1226  L.Add('');
1227  L.Add('Used command-line options : ');
1228  For I:=1 to ParamCount do
1229    L.Add(ParamStr(i));
1230  L.Add('');
1231  L.Add('Command-line options translate to: ');
1232  L.Add('');
1233  S:=SetToString(PtypeInfo(TypeInfo(TConversionOptions)),Integer(OPtions),True);
1234  L.Add('Options : '+S);
1235  L.Add('Keyword prefix : '+KeywordPrefix);
1236  L.Add('Keyword suffix : '+KeywordSuffix);
1237  L.Add('Class prefix : '+ClassPrefix);
1238  L.Add('Class suffix : '+ClassSuffix);
1239  L.Add('Field prefix : '+FieldPrefix);
1240  Str(WebIDLversion,S);
1241  L.Add('WEBIDLversion : '+S);
1242  if TypeAliases.Count>0 then
1243    begin
1244    L.Add('Type aliases:');
1245    L.AddStrings(Self.TypeAliases);
1246    end;
1247end;
1248
1249procedure TWebIDLToPas.AddOptionsToHeader;
1250
1251Var
1252  L : TStrings;
1253begin
1254  L:=TStringList.Create;
1255  try
1256    GetOptions(L);
1257    Comment(L);
1258  finally
1259    L.Free;
1260  end;
1261end;
1262
1263procedure TWebIDLToPas.WriteIncludeInterfaceCode;
1264
1265Var
1266  S : String;
1267
1268begin
1269  For S in IncludeInterfaceCode do
1270    Addln(S);
1271end;
1272
1273procedure TWebIDLToPas.WritePascal;
1274
1275begin
1276  CreateUnitClause;
1277  CreateHeader;
1278  if coaddOptionsToheader in Options then
1279    AddOptionsToHeader;
1280  EnsureSection(csType);
1281  Indent;
1282  WriteForwardClassDefs(Context.Definitions);
1283  WriteEnumDefs(Context.Definitions);
1284  WriteTypeDefs(Context.Definitions);
1285  WriteCallbackDefs(Context.Definitions);
1286  WriteDictionaryDefs(Context.Definitions);
1287  WriteInterfaceDefs(Context.Definitions);
1288  Undent;
1289  WriteIncludeInterfaceCode;
1290  Addln('');
1291  AddLn('implementation');
1292  WriteImplementation;
1293  AddLn('end.');
1294  Source.SaveToFile(OutputFileName);
1295end;
1296
1297function TWebIDLToPas.BaseUnits: String;
1298
1299begin
1300  Result:='SysUtils, JS'
1301end;
1302
1303function TWebIDLToPas.CreatePasName(aName: String): TPasData;
1304
1305begin
1306  Result:=TPasData.Create(EscapeKeyWord(aName));
1307  FPasNameList.Add(Result);
1308end;
1309
1310function TWebIDLToPas.AllocatePasName(D: TIDLDefinition; ParentName: String): TPasData;
1311
1312Var
1313  CN : String;
1314
1315begin
1316  if D Is TIDLInterfaceDefinition then
1317    begin
1318    CN:=ClassPrefix+D.Name+ClassSuffix;
1319    Result:=CreatePasname(CN);
1320    D.Data:=Result;
1321    AllocatePasNames((D as TIDLInterfaceDefinition).members,D.Name);
1322    end
1323  else if D Is TIDLDictionaryDefinition then
1324    begin
1325    CN:=D.Name;
1326    if coDictionaryAsClass in Options then
1327      CN:=ClassPrefix+CN+ClassSuffix;
1328    Result:=CreatePasname(EscapeKeyWord(CN));
1329    D.Data:=Result;
1330    AllocatePasNames((D as TIDLDictionaryDefinition).members,D.Name);
1331    end
1332  else
1333    begin
1334    Result:=CreatePasName(D.Name);
1335    D.Data:=Result;
1336    if D Is TIDLFunctionDefinition then
1337      AllocatePasNames((D as TIDLFunctionDefinition).Arguments,D.Name);
1338    end;
1339  if Verbose and (TPasData(D.Data).PasName<>D.Name) then
1340    begin
1341    if (ParentName<>'') then
1342      ParentName:=ParentName+'.';
1343    DoLog('Renamed %s to %s',[ParentName+D.Name,TPasData(D.Data).PasName]);
1344    end;
1345end;
1346
1347procedure TWebIDLToPas.SetTypeAliases(AValue: TStrings);
1348begin
1349  if FTypeAliases=AValue then Exit;
1350  FTypeAliases.Assign(AValue);
1351end;
1352
1353procedure TWebIDLToPas.SetIncludeInterfaceCode(AValue: TStrings);
1354begin
1355  if FIncludeInterfaceCode=AValue then Exit;
1356  FIncludeInterfaceCode.Assign(AValue);
1357end;
1358
1359procedure TWebIDLToPas.SetIncludeImplementationCode(AValue: TStrings);
1360begin
1361  if FIncludeImplementationCode=AValue then Exit;
1362  FIncludeImplementationCode.Assign(AValue);
1363end;
1364
1365procedure TWebIDLToPas.AllocatePasNames(aList : TIDLDefinitionList; ParentName: String = '');
1366
1367var
1368  D : TIDLDefinition;
1369
1370begin
1371  For D in aList do
1372    AllocatePasName(D,ParentName);
1373end;
1374
1375
1376procedure TWebIDLToPas.ProcessDefinitions;
1377
1378begin
1379  FContext.AppendPartials;
1380  FContext.AppendIncludes;
1381  AllocatePasNames(FContext.Definitions);
1382end;
1383
1384procedure TWebIDLToPas.Execute;
1385
1386begin
1387  FContext:=CreateContext;
1388  try
1389    FContext.Aliases:=Self.TypeAliases;
1390    Parse;
1391    if Verbose then
1392      DoLog('Parsed %d definitions.',[Context.Definitions.Count]);
1393    ProcessDefinitions;
1394    WritePascal;
1395  finally
1396    FreeAndNil(FContext);
1397  end;
1398end;
1399
1400end.
1401
1402