* ppudump: Work in progress on JSON output.

git-svn-id: trunk@24311 -
This commit is contained in:
yury 2013-04-23 15:16:34 +00:00
parent 307454e3a6
commit 61ac7580b7
3 changed files with 258 additions and 130 deletions

View File

@ -619,13 +619,13 @@ begin
writeln; writeln;
end; end;
procedure readdefinitions(const s:string); forward; procedure readdefinitions(const s:string; ParentDef: TPpuContainerDef); forward;
procedure readsymbols(const s:string); forward; procedure readsymbols(const s:string); forward;
procedure readsymtable(const s: string); procedure readsymtable(const s: string; ParentDef: TPpuContainerDef = nil);
begin begin
readsymtableoptions(s); readsymtableoptions(s);
readdefinitions(s); readdefinitions(s, ParentDef);
readsymbols(s); readsymbols(s);
end; end;
@ -704,14 +704,16 @@ end;
Procedure ReadDerefmap; Procedure ReadDerefmap;
var var
i,mapsize : longint; i,mapsize : longint;
s: string;
begin begin
mapsize:=ppufile.getlongint; mapsize:=ppufile.getlongint;
writeln(['DerefMapsize: ',mapsize]); writeln(['DerefMapsize: ',mapsize]);
SetLength(CurUnit.RefUnits, mapsize); SetLength(CurUnit.RefUnits, mapsize);
for i:=0 to mapsize-1 do for i:=0 to mapsize-1 do
begin begin
CurUnit.RefUnits[i]:=ppufile.getstring; s:=ppufile.getstring;
writeln(['DerefMap[',i,'] = ',CurUnit.RefUnits[i]]); writeln(['DerefMap[',i,'] = ',s]);
CurUnit.RefUnits[i]:=LowerCase(s);
end; end;
end; end;
@ -858,7 +860,7 @@ begin
getexprint.svalue:=ppufile.getint64; getexprint.svalue:=ppufile.getint64;
end; end;
Procedure ReadPosInfo; Procedure ReadPosInfo(Def: TPpuDef = nil);
var var
info : byte; info : byte;
fileindex,line,column : longint; fileindex,line,column : longint;
@ -891,11 +893,17 @@ begin
3 : column:=getlongint; 3 : column:=getlongint;
end; end;
Writeln([fileindex,' (',line,',',column,')']); Writeln([fileindex,' (',line,',',column,')']);
if Def <> nil then
begin
Def.FilePos.FileIndex:=fileindex - 1;
Def.FilePos.Line:=line;
Def.FilePos.Col:=column;
end;
end; end;
end; end;
procedure readderef(const derefspace: string); procedure readderef(const derefspace: string; Ref: TPpuRef = nil);
var var
b : tdereftype; b : tdereftype;
first : boolean; first : boolean;
@ -945,12 +953,16 @@ begin
idx:=pdata[i] shl 24 or pdata[i+1] shl 16 or pdata[i+2] shl 8 or pdata[i+3]; idx:=pdata[i] shl 24 or pdata[i+1] shl 16 or pdata[i+2] shl 8 or pdata[i+3];
inc(i,4); inc(i,4);
write(['DefId ',idx]); write(['DefId ',idx]);
if Ref <> nil then
Ref.Id:=idx;
end; end;
deref_unit : deref_unit :
begin begin
idx:=pdata[i] shl 8 or pdata[i+1]; idx:=pdata[i] shl 8 or pdata[i+1];
inc(i,2); inc(i,2);
write(['Unit ',idx]); write(['Unit ',idx]);
if Ref <> nil then
Ref.UnitIndex:=idx;
end; end;
else else
begin begin
@ -1220,7 +1232,7 @@ begin
end; end;
procedure readcommonsym(const s:string); procedure readcommonsym(const s:string; Def: TPpuDef = nil);
begin begin
writeln([space,'** Symbol Id ',ppufile.getlongint,' **']); writeln([space,'** Symbol Id ',ppufile.getlongint,' **']);
writeln([space,s,ppufile.getstring]); writeln([space,s,ppufile.getstring]);
@ -1238,7 +1250,7 @@ var
current_defoptions : tdefoptions; current_defoptions : tdefoptions;
current_objectoptions : tobjectoptions; current_objectoptions : tobjectoptions;
procedure readcommondef(const s:string; out defoptions: tdefoptions); procedure readcommondef(const s:string; out defoptions: tdefoptions; Def: TPpuDef = nil);
type type
tdefopt=record tdefopt=record
mask : tdefoption; mask : tdefoption;
@ -1359,7 +1371,10 @@ var
end; end;
begin begin
writeln([space,'** Definition Id ',ppufile.getlongint,' **']); i:=ppufile.getlongint;
if Def <> nil then
Def.Id:=i;
writeln([space,'** Definition Id ',i,' **']);
writeln([space,s]); writeln([space,s]);
write ([space,' Type symbol : ']); write ([space,' Type symbol : ']);
readderef(''); readderef('');
@ -1530,7 +1545,7 @@ end;
{ type tproctypeoption is in globtype unit } { type tproctypeoption is in globtype unit }
{ type tprocoption is in globtype unit } { type tprocoption is in globtype unit }
procedure read_abstract_proc_def(var proccalloption:tproccalloption;var procoptions:tprocoptions); procedure read_abstract_proc_def(var proccalloption:tproccalloption;var procoptions:tprocoptions; ProcDef: TPpuProcDef);
type type
tproccallopt=record tproccallopt=record
mask : tproccalloption; mask : tproccalloption;
@ -1619,7 +1634,7 @@ var
tempbuf : array[0..255] of byte; tempbuf : array[0..255] of byte;
begin begin
write([space,' Return type : ']); write([space,' Return type : ']);
readderef(''); readderef('', ProcDef.ReturnType);
writeln([space,' Fpu used : ',ppufile.getbyte]); writeln([space,' Fpu used : ',ppufile.getbyte]);
proctypeoption:=tproctypeoption(ppufile.getbyte); proctypeoption:=tproctypeoption(ppufile.getbyte);
write([space,' TypeOption : ']); write([space,' TypeOption : ']);
@ -2335,7 +2350,7 @@ end;
Read defintions Part Read defintions Part
****************************************************************************} ****************************************************************************}
procedure readdefinitions(const s:string); procedure readdefinitions(const s:string; ParentDef: TPpuContainerDef);
{ type tordtype is in symconst unit } { type tordtype is in symconst unit }
{ {
uvoid, uvoid,
@ -2353,6 +2368,8 @@ var
calloption : tproccalloption; calloption : tproccalloption;
procoptions : tprocoptions; procoptions : tprocoptions;
defoptions: tdefoptions; defoptions: tdefoptions;
procdef: TPpuProcDef;
ptypedef: TPpuProcTypeDef;
begin begin
with ppufile do with ppufile do
begin begin
@ -2421,8 +2438,9 @@ begin
ibprocdef : ibprocdef :
begin begin
readcommondef('Procedure definition',defoptions); procdef:=TPpuProcDef.Create(ParentDef);
read_abstract_proc_def(calloption,procoptions); readcommondef('Procedure definition',defoptions,procdef);
read_abstract_proc_def(calloption,procoptions,procdef);
if (po_has_mangledname in procoptions) then if (po_has_mangledname in procoptions) then
{$ifdef symansistr} {$ifdef symansistr}
writeln([space,' Mangled name : ',getansistring]); writeln([space,' Mangled name : ',getansistring]);
@ -2436,7 +2454,7 @@ begin
write ([space,' Procsym : ']); write ([space,' Procsym : ']);
readderef(''); readderef('');
write ([space,' File Pos : ']); write ([space,' File Pos : ']);
readposinfo; readposinfo(procdef);
writeln([space,' Visibility : ',Visibility2Str(ppufile.getbyte)]); writeln([space,' Visibility : ',Visibility2Str(ppufile.getbyte)]);
write ([space,' SymOptions : ']); write ([space,' SymOptions : ']);
readsymoptions(space+' '); readsymoptions(space+' ');
@ -2492,8 +2510,9 @@ begin
ibprocvardef : ibprocvardef :
begin begin
readcommondef('Procedural type (ProcVar) definition',defoptions); ptypedef:=TPpuProcTypeDef.Create(ParentDef);
read_abstract_proc_def(calloption,procoptions); readcommondef('Procedural type (ProcVar) definition',defoptions,ptypedef);
read_abstract_proc_def(calloption,procoptions, ptypedef);
writeln([space,' Symtable level :',ppufile.getbyte]); writeln([space,' Symtable level :',ppufile.getbyte]);
if not EndOfEntry then if not EndOfEntry then
HasMoreInfos; HasMoreInfos;
@ -3053,7 +3072,7 @@ begin
Writeln; Writeln;
Writeln('Interface definitions'); Writeln('Interface definitions');
Writeln('----------------------'); Writeln('----------------------');
readdefinitions('interface'); readdefinitions('interface', CurUnit);
end end
else else
ppufile.skipuntilentry(ibenddefs); ppufile.skipuntilentry(ibenddefs);
@ -3116,7 +3135,7 @@ begin
Writeln; Writeln;
Writeln('Static definitions'); Writeln('Static definitions');
Writeln('----------------------'); Writeln('----------------------');
readdefinitions('implementation'); readdefinitions('implementation', nil);
end end
else else
ppufile.skipuntilentry(ibenddefs); ppufile.skipuntilentry(ibenddefs);
@ -3236,6 +3255,7 @@ begin
UnitList:=TPpuContainerDef.Create(nil); UnitList:=TPpuContainerDef.Create(nil);
try try
UnitList.ItemsName:='';
{ process files } { process files }
for nrfile:=startpara to paramcount do for nrfile:=startpara to paramcount do
dofile (paramstr(nrfile)); dofile (paramstr(nrfile));

View File

@ -37,16 +37,15 @@ type
procedure BeforeWriteElement; procedure BeforeWriteElement;
procedure WriteAttr(const AName, AValue: string); procedure WriteAttr(const AName, AValue: string);
protected protected
procedure WriteDefStart(Def: TPpuDef); override; procedure WriteObjectStart(const AName: string; Def: TPpuDef); override;
procedure WriteDefEnd(Def: TPpuDef); override; procedure WriteObjectEnd(Def: TPpuDef); override;
procedure WriteSubItemsStart(Def: TPpuContainerDef); override;
procedure WriteSubItemsEnd(Def: TPpuContainerDef); override;
procedure WriteArrayStart(const AName: string); override; procedure WriteArrayStart(const AName: string); override;
procedure WriteArrayEnd(const AName: string); override; procedure WriteArrayEnd; override;
procedure WriteStr(const AName, AValue: string); override; procedure WriteStr(const AName, AValue: string); override;
procedure WriteInt(const AName: string; AValue: Int64); override; procedure WriteInt(const AName: string; AValue: Int64); override;
procedure WriteFloat(const AName: string; AValue: extended); override; procedure WriteFloat(const AName: string; AValue: extended); override;
procedure WriteBool(const AName: string; AValue: boolean); override; procedure WriteBool(const AName: string; AValue: boolean); override;
procedure WriteNull(const AName: string); override;
public public
constructor Create(var OutFile: Text); override; constructor Create(var OutFile: Text); override;
procedure IncI; override; procedure IncI; override;
@ -155,53 +154,6 @@ begin
Write(AValue); Write(AValue);
end; end;
procedure TPpuJsonOutput.WriteDefStart(Def: TPpuDef);
begin
if Def.Parent = nil then
// Top level container
exit;
WriteLn('{');
IncI;
if Def.DefType <> dtNone then
WriteStr('Type', Def.DefTypeName);
if Def.Name <> '' then
WriteStr('Name', Def.Name);
end;
procedure TPpuJsonOutput.WriteDefEnd(Def: TPpuDef);
var
s: string;
begin
if Def.Parent = nil then
// Top level container
exit;
DecI;
s:='}';
// Last def in list?
if (Def.Parent <> nil) and (Def.Parent[Def.Parent.Count - 1] <> Def) then
s:=s + ',';
WriteLn(s);
end;
procedure TPpuJsonOutput.WriteSubItemsStart(Def: TPpuContainerDef);
begin
if Def.Parent = nil then begin
// Top level container
WriteLn('[');
exit;
end;
BeforeWriteElement;
WriteLn(Format('"%s": [', [Def.ItemsName]));
end;
procedure TPpuJsonOutput.WriteSubItemsEnd(Def: TPpuContainerDef);
begin
Write(']');
if Def.Parent = nil then
// Top level container
WriteLn;
end;
procedure TPpuJsonOutput.WriteStr(const AName, AValue: string); procedure TPpuJsonOutput.WriteStr(const AName, AValue: string);
begin begin
WriteAttr(AName, JsonStr(AValue)); WriteAttr(AName, JsonStr(AValue));
@ -228,19 +180,37 @@ begin
WriteAttr(AName, 'false'); WriteAttr(AName, 'false');
end; end;
procedure TPpuJsonOutput.WriteArrayStart(const AName: string); procedure TPpuJsonOutput.WriteNull(const AName: string);
begin begin
BeforeWriteElement; WriteAttr(AName, 'null');
WriteLn(Format('"%s": [', [AName]));
IncI;
end; end;
procedure TPpuJsonOutput.WriteArrayEnd(const AName: string); procedure TPpuJsonOutput.WriteArrayStart(const AName: string);
begin begin
DecI; WriteAttr(AName, '[');
WriteLn;
inherited;
end;
procedure TPpuJsonOutput.WriteArrayEnd;
begin
inherited;
Write(']'); Write(']');
end; end;
procedure TPpuJsonOutput.WriteObjectStart(const AName: string; Def: TPpuDef);
begin
WriteAttr(AName, '{');
WriteLn;
inherited;
end;
procedure TPpuJsonOutput.WriteObjectEnd(Def: TPpuDef);
begin
inherited;
Write('}');
end;
constructor TPpuJsonOutput.Create(var OutFile: Text); constructor TPpuJsonOutput.Create(var OutFile: Text);
begin begin
inherited Create(OutFile); inherited Create(OutFile);

View File

@ -21,20 +21,21 @@
unit ppuout; unit ppuout;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
{$I+}
interface interface
uses SysUtils, Classes; uses SysUtils, cclasses, Classes;
type type
TPpuDefType = (dtNone, dtUnit, dtClass, dtRecord, dtProc, dtField, dtProp, dtParam, dtVar, TPpuDefType = (dtNone, dtUnit, dtObject, dtRecord, dtProc, dtField, dtProp, dtParam, dtVar,
dtType, dtConst, dtProcType, dtEnum, dtSet); dtType, dtConst, dtProcType, dtEnum, dtSet);
TPpuDef = class; TPpuDef = class;
TPpuContainerDef = class; TPpuContainerDef = class;
TPpuUnitDef = class;
{ TPpuOutput } { TPpuOutput }
TPpuOutput = class TPpuOutput = class
private private
FOutFile: ^Text; FOutFile: ^Text;
@ -45,16 +46,15 @@ type
procedure SetIndent(AValue: integer); procedure SetIndent(AValue: integer);
procedure SetIndentSize(AValue: integer); procedure SetIndentSize(AValue: integer);
protected protected
procedure WriteDefStart(Def: TPpuDef); virtual; procedure WriteObjectStart(const AName: string; Def: TPpuDef = nil); virtual;
procedure WriteDefEnd(Def: TPpuDef); virtual; procedure WriteObjectEnd(Def: TPpuDef = nil); virtual;
procedure WriteSubItemsStart(Def: TPpuContainerDef); virtual; procedure WriteArrayStart(const AName: string); virtual;
procedure WriteSubItemsEnd(Def: TPpuContainerDef); virtual; procedure WriteArrayEnd; virtual;
procedure WriteStr(const AName, AValue: string); virtual; procedure WriteStr(const AName, AValue: string); virtual;
procedure WriteInt(const AName: string; AValue: Int64); virtual; procedure WriteInt(const AName: string; AValue: Int64); virtual;
procedure WriteFloat(const AName: string; AValue: extended); virtual; procedure WriteFloat(const AName: string; AValue: extended); virtual;
procedure WriteBool(const AName: string; AValue: boolean); virtual; procedure WriteBool(const AName: string; AValue: boolean); virtual;
procedure WriteArrayStart(const AName: string); virtual; procedure WriteNull(const AName: string); virtual;
procedure WriteArrayEnd(const AName: string); virtual;
public public
constructor Create(var OutFile: Text); virtual; constructor Create(var OutFile: Text); virtual;
destructor Destroy; override; destructor Destroy; override;
@ -66,13 +66,30 @@ type
property IndentSize: integer read FIndentSize write SetIndentSize; property IndentSize: integer read FIndentSize write SetIndentSize;
end; end;
{ TPpuRef }
TPpuRef = class
public
UnitIndex: word;
Id: integer;
constructor Create;
procedure Write(Output: TPpuOutput; const RefName: string);
end;
TPpuFilePos = record
FileIndex: dword;
Line, Col: integer;
end;
{ TPpuDef } { TPpuDef }
TPpuDef = class TPpuDef = class
private private
FId: integer;
FParent: TPpuContainerDef; FParent: TPpuContainerDef;
FParentUnit: TPpuUnitDef;
function GetDefTypeName: string; function GetDefTypeName: string;
procedure SetProps(AValue: TStringList); function GetParentUnit: TPpuUnitDef;
procedure SetId(AValue: integer);
protected protected
procedure WriteDef(Output: TPpuOutput); virtual; procedure WriteDef(Output: TPpuOutput); virtual;
@ -80,17 +97,18 @@ type
public public
DefType: TPpuDefType; DefType: TPpuDefType;
Name: string; Name: string;
DefId: integer; FilePos: TPpuFilePos;
constructor Create(AParent: TPpuContainerDef); virtual; reintroduce; constructor Create(AParent: TPpuContainerDef); virtual; reintroduce;
destructor Destroy; override; destructor Destroy; override;
procedure Write(Output: TPpuOutput); procedure Write(Output: TPpuOutput);
property Parent: TPpuContainerDef read FParent; property Parent: TPpuContainerDef read FParent;
property ParentUnit: TPpuUnitDef read GetParentUnit;
property Id: integer read FId write SetId;
property DefTypeName: string read GetDefTypeName; property DefTypeName: string read GetDefTypeName;
end; end;
{ TPpuContainerDef } { TPpuContainerDef }
TPpuContainerDef = class(TPpuDef) TPpuContainerDef = class(TPpuDef)
private private
FItems: TList; FItems: TList;
@ -112,8 +130,9 @@ type
end; end;
{ TPpuUnitDef } { TPpuUnitDef }
TPpuUnitDef = class(TPpuContainerDef) TPpuUnitDef = class(TPpuContainerDef)
private
FIndexById: THashSet;
protected protected
procedure WriteDef(Output: TPpuOutput); override; procedure WriteDef(Output: TPpuOutput); override;
public public
@ -123,12 +142,13 @@ type
UsedUnits: TPpuContainerDef; UsedUnits: TPpuContainerDef;
RefUnits: array of string; RefUnits: array of string;
SourceFiles: TPpuContainerDef; SourceFiles: TPpuContainerDef;
constructor Create(AParent: TPpuContainerDef); override; constructor Create(AParent: TPpuContainerDef); override;
destructor Destroy; override; destructor Destroy; override;
function FindById(AId: integer): TPpuDef;
end; end;
{ TPpuSrcFile } { TPpuSrcFile }
TPpuSrcFile = class(TPpuDef) TPpuSrcFile = class(TPpuDef)
protected protected
procedure WriteDef(Output: TPpuOutput); override; procedure WriteDef(Output: TPpuOutput); override;
@ -136,13 +156,80 @@ type
FileTime: TDateTime; FileTime: TDateTime;
end; end;
{ TPpuProcDef }
TPpuProcDef = class(TPpuContainerDef)
protected
procedure WriteDef(Output: TPpuOutput); override;
public
ReturnType: TPpuRef;
constructor Create(AParent: TPpuContainerDef); override;
destructor Destroy; override;
end;
{ TPpuProcTypeDef }
TPpuProcTypeDef = class(TPpuProcDef)
public
constructor Create(AParent: TPpuContainerDef); override;
end;
implementation implementation
const const
DefTypeNames: array[TPpuDefType] of string = DefTypeNames: array[TPpuDefType] of string =
('', 'unit', 'class', 'record', 'procedure', 'field', 'property', 'parameter', 'variable', ('', 'unit', 'object', 'record', 'procedure', 'field', 'property', 'parameter', 'variable',
'type', 'constant', 'proctype', 'enum', 'set'); 'type', 'constant', 'proctype', 'enum', 'set');
{ TPpuRef }
constructor TPpuRef.Create;
begin
UnitIndex:=$FFFF;
Id:=-1;
end;
procedure TPpuRef.Write(Output: TPpuOutput; const RefName: string);
begin
with Output do
if Id < 0 then
WriteNull(RefName)
else begin
WriteObjectStart(RefName);
if UnitIndex <> $FFFF then
WriteInt('RefUnit', UnitIndex);
WriteInt('Id', Id);
WriteObjectEnd;
end;
end;
{ TPpuProcTypeDef }
constructor TPpuProcTypeDef.Create(AParent: TPpuContainerDef);
begin
inherited Create(AParent);
DefType:=dtProcType;
end;
{ TPpuProcDef }
procedure TPpuProcDef.WriteDef(Output: TPpuOutput);
begin
inherited WriteDef(Output);
ReturnType.Write(Output, 'ReturnType');
end;
constructor TPpuProcDef.Create(AParent: TPpuContainerDef);
begin
inherited Create(AParent);
DefType:=dtProc;
ReturnType:=TPpuRef.Create;
end;
destructor TPpuProcDef.Destroy;
begin
ReturnType.Free;
inherited Destroy;
end;
{ TPpuSrcFile } { TPpuSrcFile }
procedure TPpuSrcFile.WriteDef(Output: TPpuOutput); procedure TPpuSrcFile.WriteDef(Output: TPpuOutput);
@ -170,22 +257,6 @@ begin
FIndentSize:=AValue; FIndentSize:=AValue;
end; end;
procedure TPpuOutput.WriteDefStart(Def: TPpuDef);
begin
end;
procedure TPpuOutput.WriteDefEnd(Def: TPpuDef);
begin
end;
procedure TPpuOutput.WriteSubItemsStart(Def: TPpuContainerDef);
begin
end;
procedure TPpuOutput.WriteSubItemsEnd(Def: TPpuContainerDef);
begin
end;
procedure TPpuOutput.WriteStr(const AName, AValue: string); procedure TPpuOutput.WriteStr(const AName, AValue: string);
begin begin
end; end;
@ -204,22 +275,42 @@ begin
end; end;
procedure TPpuOutput.WriteBool(const AName: string; AValue: boolean); procedure TPpuOutput.WriteBool(const AName: string; AValue: boolean);
var
s: string;
begin begin
if AValue then if AValue then
s:='1' WriteStr(AName, '1')
else else
s:='0'; WriteStr(AName, '0');
WriteStr(AName, s); end;
procedure TPpuOutput.WriteNull(const AName: string);
begin
WriteStr(AName, '');
end; end;
procedure TPpuOutput.WriteArrayStart(const AName: string); procedure TPpuOutput.WriteArrayStart(const AName: string);
begin begin
IncI;
end; end;
procedure TPpuOutput.WriteArrayEnd(const AName: string); procedure TPpuOutput.WriteArrayEnd;
begin begin
DecI;
end;
procedure TPpuOutput.WriteObjectStart(const AName: string; Def: TPpuDef);
begin
IncI;
if Def = nil then
exit;
if Def.DefType <> dtNone then
WriteStr('Type', Def.DefTypeName);
if Def.Name <> '' then
WriteStr('Name', Def.Name);
end;
procedure TPpuOutput.WriteObjectEnd(Def: TPpuDef);
begin
DecI;
end; end;
constructor TPpuOutput.Create(var OutFile: Text); constructor TPpuOutput.Create(var OutFile: Text);
@ -271,15 +362,15 @@ begin
if TargetOS <> '' then if TargetOS <> '' then
WriteStr('TargetOS', TargetOS); WriteStr('TargetOS', TargetOS);
if Crc <> 0 then if Crc <> 0 then
WriteStr('Crc', hexStr(Crc, 8)); WriteStr('CRC', hexStr(Crc, 8));
if IntfCrc <> 0 then if IntfCrc <> 0 then
WriteStr('InterfaceCrc', hexStr(IntfCrc, 8)); WriteStr('InterfaceCRC', hexStr(IntfCrc, 8));
UsedUnits.WriteDef(Output); UsedUnits.WriteDef(Output);
if Length(RefUnits) > 0 then begin if Length(RefUnits) > 0 then begin
WriteArrayStart('RefUnits'); WriteArrayStart('RefUnits');
for i:=0 to High(RefUnits) do for i:=0 to High(RefUnits) do
WriteStr('', RefUnits[i]); WriteStr('', RefUnits[i]);
WriteArrayEnd('RefUnits'); WriteArrayEnd;
end; end;
SourceFiles.WriteDef(Output); SourceFiles.WriteDef(Output);
end; end;
@ -290,21 +381,36 @@ constructor TPpuUnitDef.Create(AParent: TPpuContainerDef);
begin begin
inherited Create(AParent); inherited Create(AParent);
DefType:=dtUnit; DefType:=dtUnit;
ItemsName:='Interface';
UsedUnits:=TPpuContainerDef.Create(nil); UsedUnits:=TPpuContainerDef.Create(nil);
UsedUnits.FParent:=Self; UsedUnits.FParent:=Self;
UsedUnits.ItemsName:='UsedUnits'; UsedUnits.ItemsName:='UsedUnits';
SourceFiles:=TPpuContainerDef.Create(nil); SourceFiles:=TPpuContainerDef.Create(nil);
SourceFiles.FParent:=Self; SourceFiles.FParent:=Self;
SourceFiles.ItemsName:='SrcFiles'; SourceFiles.ItemsName:='SrcFiles';
FIndexById:=THashSet.Create(64, True, False);
end; end;
destructor TPpuUnitDef.Destroy; destructor TPpuUnitDef.Destroy;
begin begin
UsedUnits.Free; UsedUnits.Free;
SourceFiles.Free; SourceFiles.Free;
FIndexById.Free;
inherited Destroy; inherited Destroy;
end; end;
function TPpuUnitDef.FindById(AId: integer): TPpuDef;
var
h: PHashSetItem;
begin
h:=FIndexById.Find(@AId, SizeOf(AId));
if h <> nil then
Result:=TPpuDef(h^.Data)
else
Result:=nil;
end;
{ TPpuContainerDef } { TPpuContainerDef }
function TPpuContainerDef.GetCount: integer; function TPpuContainerDef.GetCount: integer;
@ -329,14 +435,10 @@ begin
inherited WriteDef(Output); inherited WriteDef(Output);
if Count = 0 then if Count = 0 then
exit; exit;
Output.WriteSubItemsStart(Self); Output.WriteArrayStart(ItemsName);
if Parent <> nil then
Output.IncI;
for i:=0 to Count - 1 do for i:=0 to Count - 1 do
Items[i].Write(Output); Items[i].Write(Output);
if Parent <> nil then Output.WriteArrayEnd;
Output.DecI;
Output.WriteSubItemsEnd(Self);
end; end;
constructor TPpuContainerDef.Create(AParent: TPpuContainerDef); constructor TPpuContainerDef.Create(AParent: TPpuContainerDef);
@ -369,22 +471,56 @@ begin
Result:=DefTypeNames[DefType]; Result:=DefTypeNames[DefType];
end; end;
procedure TPpuDef.SetProps(AValue: TStringList); function TPpuDef.GetParentUnit: TPpuUnitDef;
var
d: TPpuContainerDef;
begin begin
if FParentUnit = nil then begin
d:=Parent;
while (d <> nil) and (d.DefType <> dtUnit) do
d:=d.Parent;
FParentUnit:=TPpuUnitDef(d);
end;
Result:=FParentUnit;
end;
procedure TPpuDef.SetId(AValue: integer);
var
h: PHashSetItem;
u: TPpuUnitDef;
begin
if FId = AValue then Exit;
u:=ParentUnit;
if (FId <> -1) and (u <> nil) then begin
h:=u.FIndexById.Find(@FId, SizeOf(FId));
if h <> nil then
u.FIndexById.Remove(h);
end;
FId:=AValue;
if (FId <> -1) and (u <> nil) then begin;
h:=u.FIndexById.FindOrAdd(@FId, SizeOf(FId));
h^.Data:=Self;
end;
end; end;
procedure TPpuDef.WriteDef(Output: TPpuOutput); procedure TPpuDef.WriteDef(Output: TPpuOutput);
begin begin
with Output do begin with Output do begin
if DefId >= 0 then if Id >= 0 then
WriteInt('Id', DefId); WriteInt('Id', Id);
if FilePos.Line > 0 then begin
WriteObjectStart('SrcPos');
WriteInt('SrcFile', FilePos.FileIndex);
WriteInt('Line', FilePos.Line);
WriteInt('Col', FilePos.Col);
WriteObjectEnd;
end;
end; end;
end; end;
constructor TPpuDef.Create(AParent: TPpuContainerDef); constructor TPpuDef.Create(AParent: TPpuContainerDef);
begin begin
DefId:=-1; FId:=-1;
if AParent <> nil then if AParent <> nil then
AParent.Add(Self); AParent.Add(Self);
end; end;
@ -396,9 +532,11 @@ end;
procedure TPpuDef.Write(Output: TPpuOutput); procedure TPpuDef.Write(Output: TPpuOutput);
begin begin
Output.WriteDefStart(Self); if Parent <> nil then
Output.WriteObjectStart('', Self);
WriteDef(Output); WriteDef(Output);
Output.WriteDefEnd(Self); if Parent <> nil then
Output.WriteObjectEnd(Self);
end; end;
end. end.