fpdocclasstree.pp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. unit fpdocclasstree;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, DOM, pastree;
  6. Type
  7. TClassTreeBuilder = Class
  8. Private
  9. FClassTree : TXMLDocument;
  10. FTreeStart : TDomElement;
  11. FObjectKind : TPasObjKind;
  12. FPackage: TPasPackage;
  13. FParentObject : TPasClassType;
  14. Protected
  15. function LookForElement(PE: TDomElement; AElement: TPasElement): TDomNode;
  16. function NodeMatch(N: TDomNode; AElement: TPasElement): Boolean;
  17. Function AddToClassTree(AElement : TPasElement; Var ACount : Integer) : TDomElement;
  18. Public
  19. Constructor Create(APackage : TPasPackage; AObjectKind : TPasObjKind = okClass);
  20. Destructor Destroy; override;
  21. Function BuildTree(AObjects : TStringList) : Integer;
  22. Property ClassTree : TXMLDocument Read FClassTree;
  23. end;
  24. implementation
  25. constructor TClassTreeBuilder.Create(APackage : TPasPackage;
  26. AObjectKind: TPasObjKind);
  27. Var
  28. N : TDomNode;
  29. begin
  30. FCLassTree:=TXMLDocument.Create;
  31. FPackage:=APAckage;
  32. FObjectKind:=AObjectKind;
  33. Case FObjectkind of
  34. okObject : FParentObject:=TPasClassType.Create('System.TObject',FPackage);
  35. okClass : FParentObject:=TPasClassType.Create('System.TObject',FPackage);
  36. okInterface : FParentObject:=TPasClassType.Create('System.IInterface',FPackage);
  37. end;
  38. FParentObject.ObjKind:=FObjectKind;
  39. FTreeStart:=FClassTree.CreateElement('TObject');
  40. FTreeStart['unit']:='System';
  41. ClassTree.AppendChild(FTreeStart);
  42. end;
  43. destructor TClassTreeBuilder.Destroy;
  44. begin
  45. FreeAndNil(FClassTree);
  46. Inherited;
  47. end;
  48. Function TClassTreeBuilder.BuildTree(AObjects : TStringList) : Integer;
  49. Var
  50. I : Integer;
  51. PC : TPasClassType;
  52. begin
  53. Result:=0;
  54. AObjects.Sorted:=True;
  55. For I:=0 to AObjects.Count-1 do
  56. begin
  57. PC:=TPasClassType(AObjects.Objects[i]);
  58. If (PC.ObjKind=FObjectKind) and Not PC.IsForward then
  59. begin
  60. AddToClassTree(PC as TPasElement,Result)
  61. end;
  62. end;
  63. end;
  64. Function TClassTreeBuilder.NodeMatch(N : TDomNode; AElement : TPasElement) : Boolean;
  65. Var
  66. S : String;
  67. begin
  68. Result:=(N.NodeType=ELEMENT_NODE);
  69. if Result then
  70. begin
  71. S:=N.NodeName;
  72. S:=FPackage.Name+'.'+TDomElement(N)['unit']+'.'+S;
  73. Result:= (CompareText(S,AElement.PathName)=0)
  74. end;
  75. end;
  76. Function TClassTreeBuilder.LookForElement(PE : TDomElement; AElement : TPasElement) : TDomNode;
  77. Var
  78. N : TDomNode;
  79. begin
  80. Result:=PE;
  81. While (Result<>Nil) and Not NodeMatch(Result,AElement) do
  82. Result:=Result.NextSibling;
  83. If (Result=Nil) then
  84. begin
  85. N:=PE.FirstChild;
  86. While (Result=Nil) and (N<>Nil) do
  87. begin
  88. if (N.NodeType=ELEMENT_NODE) then
  89. begin
  90. Result:=LookForElement(N as TDomElement,AElement);
  91. end;
  92. N:=N.NextSibling;
  93. end;
  94. end
  95. end;
  96. Function TClassTreeBuilder.AddToClassTree(AElement : TPasElement; Var ACount : Integer) : TDomElement;
  97. Var
  98. PC : TPasClassType;
  99. PE : TDomElement;
  100. M : TPasModule;
  101. N : TDomNode;
  102. begin
  103. Result:=Nil;
  104. If (AElement=Nil) then
  105. Result:=FTreeStart
  106. else If (AElement is TPasClassType) then
  107. begin
  108. Writeln('Doing ',AElement.Name);
  109. if (AElement=FParentObject) then
  110. Result:=FTreeStart
  111. else
  112. begin
  113. PC:=AElement as TPasClassType;
  114. PE:=AddToClassTree(PC.AncestorType,ACount);
  115. N:=LookForElement(PE,AElement);
  116. If (N<>Nil) then
  117. Result:=N as TDomElement
  118. else
  119. begin
  120. Inc(ACount);
  121. Result:=FClassTree.CreateElement(AElement.Name);
  122. If Not (AElement is TPasUnresolvedTypeRef) then
  123. begin
  124. M:=AElement.GetModule;
  125. if Assigned(M) then
  126. Result['unit']:=M.Name;
  127. end;
  128. if (PE=FTreeStart) then
  129. begin
  130. Writeln('Adding to tree start :',AELement.Name);
  131. Writeln('Have ancestor : ',PC.AncestorType<>Nil);
  132. if (PC.AncestorType<>Nil) then
  133. Writeln(PC.AncestorType.ClassName, ' : '+PC.AncestorType.Name);
  134. end;
  135. PE.AppendChild(Result);
  136. end;
  137. end;
  138. end
  139. end;
  140. end.