1 {(*}
2 (*------------------------------------------------------------------------------
3 Delphi Code formatter source code
4
5 The Original Code is Token.pas, released April 2000.
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
11 The contents of this file are subject to the Mozilla Public License Version 1.1
12 (the "License"). you may not use this file except in compliance with the License.
13 You may obtain a copy of the License at http://www.mozilla.org/NPL/
14
15 Software distributed under the License is distributed on an "AS IS" basis,
16 WITHOUT WARRANTY OF ANY KIND, either express or implied.
17 See the License for the specific language governing rights and limitations
18 under the License.
19
20 Alternatively, the contents of this file may be used under the terms of
21 the GNU General Public License Version 2 or later (the "GPL")
22 See http://www.gnu.org/licenses/gpl.html
23 ------------------------------------------------------------------------------*)
24 {*)}
25
26 unit SourceToken;
27
28 { Created AFS 29 Nov 1999
29 Token - element of source code text }
30
31 {$I JcfGlobal.inc}
32
33 interface
34
35 uses
36 SysUtils,
37 { local }
38 Tokens, ParseTreeNode;
39
40 type
41
42 TSourceToken = class(TParseTreeNode)
43 private
44 { property implementation }
45 fsSourceCode: String;
46 feTokenType: TTokenType;
47 feWordType: TWordType;
48 feCommentStyle: TCommentStyle;
49
50 fsFileName: string;
51 fiXPosition, fiYPosition: integer;
52 fiSolidTokenOnLineIndex: integer;
53 fbPreprocessedOut: boolean;
54
55 fePreprocessorSymbol: TPreProcessorSymbolType;
56 fsPreProcessorText: String;
57
58 protected
59 public
60 constructor Create;
61
Describenull62 function Describe: string; override;
DescribePositionnull63 function DescribePosition: string;
64
IsSolidnull65 function IsSolid: boolean;
SourceLinenull66 function SourceLine: string;
67
HasChildNodenull68 function HasChildNode(const peTokens: TTokenTypeSet): boolean; override;
HasChildNodenull69 function HasChildNode(const peTokens: TTokenTypeSet;
70 const {%H-}piMaxDepth: integer): boolean; override;
71
SolidChildCountnull72 function SolidChildCount: integer; override;
FirstSolidLeafnull73 function FirstSolidLeaf: TParseTreeNode; override;
IsLeafnull74 function IsLeaf: boolean; override;
75
76 { navigating the source tree as if it was a list }
NextTokennull77 function NextToken: TSourceToken;
PriorTokennull78 function PriorToken: TSourceToken;
NextSolidTokennull79 function NextSolidToken: TSourceToken;
PriorSolidTokennull80 function PriorSolidToken: TSourceToken;
NextTokenWithExclusionsnull81 function NextTokenWithExclusions(const peExclusions: TTokenTypeSet): TSourceToken;
PriorTokenWithExclusionsnull82 function PriorTokenWithExclusions(const peExclusions: TTokenTypeSet): TSourceToken;
83
84 procedure GeneratePreProcessorData;
85
86 property TokenType: TTokenType Read feTokenType Write feTokenType;
87 property WordType: TWordType Read feWordType Write feWordType;
88
89 property SourceCode: String Read fsSourceCode Write fsSourceCode;
90 property CommentStyle: TCommentStyle Read feCommentStyle Write feCommentStyle;
91
92 property FileName: string read fsFileName write fsFileName;
93 property XPosition: integer Read fiXPosition Write fiXPosition;
94 property YPosition: integer Read fiYPosition Write fiYPosition;
95 property SolidTokenOnLineIndex: integer
96 Read fiSolidTokenOnLineIndex Write fiSolidTokenOnLineIndex;
97
98 property PreprocessorSymbol: TPreProcessorSymbolType Read fePreprocessorSymbol;
99 property PreProcessorText: String Read fsPreProcessorText;
100
101 property PreprocessedOut: boolean Read fbPreprocessedOut Write fbPreprocessedOut;
102 end;
103
104 TSourceTokenProcedure = procedure(const pt: TSourceToken) of object;
105
106 implementation
107
108 {-------------------------------------------------------------------------------
109 TSourceToken }
110
111 constructor TSourceToken.Create;
112 begin
113 inherited;
114
115 feTokenType := ttUnknown;
116 fsSourceCode := '';
117
118 feWordType := wtNotAWord;
119 feCommentStyle := eNotAComment;
120
121 fiXPosition := -1;
122 fiYPosition := -1;
123 fiSolidTokenOnLineIndex := -1;
124
125 fePreprocessorSymbol := ppNone;
126 fsPreProcessorText := '';
127 fbPreprocessedOut := False;
128 end;
129
Describenull130 function TSourceToken.Describe: string;
131 const
132 StructuredTokens: TTokenTypeSet =
133 [ttComment, ttNumber, ttQuotedLiteralString, ttUnknown, ttPunctuation, ttIdentifier];
134 begin
135 if TokenType = ttIdentifier then
136 Result := SourceCode
137 else
138 begin
139 Result := TokenTypeToString(TokenType);
140 if (TokenType in StructuredTokens) then
141 Result := Result + ' ' + SourceCode;
142 end;
143 end;
144
TSourceToken.DescribePositionnull145 function TSourceToken.DescribePosition: string;
146 begin
147 Result := '';
148
149 if YPosition > 0 then
150 begin
151 Result := Result + 'on line ' + IntToStr(YPosition);
152
153 if XPosition > 0 then
154 Result := Result + ' position ' + IntToStr(XPosition);
155 end;
156 end;
157
TSourceToken.HasChildNodenull158 function TSourceToken.HasChildNode(const peTokens: TTokenTypeSet): boolean;
159 begin
160 Result := (TokenType in peTokens);
161 end;
162
TSourceToken.HasChildNodenull163 function TSourceToken.HasChildNode(const peTokens: TTokenTypeSet;
164 const piMaxDepth: integer): boolean;
165 begin
166 Result := (TokenType in peTokens);
167 end;
168
IsSolidnull169 function TSourceToken.IsSolid: boolean;
170 begin
171 Result := not (TokenType in NotSolidTokens);
172 end;
173
174
NextTokennull175 function TSourceToken.NextToken: TSourceToken;
176 var
177 lcTemp: TParseTreeNode;
178 begin
179 Result := nil;
180 lcTemp := NextLeafNode;
181 if lcTemp = nil then
182 exit;
183
184 Assert(lcTemp is TSourceToken, 'Next leaf is not token at ' + Describe);
185 Result := TSourceToken(lcTemp);
186 end;
187
TSourceToken.PriorTokennull188 function TSourceToken.PriorToken: TSourceToken;
189 var
190 lcTemp: TParseTreeNode;
191 begin
192 Result := nil;
193 lcTemp := PriorLeafNode;
194 if lcTemp = nil then
195 exit;
196
197 Assert(lcTemp is TSourceToken, 'prior leaf is not token at ' + Describe);
198 Result := TSourceToken(lcTemp);
199 end;
200
TSourceToken.NextSolidTokennull201 function TSourceToken.NextSolidToken: TSourceToken;
202 begin
203 Result := NextToken;
204
205 while (Result <> nil) and ( not Result.IsSolid) do
206 Result := Result.NextToken;
207 end;
208
NextTokenWithExclusionsnull209 function TSourceToken.NextTokenWithExclusions(
210 const peExclusions: TTokenTypeSet): TSourceToken;
211 begin
212 Result := NextToken;
213
214 while (Result <> nil) and (Result.TokenType in peExclusions) do
215 Result := Result.NextToken;
216 end;
217
TSourceToken.PriorTokenWithExclusionsnull218 function TSourceToken.PriorTokenWithExclusions(
219 const peExclusions: TTokenTypeSet): TSourceToken;
220 begin
221 Result := PriorToken;
222
223 while (Result <> nil) and (Result.TokenType in peExclusions) do
224 Result := Result.PriorToken;
225 end;
226
227
TSourceToken.PriorSolidTokennull228 function TSourceToken.PriorSolidToken: TSourceToken;
229 begin
230 Result := PriorToken;
231
232 while (Result <> nil) and ( not Result.IsSolid) do
233 Result := Result.PriorToken;
234 end;
235
SolidChildCountnull236 function TSourceToken.SolidChildCount: integer;
237 begin
238 if IsSolid then
239 Result := 1
240 else
241 Result := 0;
242 end;
243
SourceLinenull244 function TSourceToken.SourceLine: string;
245 var
246 lcLineToken: TSourceToken;
247 begin
248 // find the return at the start of the line
249 // or nil for start of first line
250 lcLineToken := self;
251
252 while lcLineToken.PriorToken <> nil do
253 begin
254 if lcLineToken.PriorToken.TokenType = ttReturn then
255 break
256 else
257 lcLineToken := lcLineToken.PriorToken;
258 end;
259
260 // walk to the end of the line
261 Result := '';
262 while (lcLineToken <> nil) and (lcLineToken.TokenType <> ttReturn) do
263 begin
264 Result := Result + lcLineToken.SourceCode;
265 lcLineToken := lcLineToken.NextToken;
266 end;
267 end;
268
TSourceToken.FirstSolidLeafnull269 function TSourceToken.FirstSolidLeaf: TParseTreeNode;
270 begin
271 if IsSolid then
272 Result := self
273 else
274 Result := nil;
275 end;
276
IsLeafnull277 function TSourceToken.IsLeaf: boolean;
278 begin
279 Result := True;
280 end;
281
282 procedure TSourceToken.GeneratePreProcessorData;
283 begin
284 GetPreprocessorSymbolData(SourceCode, fePreprocessorSymbol, fsPreProcessorText);
285 end;
286
287 end.
288