fpdocclasstree.pp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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; 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. PN,S : String;
  67. begin
  68. Result:=(N.NodeType=ELEMENT_NODE);
  69. if Result then
  70. begin
  71. S:=N.NodeName;
  72. IF Assigned(Aelement.GetModule) then
  73. PN:=Aelement.GetModule.PackageName
  74. else
  75. PN:=FPackage.Name;
  76. S:='#'+PN+'.'+TDomElement(N)['unit']+S;
  77. Result:= (CompareText(S,AElement.PathName)=0)
  78. end;
  79. end;
  80. Function TClassTreeBuilder.LookForElement(PE : TDomElement; AElement : TPasElement) : TDomNode;
  81. Var
  82. N : TDomNode;
  83. begin
  84. Result:=PE;
  85. While (Result<>Nil) and Not NodeMatch(Result,AElement) do
  86. Result:=Result.NextSibling;
  87. If (Result=Nil) then
  88. if Assigned(PE) then
  89. begin
  90. N:=PE.FirstChild;
  91. While (Result=Nil) and (N<>Nil) do
  92. begin
  93. if (N.NodeType=ELEMENT_NODE) then
  94. begin
  95. Result:=LookForElement(N as TDomElement,AElement);
  96. end;
  97. N:=N.NextSibling;
  98. end;
  99. end;
  100. end;
  101. Function TClassTreeBuilder.AddToClassTree(AElement : TPasElement; ACount : Integer) : TDomElement;
  102. Var
  103. PC : TPasClassType;
  104. PE : TDomElement;
  105. M : TPasModule;
  106. N : TDomNode;
  107. begin
  108. Result:=Nil;
  109. If (AElement=Nil) then
  110. Result:=FTreeStart
  111. else If (AElement is TPasClassType) then
  112. begin
  113. if (AElement=FParentObject) then
  114. Result:=FTreeStart
  115. else
  116. begin
  117. PC:=AElement as TPasClassType;
  118. PE:=AddToClassTree(PC.AncestorType,ACount+1);
  119. if PE=Nil then
  120. begin
  121. Write('Name ',PC.Name,' parent ');
  122. if Assigned(PC.AncestorType) then
  123. Write('(Name: ',PC.AncestorType.Name,' Type:',PC.ANcestorType.ClassName,')');
  124. PE:=FClassTree.CreateElement(PC.AncestorType.Name);
  125. FTreeStart.AppendChild(PE);
  126. end;
  127. N:=LookForElement(PE,PC);
  128. If (N<>Nil) then
  129. Result:=N as TDomElement
  130. else
  131. begin
  132. Inc(ACount);
  133. Result:=FClassTree.CreateElement(AElement.Name);
  134. If Not (AElement is TPasUnresolvedTypeRef) then
  135. begin
  136. M:=AElement.GetModule;
  137. if Assigned(M) then
  138. Result['unit']:=M.Name;
  139. end;
  140. PE.AppendChild(Result);
  141. end;
  142. end;
  143. end
  144. end;
  145. end.