1 | unit VA508Classes;
|
---|
2 |
|
---|
3 | interface
|
---|
4 | uses SysUtils, Classes, Contnrs, StrUtils, Windows, HRParser, HRParserPas, Forms, Dialogs;
|
---|
5 |
|
---|
6 | type
|
---|
7 | TFormData = class
|
---|
8 | private
|
---|
9 | FFileName: string;
|
---|
10 | FlcFormClassName: string;
|
---|
11 | FInheritedForm: boolean;
|
---|
12 | FParent: TFormData;
|
---|
13 | FManagerComponentName: string;
|
---|
14 | FInheritedManager: boolean;
|
---|
15 | FFormClassName: string;
|
---|
16 | FEmptyManager: boolean;
|
---|
17 | procedure SetFormClassName(const Value: string);
|
---|
18 | public
|
---|
19 | function HasManager: boolean;
|
---|
20 | function HasParent: boolean;
|
---|
21 | property FormClassName: string read FFormClassName write SetFormClassName;
|
---|
22 | property lcFormClassName: string read FlcFormClassName;
|
---|
23 | property EmptyManager: boolean read FEmptyManager write FEmptyManager;
|
---|
24 | property FileName: string read FFileName write FFileName;
|
---|
25 | property Parent: TFormData read FParent write FParent;
|
---|
26 | property InheritedForm: boolean read FInheritedForm write FInheritedForm;
|
---|
27 | property InheritedManager: boolean read FInheritedManager write FInheritedManager;
|
---|
28 | property ManagerComponentName: string read FManagerComponentName write FManagerComponentName;
|
---|
29 | end;
|
---|
30 |
|
---|
31 | EVA508AccessibilityException = class(Exception);
|
---|
32 |
|
---|
33 | TParentChildErrorCode = (pcNoParentManager, pcValidRelationship,
|
---|
34 | pcNoInheritence, pcNoChildComponent, pcEmptyManagerComponent,
|
---|
35 | pcOtherChildComponent, pcInheritedNoParent);
|
---|
36 | const
|
---|
37 | TParentChildPassCodes = [pcNoParentManager, pcValidRelationship];
|
---|
38 | TParentChildFailCodes = [pcNoInheritence, pcNoChildComponent, pcEmptyManagerComponent,
|
---|
39 | pcOtherChildComponent, pcInheritedNoParent];
|
---|
40 | TAutoFixFailCodes = [pcNoInheritence, pcEmptyManagerComponent, pcNoChildComponent, pcInheritedNoParent];
|
---|
41 |
|
---|
42 | type
|
---|
43 | TParentChildFormTracker = class
|
---|
44 | private
|
---|
45 | FData: TObjectList;
|
---|
46 | function FindForm(AFormClassName: String): TFormData;
|
---|
47 | public
|
---|
48 | constructor Create;
|
---|
49 | destructor Destroy; override;
|
---|
50 | procedure Clear;
|
---|
51 | procedure AddForm(AFileName, AFormClassName, AManagerComponentName: string;
|
---|
52 | AEmptyManager: boolean; AInheritedForm, AInheritedManager: boolean);
|
---|
53 | procedure AddLink(ParentFormClassName, ChildFormClassName: string);
|
---|
54 | function FormCount: integer;
|
---|
55 | function GetFormData(index: integer): TFormData;
|
---|
56 | function ParentChildErrorStatus(index: integer): TParentChildErrorCode;
|
---|
57 | function ParentChildErrorDescription(index: integer): string;
|
---|
58 | end;
|
---|
59 |
|
---|
60 | TUnitSection = (usUnknown, usInterface, usImplementation);
|
---|
61 | TTokenState = (tsNormal, tsPendingEqualChar, tsPendingClassSymbol, tsPendingParenChar,
|
---|
62 | tsPendingClassName, tsPendingEndOfClass);
|
---|
63 |
|
---|
64 | TVA508Parser = class
|
---|
65 | private
|
---|
66 | FClassName: String;
|
---|
67 | FParentClass: String;
|
---|
68 | FPendingParentClass: string;
|
---|
69 | FParser: THRParserPas;
|
---|
70 | FToken: THRToken;
|
---|
71 | FLastLine: integer;
|
---|
72 | FLastPos: integer;
|
---|
73 | FTokenName: String;
|
---|
74 | FState: TTokenState;
|
---|
75 | FUnitSection: TUnitSection;
|
---|
76 | FDone: boolean;
|
---|
77 | FIsSymbol: boolean;
|
---|
78 | FIsChar: boolean;
|
---|
79 | procedure ParseToken;
|
---|
80 | public
|
---|
81 | function GetParentClassName(ClassName, FileName: String;
|
---|
82 | InStream: TStream; var OutStream: TStream): String;
|
---|
83 | function LastLineRead: integer;
|
---|
84 | function LastPosition: integer;
|
---|
85 | end;
|
---|
86 |
|
---|
87 | procedure VA508ComponentCreationCheck(AComponent, AOwner: TComponent;
|
---|
88 | AllowDataModules: boolean; ManagerRequired: boolean);
|
---|
89 | procedure VA508ComponentDestructionCheck(AComponent: TComponent);
|
---|
90 |
|
---|
91 | const
|
---|
92 | NO_OWNER_ERROR = 'Cannot create a %s component without an owner';
|
---|
93 |
|
---|
94 | implementation
|
---|
95 |
|
---|
96 | uses
|
---|
97 | VA508AccessibilityManager, VA508ImageListLabeler;
|
---|
98 |
|
---|
99 | const
|
---|
100 | MANAGER_CLASS_REQUIRED = 'Cannot create a %s component without a ' + #13#10 +
|
---|
101 | '%s component on the same form';
|
---|
102 | OTHER_COMPONENTS_DELETED = 'Deleting this %s component also deletes all' + #13#10 +
|
---|
103 | 'A %s components on this form';
|
---|
104 | OWNER_NOT_ALLOWED = 'You may not place a %s component on a %s';
|
---|
105 | OWNER_REQUIREMENTS = '%s component can only be added to a %s';
|
---|
106 | HAS_EXISTING_MANAGER_ERROR = '%s alread has a %s component';
|
---|
107 |
|
---|
108 | function HasAnotherAccessibilityManager(Root, AComponent: TComponent): boolean;
|
---|
109 | var
|
---|
110 | i: integer;
|
---|
111 | comp: TComponent;
|
---|
112 | begin
|
---|
113 | Result := false;
|
---|
114 | for i := 0 to AComponent.ComponentCount-1 do
|
---|
115 | begin
|
---|
116 | comp := AComponent.Components[i];
|
---|
117 | if (comp <> Root) and (comp is TVA508AccessibilityManager) then
|
---|
118 | begin
|
---|
119 | Result := true;
|
---|
120 | exit;
|
---|
121 | end;
|
---|
122 | if HasAnotherAccessibilityManager(Root, AComponent.Components[i]) then
|
---|
123 | begin
|
---|
124 | Result := true;
|
---|
125 | exit;
|
---|
126 | end;
|
---|
127 | end;
|
---|
128 | end;
|
---|
129 |
|
---|
130 | procedure VA508ComponentCreationCheck(AComponent, AOwner: TComponent;
|
---|
131 | AllowDataModules: boolean; ManagerRequired: boolean);
|
---|
132 | var
|
---|
133 | msg: string;
|
---|
134 |
|
---|
135 | procedure EnsureManager;
|
---|
136 | var
|
---|
137 | i: integer;
|
---|
138 | error: boolean;
|
---|
139 | begin
|
---|
140 | if (csDesigning in AOwner.ComponentState) and (not (csLoading in AOwner.ComponentState)) then
|
---|
141 | begin
|
---|
142 | error := TRUE;
|
---|
143 | for i := 0 to AOwner.ComponentCount-1 do
|
---|
144 | begin
|
---|
145 | if AOwner.Components[i] is TVA508AccessibilityManager then
|
---|
146 | begin
|
---|
147 | error := FALSE;
|
---|
148 | break;
|
---|
149 | end;
|
---|
150 | end;
|
---|
151 | if error then
|
---|
152 | begin
|
---|
153 | raise EVA508AccessibilityException.CreateFmt(MANAGER_CLASS_REQUIRED,
|
---|
154 | [AComponent.ClassName, TVA508AccessibilityManager.ClassName]);
|
---|
155 | end;
|
---|
156 | end;
|
---|
157 | end;
|
---|
158 |
|
---|
159 | begin
|
---|
160 | if not assigned(AOwner) then
|
---|
161 | raise EVA508AccessibilityException.CreateFmt(NO_OWNER_ERROR, [AComponent.ClassName]);
|
---|
162 | if (AOwner is TDataModule) then
|
---|
163 | begin
|
---|
164 | if AllowDataModules then
|
---|
165 | exit
|
---|
166 | else
|
---|
167 | raise EVA508AccessibilityException.CreateFmt(OWNER_NOT_ALLOWED, [AComponent.ClassName, TDataModule.ClassName]);
|
---|
168 | end;
|
---|
169 | if not (AOwner is TCustomForm) then
|
---|
170 | begin
|
---|
171 | msg := 'Form';
|
---|
172 | if AllowDataModules then
|
---|
173 | msg := msg + ' or a Data Module';
|
---|
174 | raise EVA508AccessibilityException.CreateFmt(OWNER_REQUIREMENTS, [AComponent.ClassName, msg]);
|
---|
175 | end;
|
---|
176 | if ManagerRequired then
|
---|
177 | EnsureManager
|
---|
178 | else
|
---|
179 | begin
|
---|
180 | if HasAnotherAccessibilityManager(AComponent, AOwner) then
|
---|
181 | raise EVA508AccessibilityException.Create(Format(HAS_EXISTING_MANAGER_ERROR,
|
---|
182 | [AOwner.ClassName, AComponent.ClassName]));
|
---|
183 | end;
|
---|
184 | end;
|
---|
185 |
|
---|
186 | procedure VA508ComponentDestructionCheck(AComponent: TComponent);
|
---|
187 | var
|
---|
188 | i: integer;
|
---|
189 | list: TObjectList;
|
---|
190 | msg: string;
|
---|
191 | ComponentAccessFound, ImageListLabelerFound: boolean;
|
---|
192 | Owner: TComponent;
|
---|
193 |
|
---|
194 | begin
|
---|
195 | if not assigned(AComponent) then exit;
|
---|
196 | Owner := AComponent.Owner;
|
---|
197 | if not assigned(Owner) then exit;
|
---|
198 | if HasAnotherAccessibilityManager(AComponent, Owner) then exit;
|
---|
199 | if (csDesigning in AComponent.ComponentState) and (not (csDestroying in Owner.ComponentState)) then
|
---|
200 | begin
|
---|
201 | list := TObjectList.Create;
|
---|
202 | try
|
---|
203 | ComponentAccessFound := FALSE;
|
---|
204 | ImageListLabelerFound := FALSE;
|
---|
205 | for I := 0 to Owner.ComponentCount-1 do
|
---|
206 | begin
|
---|
207 | if Owner.Components[i] is TVA508ComponentAccessibility then
|
---|
208 | begin
|
---|
209 | ComponentAccessFound := TRUE;
|
---|
210 | list.Add(Owner.Components[i]);
|
---|
211 | end
|
---|
212 | else
|
---|
213 | if Owner.Components[i] is TVA508ImageListLabeler then
|
---|
214 | begin
|
---|
215 | ImageListLabelerFound := TRUE;
|
---|
216 | list.Add(Owner.Components[i]);
|
---|
217 | end
|
---|
218 | end;
|
---|
219 | msg := '';
|
---|
220 | if ImageListLabelerFound then
|
---|
221 | msg := TVA508ImageListLabeler.ClassName;
|
---|
222 | if ComponentAccessFound then
|
---|
223 | begin
|
---|
224 | if msg <> '' then
|
---|
225 | msg := msg + ' and ';
|
---|
226 | msg := msg + TVA508ComponentAccessibility.ClassName;
|
---|
227 | end;
|
---|
228 | if msg <> '' then
|
---|
229 | begin
|
---|
230 | MessageDlg(Format(OTHER_COMPONENTS_DELETED, [AComponent.ClassName, msg]), mtWarning, [mbOK], 0);
|
---|
231 | end;
|
---|
232 | finally
|
---|
233 | list.Free;
|
---|
234 | end;
|
---|
235 | end;
|
---|
236 | end;
|
---|
237 |
|
---|
238 | { TFormData }
|
---|
239 |
|
---|
240 | function TFormData.HasManager: boolean;
|
---|
241 | begin
|
---|
242 | Result := ManagerComponentName <> '';
|
---|
243 | end;
|
---|
244 |
|
---|
245 | function TFormData.HasParent: boolean;
|
---|
246 | begin
|
---|
247 | Result := assigned(Parent);
|
---|
248 | end;
|
---|
249 |
|
---|
250 | procedure TFormData.SetFormClassName(const Value: string);
|
---|
251 | begin
|
---|
252 | FFormClassName := Value;
|
---|
253 | FlcFormClassName := lowerCase(Value);
|
---|
254 | end;
|
---|
255 |
|
---|
256 | { TParentChildFormTracker }
|
---|
257 |
|
---|
258 | procedure TParentChildFormTracker.AddForm(AFileName, AFormClassName, AManagerComponentName: string;
|
---|
259 | AEmptyManager: boolean; AInheritedForm, AInheritedManager: boolean);
|
---|
260 | var
|
---|
261 | data: TFormData;
|
---|
262 | begin
|
---|
263 | if FindForm(AFormClassName) = nil then
|
---|
264 | begin
|
---|
265 | Data := TFormData.Create;
|
---|
266 | data.FileName := AFileName;
|
---|
267 | data.FormClassName := AFormClassName;
|
---|
268 | data.ManagerComponentName := AManagerComponentName;
|
---|
269 | data.Parent := nil;
|
---|
270 | data.InheritedForm := AInheritedForm;
|
---|
271 | data.InheritedManager := AInheritedManager;
|
---|
272 | data.EmptyManager := AEmptyManager;
|
---|
273 | FData.Add(data);
|
---|
274 | end;
|
---|
275 | end;
|
---|
276 |
|
---|
277 | procedure TParentChildFormTracker.AddLink(ParentFormClassName, ChildFormClassName: string);
|
---|
278 | var
|
---|
279 | child,parent: TFormData;
|
---|
280 | begin
|
---|
281 | child := FindForm(ChildFormClassName);
|
---|
282 | parent := FindForm(ParentFormClassName);
|
---|
283 | if assigned(child) and assigned(parent) then
|
---|
284 | child.Parent := parent;
|
---|
285 | end;
|
---|
286 |
|
---|
287 | procedure TParentChildFormTracker.Clear;
|
---|
288 | begin
|
---|
289 | FData.Clear;
|
---|
290 | end;
|
---|
291 |
|
---|
292 | constructor TParentChildFormTracker.Create;
|
---|
293 | begin
|
---|
294 | FData := TObjectList.Create;
|
---|
295 | end;
|
---|
296 |
|
---|
297 | destructor TParentChildFormTracker.Destroy;
|
---|
298 | begin
|
---|
299 | FData.Free;
|
---|
300 | inherited;
|
---|
301 | end;
|
---|
302 |
|
---|
303 | function TParentChildFormTracker.FindForm(AFormClassName: String): TFormData;
|
---|
304 | var
|
---|
305 | i: integer;
|
---|
306 | name: string;
|
---|
307 | begin
|
---|
308 | name := lowercase(AFormClassName);
|
---|
309 | Result := nil;
|
---|
310 | for i := 0 to FData.Count - 1 do
|
---|
311 | begin
|
---|
312 | if GetFormData(i).lcFormClassName = Name then
|
---|
313 | begin
|
---|
314 | Result := GetFormData(i);
|
---|
315 | exit;
|
---|
316 | end;
|
---|
317 | end;
|
---|
318 | end;
|
---|
319 |
|
---|
320 | function TParentChildFormTracker.FormCount: integer;
|
---|
321 | begin
|
---|
322 | Result := FData.Count;
|
---|
323 | end;
|
---|
324 |
|
---|
325 | function TParentChildFormTracker.GetFormData(index: integer): TFormData;
|
---|
326 | begin
|
---|
327 | Result := TFormData(FData[index]);
|
---|
328 | end;
|
---|
329 |
|
---|
330 | function TParentChildFormTracker.ParentChildErrorDescription(index: integer): string;
|
---|
331 | var
|
---|
332 | code: TParentChildErrorCode;
|
---|
333 | parent: TFormData;
|
---|
334 | child: TFormData;
|
---|
335 | begin
|
---|
336 | code := ParentChildErrorStatus(index);
|
---|
337 | Result := '';
|
---|
338 | if code in [pcNoParentManager, pcValidRelationship] then exit;
|
---|
339 | child := GetFormData(index);
|
---|
340 | parent := child.Parent;
|
---|
341 | case code of
|
---|
342 | pcNoInheritence: Result := 'Form ' + child.FormClassName + ' descends from form ' + parent.FormClassName +
|
---|
343 | ' but uses the word "object" instead of "inherited" in the .dfm file.';
|
---|
344 | pcNoChildComponent, pcEmptyManagerComponent: Result := 'Form ' + child.FormClassName +
|
---|
345 | ' .dfm file needs to be rebuilt. To fix manually, view the form as text, then as a form, ' +
|
---|
346 | ' make sure the form is in a modified state, and save it.';
|
---|
347 | pcOtherChildComponent: Result := 'Form ' + child.FormClassName + ' has two ' + TVA508AccessibilityManager.ClassName +
|
---|
348 | ' components, one from an inherited form, and one on the form.' +
|
---|
349 | ' Remove the component on the form and use the inherited component';
|
---|
350 | pcInheritedNoParent: Result := 'Form ' + child.FormClassName + ' has a ' + TVA508AccessibilityManager.ClassName +
|
---|
351 | ' component, ' + child.ManagerComponentName +
|
---|
352 | ', that was inherited from a parent form, but ' + child.ManagerComponentName +
|
---|
353 | ' has been deleted from the parent form. To Remove the component, view the form as text, then as a form, ' +
|
---|
354 | ' make sure the form is in a modified state, and save it. Or you can add the ' +
|
---|
355 | TVA508AccessibilityManager.ClassName + ' component back onto the parent form.';
|
---|
356 | else Result := '';
|
---|
357 | end;
|
---|
358 | end;
|
---|
359 |
|
---|
360 | function TParentChildFormTracker.ParentChildErrorStatus(
|
---|
361 | index: integer): TParentChildErrorCode;
|
---|
362 | var
|
---|
363 | parent: TFormData;
|
---|
364 | child: TFormData;
|
---|
365 | bad: boolean;
|
---|
366 |
|
---|
367 | begin
|
---|
368 | Result := pcNoParentManager;
|
---|
369 | child := GetFormData(index);
|
---|
370 | if not assigned(child) then exit;
|
---|
371 |
|
---|
372 | bad := false;
|
---|
373 | if child.InheritedManager then
|
---|
374 | begin
|
---|
375 | bad := not child.HasParent;
|
---|
376 | if not bad then
|
---|
377 | bad := not child.InheritedForm;
|
---|
378 | if not bad then
|
---|
379 | bad := not child.Parent.HasManager;
|
---|
380 | end;
|
---|
381 |
|
---|
382 | try
|
---|
383 | if not child.HasParent then exit;
|
---|
384 | parent := child.Parent;
|
---|
385 | if not parent.HasManager then exit;
|
---|
386 | if child.InheritedForm then
|
---|
387 | begin
|
---|
388 | if child.HasManager then
|
---|
389 | begin
|
---|
390 | if (parent.ManagerComponentName = child.ManagerComponentName) and
|
---|
391 | (child.InheritedManager) then
|
---|
392 | begin
|
---|
393 | if child.EmptyManager then
|
---|
394 | Result := pcEmptyManagerComponent
|
---|
395 | else
|
---|
396 | Result := pcValidRelationship
|
---|
397 | end
|
---|
398 | else
|
---|
399 | Result := pcOtherChildComponent
|
---|
400 | end
|
---|
401 | else
|
---|
402 | Result := pcNoChildComponent;
|
---|
403 | end
|
---|
404 | else
|
---|
405 | Result := pcNoInheritence;
|
---|
406 | finally
|
---|
407 | if bad and (Result = pcNoParentManager) then
|
---|
408 | Result := pcInheritedNoParent;
|
---|
409 | end;
|
---|
410 | end;
|
---|
411 |
|
---|
412 | const
|
---|
413 | INTERFACE_NAME = 'interface';
|
---|
414 | IMPLEMENTATION_NAME = 'implementation';
|
---|
415 |
|
---|
416 | CLASS_NAME = 'class';
|
---|
417 | LEFT_PAREN = '(';
|
---|
418 | RIGHT_PAREN = ')';
|
---|
419 | COMMA = ',';
|
---|
420 | EQUALS = '=';
|
---|
421 |
|
---|
422 | { TVA508Parser }
|
---|
423 |
|
---|
424 | function TVA508Parser.GetParentClassName(ClassName, FileName: String;
|
---|
425 | InStream: TStream; var OutStream: TStream): String;
|
---|
426 | begin
|
---|
427 | FClassName := lowerCase(ClassName);
|
---|
428 | FParentClass := '';
|
---|
429 | FState := tsNormal;
|
---|
430 | FUnitSection := usUnknown;
|
---|
431 | FDone := false;
|
---|
432 |
|
---|
433 | if(assigned(FParser)) then
|
---|
434 | FParser.Free;
|
---|
435 | FParser := THRParserPas.Create;
|
---|
436 | FLastLine := 0;
|
---|
437 | FLastPos := 0;
|
---|
438 | if assigned(InStream) then
|
---|
439 | FParser.Source := InStream
|
---|
440 | else
|
---|
441 | FParser.Source := TFileStream.Create(FileName, fmOpenRead, fmShareDenyNone);
|
---|
442 | try
|
---|
443 | while (not FDone) and (FParser.NextToken.TokenType <> HR_TOKEN_EOF) do
|
---|
444 | begin
|
---|
445 | FToken := FParser.Token;
|
---|
446 | FLastLine := FToken.Line;
|
---|
447 | FLastPos := FToken.SourcePos;
|
---|
448 | ParseToken;
|
---|
449 | end;
|
---|
450 | finally
|
---|
451 | if assigned(InStream) then
|
---|
452 | begin
|
---|
453 | InStream.Free;
|
---|
454 | OutStream := nil;
|
---|
455 | end
|
---|
456 | else
|
---|
457 | OutStream := FParser.Source;
|
---|
458 | FreeAndNil(FParser);
|
---|
459 | end;
|
---|
460 | Result := FParentClass;
|
---|
461 | end;
|
---|
462 |
|
---|
463 | function TVA508Parser.LastLineRead: integer;
|
---|
464 | begin
|
---|
465 | Result := FLastLine;
|
---|
466 | end;
|
---|
467 |
|
---|
468 | function TVA508Parser.LastPosition: integer;
|
---|
469 | begin
|
---|
470 | Result := FLastPos + 1;
|
---|
471 | end;
|
---|
472 |
|
---|
473 | procedure TVA508Parser.ParseToken;
|
---|
474 |
|
---|
475 | function IgnoreToken: boolean;
|
---|
476 | begin
|
---|
477 | if(FUnitSection = usImplementation) then
|
---|
478 | begin
|
---|
479 | Result := TRUE;
|
---|
480 | exit;
|
---|
481 | end;
|
---|
482 | case FToken.TokenType of
|
---|
483 | HR_TOKEN_TEXT_SPACE, HR_TOKEN_PAS_COMMENT_SLASH,
|
---|
484 | HR_TOKEN_PAS_COMMENT_BRACE_OPEN, HR_TOKEN_PAS_COMMENT_BRACE,
|
---|
485 | HR_TOKEN_PAS_COMMENT_BRACKET_OPEN, HR_TOKEN_PAS_COMMENT_BRACKET:
|
---|
486 | Result := TRUE;
|
---|
487 | else
|
---|
488 | Result := FALSE;
|
---|
489 | end;
|
---|
490 | end;
|
---|
491 |
|
---|
492 | function InvalidSection: boolean;
|
---|
493 | var
|
---|
494 | changed: boolean;
|
---|
495 | begin
|
---|
496 | changed := false;
|
---|
497 | if FIsSymbol then
|
---|
498 | begin
|
---|
499 | if FTokenName = INTERFACE_NAME then
|
---|
500 | begin
|
---|
501 | FUnitSection := usInterface;
|
---|
502 | changed := true;
|
---|
503 | end
|
---|
504 | else if FTokenName = IMPLEMENTATION_NAME then
|
---|
505 | begin
|
---|
506 | FUnitSection := usImplementation;
|
---|
507 | FDone := TRUE;
|
---|
508 | changed := true;
|
---|
509 | end;
|
---|
510 | end;
|
---|
511 | Result := (FUnitSection <> usInterface);
|
---|
512 | if changed then
|
---|
513 | FState := tsNormal;
|
---|
514 | end;
|
---|
515 |
|
---|
516 | begin
|
---|
517 | if(IgnoreToken) then exit;
|
---|
518 |
|
---|
519 | FTokenName := LowerCase(FToken.Token);
|
---|
520 | FIsSymbol := (FToken.TokenType = HR_TOKEN_TEXT_SYMBOL);
|
---|
521 | FIsChar := (FToken.TokenType = HR_TOKEN_CHAR);
|
---|
522 |
|
---|
523 | if(InvalidSection) then exit;
|
---|
524 | case FState of
|
---|
525 | tsNormal: if FIsSymbol and (FTokenName = FClassName) then
|
---|
526 | FState := tsPendingEqualChar;
|
---|
527 | tsPendingEqualChar: if FIsChar and (FTokenName = EQUALS) then
|
---|
528 | FState := tsPendingClassSymbol
|
---|
529 | else
|
---|
530 | FState := tsNormal;
|
---|
531 | tsPendingClassSymbol: if FIsSymbol and (FTokenName = CLASS_NAME) then
|
---|
532 | FState := tsPendingParenChar
|
---|
533 | else
|
---|
534 | FState := tsNormal;
|
---|
535 | tsPendingParenChar: if FIsChar and (FTokenName = LEFT_PAREN) then
|
---|
536 | FState := tsPendingClassName
|
---|
537 | else
|
---|
538 | FState := tsNormal;
|
---|
539 | tsPendingClassName: if FIsSymbol then
|
---|
540 | begin
|
---|
541 | FPendingParentClass := FToken.Token;
|
---|
542 | FState := tsPendingEndOfClass;
|
---|
543 | end
|
---|
544 | else
|
---|
545 | FState := tsNormal;
|
---|
546 | tsPendingEndOfClass: begin
|
---|
547 | if FIsChar and ((FTokenName = RIGHT_PAREN) or
|
---|
548 | (FTokenName = COMMA)) then
|
---|
549 | begin
|
---|
550 | FParentClass := FPendingParentClass;
|
---|
551 | FDone := TRUE;
|
---|
552 | end;
|
---|
553 | FState := tsNormal;
|
---|
554 | end;
|
---|
555 | else
|
---|
556 | FState := tsNormal;
|
---|
557 | end;
|
---|
558 | end;
|
---|
559 |
|
---|
560 |
|
---|
561 | end.
|
---|