/components/jcf2/Process/Transform/UsesClauseRemove.pas

http://github.com/graemeg/lazarus · Pascal · 167 lines · 96 code · 30 blank · 41 comment · 13 complexity · 495b1f70505b6ca2b4f24a23f4411698 MD5 · raw file

  1. unit UsesClauseRemove;
  2. {(*}
  3. (*------------------------------------------------------------------------------
  4. Delphi Code formatter source code
  5. The Original Code is UsesClauseRemove.pas, released October 2003.
  6. The Initial Developer of the Original Code is Anthony Steele.
  7. Portions created by Anthony Steele are Copyright (C) 1999-2008 Anthony Steele.
  8. All Rights Reserved.
  9. Contributor(s): Anthony Steele.
  10. The contents of this file are subject to the Mozilla Public License Version 1.1
  11. (the "License"). you may not use this file except in compliance with the License.
  12. You may obtain a copy of the License at http://www.mozilla.org/NPL/
  13. Software distributed under the License is distributed on an "AS IS" basis,
  14. WITHOUT WARRANTY OF ANY KIND, either express or implied.
  15. See the License for the specific language governing rights and limitations
  16. under the License.
  17. Alternatively, the contents of this file may be used under the terms of
  18. the GNU General Public License Version 2 or later (the "GPL")
  19. See http://www.gnu.org/licenses/gpl.html
  20. ------------------------------------------------------------------------------*)
  21. {*)}
  22. {$I JcfGlobal.inc}
  23. interface
  24. { AFS 4 October 2003
  25. - massage the uses clause. Remove units
  26. }
  27. uses
  28. { local }
  29. SourceToken,
  30. SwitchableVisitor;
  31. type
  32. TUsesClauseRemove = class(TSwitchableVisitor)
  33. private
  34. fiCount: integer;
  35. fbDoneInterface, fbDoneImplementation: boolean;
  36. function MatchesSearch(const ps: string): boolean;
  37. protected
  38. function EnabledVisitSourceToken(const pcNode: TObject): Boolean; override;
  39. public
  40. constructor Create; override;
  41. function IsIncludedInSettings: boolean; override;
  42. function FinalSummary(out psMessage: string): boolean; override;
  43. end;
  44. implementation
  45. uses
  46. { delphi }
  47. SysUtils,
  48. { local }
  49. JcfSettings,
  50. Tokens,
  51. FormatFlags,
  52. ParseTreeNodeType,
  53. TokenUtils;
  54. constructor TUsesClauseRemove.Create;
  55. begin
  56. inherited;
  57. FormatFlags := FormatFlags + [eFindReplaceUses];
  58. fbDoneInterface := False;
  59. fbDoneImplementation := False;
  60. fiCount := 0;
  61. end;
  62. function TUsesClauseRemove.IsIncludedInSettings: boolean;
  63. begin
  64. Result := (FormatSettings.UsesClause.InsertInterfaceEnabled or
  65. FormatSettings.UsesClause.InsertImplementationEnabled);
  66. end;
  67. function TUsesClauseRemove.EnabledVisitSourceToken(const pcNode: TObject): Boolean;
  68. var
  69. lcSourceToken, lcSepAfter, lcSepBefore: TSourceToken;
  70. lbInterface, lbImplementation: boolean;
  71. begin
  72. Result := False;
  73. if pcNode = nil then
  74. exit;
  75. lcSourceToken := TSourceToken(pcNode);
  76. { only do this in a uses clause }
  77. if not lcSourceToken.HasParentNode(nUses) then
  78. exit;
  79. lbInterface := lcSourceToken.HasParentNode(nInterfaceSection);
  80. if lbInterface then
  81. lbImplementation := False
  82. else
  83. lbImplementation := lcSourceToken.HasParentNode(nImplementationSection);
  84. if not (lbImplementation or lbInterface) then
  85. exit;
  86. { only proceed on one of the specified words }
  87. if not (lcSourceToken.TokenType = ttIdentifier) then
  88. exit;
  89. if not MatchesSearch(lcSourceToken.SourceCode) then
  90. exit;
  91. { throw away the word and the trailing comma, as in uses clause find/replace }
  92. BlankToken(lcSourceToken);
  93. lcSepAfter := lcSourceToken.NextSolidToken;
  94. if lcSepAfter.TokenType = ttComma then
  95. begin
  96. BlankToken(lcSepAfter);
  97. end
  98. else if lcSepAfter.TokenType = ttSemiColon then
  99. begin
  100. { can't remove the semicolon, but doing nothing
  101. might leave a comma just before it, e.g. "uses foo, ;"
  102. get rid of that comma }
  103. lcSepBefore := lcSourceToken.PriorSolidToken;
  104. if lcSepBefore.TokenType = ttComma then
  105. BlankToken(lcSepBefore)
  106. else if lcSepBefore.TokenType = ttUses then
  107. begin
  108. { "uses" before, ";" after. There must have been only 1 unit in the uses clause
  109. remove it entirely }
  110. BlankToken(lcSepAfter);
  111. BlankToken(lcSepBefore);
  112. end;
  113. end;
  114. end;
  115. function TUsesClauseRemove.FinalSummary(out psMessage: string): boolean;
  116. begin
  117. Result := (fiCount > 0);
  118. if Result then
  119. begin
  120. psMessage := 'Uses clause removal: ' + IntToStr(fiCount) + ' removals were made';
  121. end
  122. else
  123. begin
  124. psMessage := '';
  125. end;
  126. end;
  127. function TUsesClauseRemove.MatchesSearch(const ps: string): boolean;
  128. begin
  129. Result := FormatSettings.UsesClause.Remove.IndexOf(ps) >= 0;
  130. end;
  131. end.