fpdocclasstree.pp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. unit fpdocclasstree;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, DOM, pastree, contnrs;
  6. Type
  7. { TPasElementNode }
  8. TPasElementNode = Class
  9. Private
  10. FElement : TPasElement;
  11. FChildren : TFPObjectList;
  12. function GetChild(aIndex : Integer): TPasElementNode;
  13. function GetChildCount: Integer;
  14. Public
  15. Constructor Create (aElement : TPaselement);
  16. Destructor Destroy; override;
  17. Procedure AddChild(C : TPasElementNode);
  18. Procedure SortChildren;
  19. Property Element : TPasElement Read FElement;
  20. Property Children [aIndex : Integer] : TPasElementNode Read GetChild;
  21. Property ChildCount : Integer Read GetChildCount;
  22. end;
  23. { TClassTreeBuilder }
  24. TClassTreeBuilder = Class
  25. Private
  26. // Full name -> TDomElement;
  27. FElementList : TFPObjectHashTable;
  28. FObjectKind : TPasObjKind;
  29. FPackage: TPasPackage;
  30. FParentObject : TPasClassType;
  31. FRootNode : TPasElementNode;
  32. FRootObjectName : string;
  33. Protected
  34. function AddToList(aElement: TPasClassType): TPasElementNode;
  35. Public
  36. Constructor Create(APackage : TPasPackage; AObjectKind : TPasObjKind = okClass);
  37. Destructor Destroy; override;
  38. Function BuildTree(AObjects : TStringList) : Integer;
  39. Property RootNode : TPasElementNode Read FRootNode;
  40. end;
  41. implementation
  42. { TPasElementNode }
  43. function SortOnElementName(Item1, Item2: Pointer): Integer;
  44. begin
  45. Result:=CompareText(TPasElementNode(Item1).Element.Name,TPasElementNode(Item2).Element.Name);
  46. end;
  47. function TPasElementNode.GetChild(aIndex : Integer): TPasElementNode;
  48. begin
  49. if Assigned(FChildren) then
  50. Result:=TPasElementNode(FChildren[aIndex])
  51. else
  52. Raise EListError.Create('Index out of range');
  53. end;
  54. function TPasElementNode.GetChildCount: Integer;
  55. begin
  56. if Assigned(FChildren) then
  57. Result:=FChildren.Count
  58. else
  59. Result:=0
  60. end;
  61. constructor TPasElementNode.Create(aElement: TPaselement);
  62. begin
  63. FElement:=aElement;
  64. end;
  65. destructor TPasElementNode.Destroy;
  66. begin
  67. FreeAndNil(FChildren);
  68. inherited Destroy;
  69. end;
  70. procedure TPasElementNode.AddChild(C: TPasElementNode);
  71. begin
  72. if FChildren=Nil then
  73. FChildren:=TFPObjectList.Create(True);
  74. FChildren.Add(C);
  75. end;
  76. procedure TPasElementNode.SortChildren;
  77. begin
  78. if Assigned(FChildren) then
  79. FChildren.Sort(@SortOnElementName);
  80. end;
  81. constructor TClassTreeBuilder.Create(APackage : TPasPackage;
  82. AObjectKind: TPasObjKind);
  83. begin
  84. FPackage:=APAckage;
  85. FObjectKind:=AObjectKind;
  86. Case FObjectkind of
  87. okInterface : FRootObjectName:='#rtl.System.IInterface';
  88. okObject,
  89. okClass : FRootObjectName:='#rtl.System.TObject';
  90. else
  91. FRootObjectName:='#rtl.System.TObject';
  92. end;
  93. FParentObject:=TPasClassType.Create(FRootObjectName,FPackage);
  94. FParentObject.ObjKind:=FObjectKind;
  95. FRootNode:=TPasElementNode.Create(FParentObject);
  96. FElementList:=TFPObjectHashTable.Create(False);
  97. FElementList.Add(FRootObjectName,FRootNode);
  98. end;
  99. destructor TClassTreeBuilder.Destroy;
  100. begin
  101. FreeAndNil(FParentObject);
  102. FreeAndNil(FRootNode);
  103. FreeAndNil(FElementList);
  104. Inherited;
  105. end;
  106. Function TClassTreeBuilder.AddToList(aElement : TPasClassType) : TPasElementNode;
  107. Var
  108. aParentNode : TPasElementNode;
  109. aName : String;
  110. begin
  111. if aElement=Nil then
  112. aName:=FRootObjectName
  113. else
  114. begin
  115. aName:=aElement.PathName;
  116. end;
  117. Result:=TPasElementNode(FElementList.Items[aName]);
  118. if (Result=Nil) then
  119. begin
  120. if aElement.AncestorType is TPasClassType then
  121. aParentNode:=AddToList(aElement.AncestorType as TPasClassType)
  122. else
  123. aParentNode:=FRootNode;
  124. Result:=TPasElementNode.Create(aElement);
  125. aParentNode.AddChild(Result);
  126. FElementList.Add(aName,Result);
  127. end;
  128. end;
  129. Function TClassTreeBuilder.BuildTree(AObjects : TStringList) : Integer;
  130. (*
  131. Procedure DumpNode(Prefix : String; N : TPasElementNode);
  132. Var
  133. I : Integer;
  134. begin
  135. Writeln(Prefix,N.FElement.Name);
  136. if Assigned(N.FChildren) then
  137. For I:=0 to N.FChildren.Count-1 do
  138. DumpNode(Prefix+' ',TPasElementNode(N.FChildren[i]));
  139. end;
  140. *)
  141. Var
  142. I : Integer;
  143. PC : TPasClassType;
  144. begin
  145. Result:=0;
  146. For I:=0 to AObjects.Count-1 do
  147. // Advanced records
  148. if AObjects.Objects[i] is TPasClassType then
  149. begin
  150. PC:=AObjects.Objects[i] as TPasClassType;
  151. AddToList(PC);
  152. end;
  153. end;
  154. end.