[829] | 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.
|
---|