PageRenderTime 33ms CodeModel.GetById 28ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 1ms

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