From ce4ccfc0aa652a0244d3a6815ae56abdf1507370 Mon Sep 17 00:00:00 2001 From: Mattias Gaertner <nc-gaertnma@netcologne.de> Date: Mon, 22 Oct 2018 10:39:43 +0000 Subject: [PATCH] fcl-passrc: adapt pasuseanalyzer for pas2js git-svn-id: trunk@40013 - --- packages/fcl-passrc/src/pastree.pp | 17 +- packages/fcl-passrc/src/pasuseanalyzer.pas | 439 ++++++++++++++++----- 2 files changed, 353 insertions(+), 103 deletions(-) diff --git a/packages/fcl-passrc/src/pastree.pp b/packages/fcl-passrc/src/pastree.pp index 26bdd3f465..a3de220b8d 100644 --- a/packages/fcl-passrc/src/pastree.pp +++ b/packages/fcl-passrc/src/pastree.pp @@ -135,6 +135,10 @@ type FParent: TPasElement; FHints : TPasMemberHints; FHintMessage : String; + {$ifdef pas2js} + FPasElementId: NativeInt; + class var FLastPasElementId: NativeInt; + {$endif} {$ifdef EnablePasTreeGlobalRefCount} class var FGlobalRefCount: int64; {$endif} @@ -175,9 +179,12 @@ type property RefCount: LongWord read FRefCount; property Name: string read FName write FName; property Parent: TPasElement read FParent Write SetParent; - Property Hints : TPasMemberHints Read FHints Write FHints; - Property HintMessage : String Read FHintMessage Write FHintMessage; - Property DocComment : String Read FDocComment Write FDocComment; + property Hints : TPasMemberHints Read FHints Write FHints; + property HintMessage : String Read FHintMessage Write FHintMessage; + property DocComment : String Read FDocComment Write FDocComment; + {$ifdef pas2js} + property PasElementId: NativeInt read FPasElementId; // global unique id + {$endif} {$ifdef EnablePasTreeGlobalRefCount} class property GlobalRefCount: int64 read FGlobalRefCount write FGlobalRefCount; {$endif} @@ -2308,6 +2315,10 @@ begin inherited Create; FName := AName; FParent := AParent; + {$ifdef pas2js} + inc(FLastPasElementId); + FPasElementId:=FLastPasElementId; + {$endif} {$ifdef EnablePasTreeGlobalRefCount} Inc(FGlobalRefCount); {$endif} diff --git a/packages/fcl-passrc/src/pasuseanalyzer.pas b/packages/fcl-passrc/src/pasuseanalyzer.pas index dee9a36098..308adde87f 100644 --- a/packages/fcl-passrc/src/pasuseanalyzer.pas +++ b/packages/fcl-passrc/src/pasuseanalyzer.pas @@ -39,12 +39,23 @@ Working: } unit PasUseAnalyzer; -{$mode objfpc}{$H+}{$inline on} +{$mode objfpc}{$H+} +{$inline on} + +{$ifdef fpc} + {$define UsePChar} + {$define HasInt64} +{$endif} interface uses - Classes, SysUtils, Types, AVL_Tree, + {$ifdef pas2js} + js, + {$else} + AVL_Tree, + {$endif} + Classes, SysUtils, Types, PasTree, PScanner, PasResolveEval, PasResolver; const @@ -88,7 +99,7 @@ type private FRefCount: integer; public - Id: int64; + Id: TMaxPrecInt; MsgType: TMessageType; MsgNumber: integer; MsgText: string; @@ -148,6 +159,43 @@ type property Overrides[Index: integer]: TPasElement read GetOverrides; default; end; + {$ifdef pas2js} + TPASItemToNameProc = function(Item: Pointer): String; + {$endif} + + { TPasAnalyzerKeySet - set of items, each item has a key, no duplicate keys } + + TPasAnalyzerKeySet = class + private + {$ifdef pas2js} + FItems: TJSObject; + FCount: integer; + FItemToName: TPASItemToNameProc; + FKeyToName: TPASItemToNameProc; + {$else} + FTree: TAVLTree; // tree of pointers, sorted for keys given by OnItemToKey, no duplicate keys + FCompareKeyWithData: TListSortCompare; + {$endif} + public + {$ifdef pas2js} + constructor Create(const OnItemToName, OnKeyToName: TPASItemToNameProc); reintroduce; + {$else} + constructor Create(const OnCompareMethod: TListSortCompare; + const OnCompareKeyWithData: TListSortCompare); + {$endif} + destructor Destroy; override; + procedure Clear; + procedure FreeItems; + procedure Add(Item: Pointer; CheckDuplicates: boolean = true); + procedure Remove(Item: Pointer); + function ContainsItem(Item: Pointer): boolean; + function ContainsKey(Key: Pointer): boolean; + function FindItem(Item: Pointer): Pointer; + function FindKey(Key: Pointer): Pointer; + function Count: integer; + function GetList: TFPList; // list of items + end; + TPasAnalyzerOption = ( paoOnlyExports, // default: use all class members accessible from outside (protected, but not private) paoImplReferences // collect references of top lvl proc implementations, initializationa dn finalization sections @@ -175,29 +223,26 @@ type TPasAnalyzer = class private - FChecked: array[TPAUseMode] of TAVLTree; // tree of TElement + FChecked: array[TPAUseMode] of TPasAnalyzerKeySet; // tree of TElement FOnMessage: TPAMessageEvent; FOptions: TPasAnalyzerOptions; - FOverrideLists: TAVLTree; // tree of TPAOverrideList sorted for Element + FOverrideLists: TPasAnalyzerKeySet; // tree of TPAOverrideList sorted for Element FResolver: TPasResolver; FScopeModule: TPasModule; - FUsedElements: TAVLTree; // tree of TPAElement sorted for Element + FUsedElements: TPasAnalyzerKeySet; // tree of TPAElement sorted for Element procedure UseElType(El: TPasElement; aType: TPasType; Mode: TPAUseMode); inline; function AddOverride(OverriddenEl, OverrideEl: TPasElement): boolean; - function FindOverrideNode(El: TPasElement): TAVLTreeNode; - function FindOverrideList(El: TPasElement): TPAOverrideList; procedure SetOptions(AValue: TPasAnalyzerOptions); procedure UpdateAccess(IsWrite: Boolean; IsRead: Boolean; Usage: TPAElement); procedure OnUseScopeRef(Data, DeclScope: pointer); protected - procedure RaiseInconsistency(const Id: int64; Msg: string); - procedure RaiseNotSupported(const Id: int64; El: TPasElement; const Msg: string = ''); + procedure RaiseInconsistency(const Id: TMaxPrecInt; Msg: string); + procedure RaiseNotSupported(const Id: TMaxPrecInt; El: TPasElement; const Msg: string = ''); function FindTopImplScope(El: TPasElement): TPasScope; // mark used elements function Add(El: TPasElement; CheckDuplicate: boolean = true; aClass: TPAElementClass = nil): TPAElement; - function FindNode(El: TPasElement): TAVLTreeNode; inline; - function FindPAElement(El: TPasElement): TPAElement; inline; + function PAElementExists(El: TPasElement): boolean; inline; procedure CreateTree; virtual; function MarkElementAsUsed(El: TPasElement; aClass: TPAElementClass = nil): boolean; // true if new function ElementVisited(El: TPasElement; Mode: TPAUseMode): boolean; @@ -238,7 +283,7 @@ type procedure AnalyzeModule(aModule: TPasModule); procedure AnalyzeWholeProgram(aStartModule: TPasProgram); procedure EmitModuleHints(aModule: TPasModule); virtual; - function FindElement(El: TPasElement): TPAElement; + function FindElement(El: TPasElement): TPAElement; inline; function FindUsedElement(El: TPasElement): TPAElement; // utility function IsUsed(El: TPasElement): boolean; // valid after calling Analyze* @@ -247,8 +292,10 @@ type function IsExport(El: TPasElement): boolean; function IsIdentifier(El: TPasElement): boolean; function IsImplBlockEmpty(El: TPasImplBlock): boolean; - procedure EmitMessage(Id: int64; MsgType: TMessageType; - MsgNumber: integer; Fmt: String; const Args: array of const; PosEl: TPasElement); + procedure EmitMessage(Id: TMaxPrecInt; MsgType: TMessageType; + MsgNumber: integer; Fmt: String; + const Args: array of {$ifdef pas2js}jsvalue{$else}const{$endif}; + PosEl: TPasElement); procedure EmitMessage(Msg: TPAMessage); class function GetWarnIdentifierNumbers(Identifier: string; out MsgNumbers: TIntegerDynArray): boolean; virtual; @@ -259,15 +306,43 @@ type property ScopeModule: TPasModule read FScopeModule write FScopeModule; end; +{$ifdef pas2js} +function PasElementToHashName(Item: Pointer): String; +function PAElement_ElToHashName(Item: Pointer): String; +function PAOverrideList_ElToHashName(Item: Pointer): String; +{$else} function ComparePAElements(Identifier1, Identifier2: Pointer): integer; function CompareElementWithPAElement(El, Id: Pointer): integer; function ComparePAOverrideLists(List1, List2: Pointer): integer; function CompareElementWithPAOverrideList(El, List: Pointer): integer; +{$endif} function GetElModName(El: TPasElement): string; function dbgs(a: TPAIdentifierAccess): string; overload; implementation +{$ifdef pas2js} +function PasElementToHashName(Item: Pointer): String; +var + El: TPasElement absolute Item; +begin + Result:=string(jsvalue(El.PasElementId)); +end; + +function PAElement_ElToHashName(Item: Pointer): String; +var + El: TPAElement absolute Item; +begin + Result:=string(jsvalue(El.Element.PasElementId)); +end; + +function PAOverrideList_ElToHashName(Item: Pointer): String; +var + List: TPAOverrideList absolute Item; +begin + Result:=string(jsvalue(List.Element.PasElementId)); +end; +{$else} function ComparePointer(Data1, Data2: Pointer): integer; begin if Data1>Data2 then Result:=-1 @@ -304,6 +379,7 @@ var begin Result:=ComparePointer(El,OvList.Element); end; +{$endif} function GetElModName(El: TPasElement): string; var @@ -324,6 +400,190 @@ begin str(a,Result); end; +{ TPasAnalyzerKeySet } + +{$ifdef pas2js} +constructor TPasAnalyzerKeySet.Create(const OnItemToName, + OnKeyToName: TPASItemToNameProc); +begin + FItemToName:=OnItemToName; + FKeyToName:=OnKeyToName; + FItems:=TJSObject.new; +end; +{$else} +constructor TPasAnalyzerKeySet.Create(const OnCompareMethod: TListSortCompare; + const OnCompareKeyWithData: TListSortCompare); +begin + FTree:=TAVLTree.Create(OnCompareMethod); + FCompareKeyWithData:=OnCompareKeyWithData; +end; +{$endif} + +destructor TPasAnalyzerKeySet.Destroy; +begin + {$ifdef pas2js} + FItems:=nil; + {$else} + FreeAndNil(FTree); + {$endif} + inherited Destroy; +end; + +procedure TPasAnalyzerKeySet.Clear; +begin + {$ifdef pas2js} + FItems:=TJSObject.new; + FCount:=0; + {$else} + FTree.Clear; + {$endif} +end; + +procedure TPasAnalyzerKeySet.FreeItems; +{$ifdef pas2js} +var + List: TStringDynArray; + i: Integer; +begin + List:=TJSObject.getOwnPropertyNames(FItems); + for i:=0 to length(List)-1 do + TObject(FItems[List[i]]).Destroy; + FItems:=TJSObject.new; + FCount:=0; +end; +{$else} +begin + FTree.FreeAndClear; +end; +{$endif} + +procedure TPasAnalyzerKeySet.Add(Item: Pointer; CheckDuplicates: boolean); +begin + if CheckDuplicates then + if ContainsItem(Item) then + raise Exception.Create('TPasAnalyzerSet.Add duplicate'); + {$ifdef pas2js} + FItems[FItemToName(Item)]:=Item; + inc(FCount); + {$else} + FTree.Add(Item); + {$endif} +end; + +procedure TPasAnalyzerKeySet.Remove(Item: Pointer); +{$ifdef pas2js} +var + aName: string; +begin + aName:=FItemToName(Item); + if not FItems.hasOwnProperty(aName) then exit; + JSDelete(FItems,aName); + dec(FCount); +end; +{$else} +begin + FTree.Remove(Item); +end; +{$endif} + +function TPasAnalyzerKeySet.ContainsItem(Item: Pointer): boolean; +begin + {$ifdef pas2js} + Result:=FItems.hasOwnProperty(FItemToName(Item)); + {$else} + Result:=FTree.Find(Item)<>nil; + {$endif} +end; + +function TPasAnalyzerKeySet.ContainsKey(Key: Pointer): boolean; +begin + {$ifdef pas2js} + Result:=FItems.hasOwnProperty(FKeyToName(Key)); + {$else} + Result:=FTree.FindKey(Key,FCompareKeyWithData)<>nil; + {$endif} +end; + +function TPasAnalyzerKeySet.FindItem(Item: Pointer): Pointer; +{$ifdef pas2js} +var + aName: string; +begin + aName:=FItemToName(Item); + if not FItems.hasOwnProperty(aName) then + exit(nil) + else + Result:=Pointer(FItems[aName]); +end; +{$else} +var + Node: TAVLTreeNode; +begin + Node:=FTree.Find(Item); + if Node<>nil then + Result:=Node.Data + else + Result:=nil; +end; +{$endif} + +function TPasAnalyzerKeySet.FindKey(Key: Pointer): Pointer; +{$ifdef pas2js} +var + aName: string; +begin + aName:=FKeyToName(Key); + if not FItems.hasOwnProperty(aName) then + exit(nil) + else + Result:=Pointer(FItems[aName]); +end; +{$else} +var + Node: TAVLTreeNode; +begin + Node:=FTree.FindKey(Key,FCompareKeyWithData); + if Node<>nil then + Result:=Node.Data + else + Result:=nil; +end; +{$endif} + +function TPasAnalyzerKeySet.Count: integer; +begin + {$ifdef pas2js} + Result:=FCount; + {$else} + Result:=FTree.Count; + {$endif} +end; + +function TPasAnalyzerKeySet.GetList: TFPList; +{$ifdef pas2js} +var + List: TStringDynArray; + i: Integer; +begin + List:=TJSObject.getOwnPropertyNames(FItems); + Result:=TFPList.Create; + for i:=0 to length(List)-1 do + Result.Add(FItems[List[i]]); +end; +{$else} +var + Node: TAVLTreeNode; +begin + Result:=TFPList.Create; + Node:=FTree.FindLowest; + while Node<>nil do + begin + Result.Add(Node.Data); + Node:=FTree.FindSuccessor(Node); + end; +end; +{$endif} + { TPAMessage } constructor TPAMessage.Create; @@ -342,7 +602,11 @@ begin raise Exception.Create(''); dec(FRefCount); if FRefCount=0 then + {$ifdef pas2js} + Destroy; + {$else} Free; + {$endif} end; { TPAOverrideList } @@ -417,21 +681,9 @@ end; { TPasAnalyzer } // inline -function TPasAnalyzer.FindNode(El: TPasElement): TAVLTreeNode; +function TPasAnalyzer.PAElementExists(El: TPasElement): boolean; begin - Result:=FUsedElements.FindKey(El,@CompareElementWithPAElement); -end; - -// inline -function TPasAnalyzer.FindPAElement(El: TPasElement): TPAElement; -var - Node: TAVLTreeNode; -begin - Node:=FindNode(El); - if Node=nil then - Result:=nil - else - Result:=TPAElement(Node.Data); + Result:=FUsedElements.ContainsKey(El); end; // inline @@ -443,33 +695,22 @@ begin UseType(aType,Mode); end; +// inline +function TPasAnalyzer.FindElement(El: TPasElement): TPAElement; +begin + Result:=TPAElement(FUsedElements.FindKey(El)); +end; + procedure TPasAnalyzer.SetOptions(AValue: TPasAnalyzerOptions); begin if FOptions=AValue then Exit; FOptions:=AValue; end; -function TPasAnalyzer.FindOverrideNode(El: TPasElement): TAVLTreeNode; -begin - Result:=FOverrideLists.FindKey(El,@CompareElementWithPAOverrideList); -end; - -function TPasAnalyzer.FindOverrideList(El: TPasElement): TPAOverrideList; -var - Node: TAVLTreeNode; -begin - Node:=FindOverrideNode(El); - if Node=nil then - Result:=nil - else - Result:=TPAOverrideList(Node.Data); -end; - function TPasAnalyzer.AddOverride(OverriddenEl, OverrideEl: TPasElement): boolean; // OverrideEl overrides OverriddenEl // returns true if new override var - Node: TAVLTreeNode; Item: TPAOverrideList; OverriddenPAEl: TPAElement; TypeEl: TPasType; @@ -477,16 +718,15 @@ begin {$IFDEF VerbosePasAnalyzer} writeln('TPasAnalyzer.AddOverride OverriddenEl=',GetElModName(OverriddenEl),' OverrideEl=',GetElModName(OverrideEl)); {$ENDIF} - Node:=FindOverrideNode(OverriddenEl); - if Node=nil then + Item:=TPAOverrideList(FOverrideLists.FindKey(OverriddenEl)); + if Item=nil then begin Item:=TPAOverrideList.Create; Item.Element:=OverriddenEl; - FOverrideLists.Add(Item); + FOverrideLists.Add(Item,false); end else begin - Item:=TPAOverrideList(Node.Data); if Item.IndexOf(OverrideEl)>=0 then exit(false); end; @@ -494,7 +734,7 @@ begin Item.Add(OverrideEl); Result:=true; - OverriddenPAEl:=FindPAElement(OverriddenEl); + OverriddenPAEl:=FindElement(OverriddenEl); if OverriddenPAEl<>nil then begin // OverriddenEl was already used -> use OverrideEl @@ -567,7 +807,7 @@ begin end; end; -procedure TPasAnalyzer.RaiseInconsistency(const Id: int64; Msg: string); +procedure TPasAnalyzer.RaiseInconsistency(const Id: TMaxPrecInt; Msg: string); begin {$IFDEF VerbosePasAnalyzer} writeln('TPasAnalyzer.RaiseInconsistency ['+IntToStr(Id)+']: '+Msg); @@ -575,7 +815,7 @@ begin raise EPasAnalyzer.Create('['+IntToStr(Id)+']: '+Msg); end; -procedure TPasAnalyzer.RaiseNotSupported(const Id: int64; El: TPasElement; +procedure TPasAnalyzer.RaiseNotSupported(const Id: TMaxPrecInt; El: TPasElement; const Msg: string); var s: String; @@ -626,9 +866,9 @@ begin if El=nil then RaiseInconsistency(20170308093407,''); {$IFDEF VerbosePasAnalyzer} - writeln('TPasAnalyzer.Add ',GetElModName(El),' New=',FindNode(El)=nil); + writeln('TPasAnalyzer.Add ',GetElModName(El),' New=',not PAElementExists(El)); {$ENDIF} - if CheckDuplicate and (FindNode(El)<>nil) then + if CheckDuplicate and PAElementExists(El) then RaiseInconsistency(20170304201318,''); if aClass=nil then aClass:=TPAElement; @@ -636,13 +876,18 @@ begin Result.Element:=El; FUsedElements.Add(Result); {$IFDEF VerbosePasAnalyzer} - //writeln('TPasAnalyzer.Add END ',GetElModName(El),' Success=',FindNode(El)<>nil,' ',ptruint(pointer(El))); + //writeln('TPasAnalyzer.Add END ',GetElModName(El),' Success=',PAElementExists(El),' ',ptruint(pointer(El))); {$ENDIF} end; procedure TPasAnalyzer.CreateTree; begin - FUsedElements:=TAVLTree.Create(@ComparePAElements); + FUsedElements:=TPasAnalyzerKeySet.Create( + {$ifdef pas2js} + @PAElement_ElToHashName,@PasElementToHashName + {$else} + @ComparePAElements,@CompareElementWithPAElement + {$endif}); end; function TPasAnalyzer.MarkElementAsUsed(El: TPasElement; aClass: TPAElementClass @@ -650,7 +895,7 @@ function TPasAnalyzer.MarkElementAsUsed(El: TPasElement; aClass: TPAElementClass function MarkModule(CurModule: TPasModule): boolean; begin - if FindNode(CurModule)<>nil then + if PAElementExists(CurModule) then exit(false); {$IFDEF VerbosePasAnalyzer} writeln('TPasAnalyzer.MarkElement.MarkModule mark "',GetElModName(CurModule),'"'); @@ -686,7 +931,7 @@ begin end; // mark element - if FindNode(El)<>nil then exit(false); + if PAElementExists(El) then exit(false); Add(El,false,aClass); Result:=true; @@ -705,9 +950,9 @@ function TPasAnalyzer.ElementVisited(El: TPasElement; Mode: TPAUseMode begin if El=nil then exit(true); - if FChecked[Mode].Find(El)<>nil then exit(true); + if FChecked[Mode].ContainsItem(El) then exit(true); Result:=false; - FChecked[Mode].Add(El); + FChecked[Mode].Add(El,false); end; procedure TPasAnalyzer.MarkImplScopeRef(El, RefEl: TPasElement; @@ -900,7 +1145,7 @@ procedure TPasAnalyzer.UseModule(aModule: TPasModule; Mode: TPAUseMode); UseScopeReferences(Scope.References); if (Scope.References=nil) and IsImplBlockEmpty(ImplBlock) then exit; // this module has an initialization section -> mark module - if FindNode(aModule)=nil then + if not PAElementExists(aModule) then Add(aModule); UseImplBlock(ImplBlock,true); end; @@ -936,7 +1181,7 @@ begin if Mode=paumElement then // e.g. a reference: unitname.identifier - if FindNode(aModule)=nil then + if not PAElementExists(aModule) then Add(aModule); end; @@ -979,7 +1224,7 @@ begin if IsImplBlockEmpty(UsedModule.InitializationSection) and IsImplBlockEmpty(UsedModule.FinalizationSection) then continue; - if FindNode(UsedModule)=nil then + if not PAElementExists(UsedModule) then Add(UsedModule); UseImplBlock(UsedModule.InitializationSection,true); UseImplBlock(UsedModule.FinalizationSection,true); @@ -1427,7 +1672,7 @@ procedure TPasAnalyzer.UseProcedure(Proc: TPasProcedure); i: Integer; OverrideProc: TPasProcedure; begin - OverrideList:=FindOverrideList(CurProc); + OverrideList:=TPAOverrideList(FOverrideLists.FindKey(CurProc)); if OverrideList=nil then exit; // Note: while traversing the OverrideList it may grow i:=0; @@ -1637,7 +1882,7 @@ procedure TPasAnalyzer.UseClassType(El: TPasClassType; Mode: TPAUseMode); i: Integer; Prop: TPasProperty; begin - OverrideList:=FindOverrideList(El); + OverrideList:=TPAOverrideList(FOverrideLists.FindKey(El)); if OverrideList=nil then exit; // Note: while traversing the OverrideList it may grow i:=0; @@ -2099,7 +2344,7 @@ begin begin UsedModule:=TPasModule(Use.Module); if CompareText(UsedModule.Name,'system')=0 then continue; - if FindNode(UsedModule)=nil then + if not PAElementExists(UsedModule) then EmitMessage(20170311191725,mtHint,nPAUnitNotUsed,sPAUnitNotUsed, [UsedModule.Name,aModule.Name],Use.Expr); end; @@ -2128,7 +2373,7 @@ begin EmitProcedureHints(TPasProcedure(Decl)) else begin - Usage:=FindPAElement(Decl); + Usage:=FindElement(Decl); if Usage=nil then begin // declaration was never used @@ -2149,7 +2394,7 @@ begin {$IFDEF VerbosePasAnalyzer} writeln('TPasAnalyzer.EmitTypeHints ',GetElModName(El)); {$ENDIF} - Usage:=FindPAElement(El); + Usage:=FindElement(El); if Usage=nil then begin // the whole type was never used @@ -2191,7 +2436,7 @@ begin {$IFDEF VerbosePasAnalyzer} writeln('TPasAnalyzer.EmitVariableHints ',GetElModName(El)); {$ENDIF} - Usage:=FindPAElement(El); + Usage:=FindElement(El); if Usage=nil then begin // not used @@ -2251,7 +2496,7 @@ begin ImplProc:=El else ImplProc:=ProcScope.ImplProc; - if FindNode(DeclProc)=nil then + if not PAElementExists(DeclProc) then begin // procedure never used if ProcScope.DeclarationProc=nil then @@ -2282,7 +2527,7 @@ begin for i:=0 to Args.Count-1 do begin Arg:=TPasArgument(Args[i]); - Usage:=FindPAElement(Arg); + Usage:=FindElement(Arg); if (Usage=nil) or (Usage.Access=paiaNone) then begin // parameter was never used @@ -2308,7 +2553,7 @@ begin PosEl:=TPasFunction(El).FuncType.ResultEl; if (ProcScope.ImplProc<>nil) and (TPasFunction(ProcScope.ImplProc).FuncType.ResultEl<>nil) then PosEl:=TPasFunction(ProcScope.ImplProc).FuncType.ResultEl; - Usage:=FindPAElement(TPasFunction(El).FuncType.ResultEl); + Usage:=FindElement(TPasFunction(El).FuncType.ResultEl); if (Usage=nil) or (Usage.Access in [paiaNone,paiaRead]) then // result was never used EmitMessage(20170313214038,mtHint,nPAFunctionResultDoesNotSeemToBeSet, @@ -2334,8 +2579,20 @@ var begin CreateTree; for m in TPAUseMode do - FChecked[m]:=TAVLTree.Create; - FOverrideLists:=TAVLTree.Create(@ComparePAOverrideLists); + FChecked[m]:=TPasAnalyzerKeySet.Create( + {$ifdef pas2js} + @PasElementToHashName + {$else} + @ComparePointer + {$endif} + ,nil + ); + FOverrideLists:=TPasAnalyzerKeySet.Create( + {$ifdef pas2js} + @PAOverrideList_ElToHashName,@PasElementToHashName + {$else} + @ComparePAOverrideLists,@CompareElementWithPAOverrideList + {$endif}); end; destructor TPasAnalyzer.Destroy; @@ -2354,8 +2611,8 @@ procedure TPasAnalyzer.Clear; var m: TPAUseMode; begin - FOverrideLists.FreeAndClear; - FUsedElements.FreeAndClear; + FOverrideLists.FreeItems; + FUsedElements.FreeItems; for m in TPAUseMode do FChecked[m].Clear; end; @@ -2418,17 +2675,6 @@ begin //EmitBlockHints(aModule.FinalizationSection); end; -function TPasAnalyzer.FindElement(El: TPasElement): TPAElement; -var - Node: TAVLTreeNode; -begin - Node:=FindNode(El); - if Node=nil then - Result:=nil - else - Result:=TPAElement(Node.Data); -end; - function TPasAnalyzer.FindUsedElement(El: TPasElement): TPAElement; var ProcScope: TPasProcedureScope; @@ -2450,7 +2696,7 @@ end; function TPasAnalyzer.IsTypeInfoUsed(El: TPasElement): boolean; begin - Result:=FChecked[paumTypeInfo].Find(El)<>nil; + Result:=FChecked[paumTypeInfo].ContainsItem(El); end; function TPasAnalyzer.IsModuleInternal(El: TPasElement): boolean; @@ -2497,8 +2743,9 @@ begin Result:=false; end; -procedure TPasAnalyzer.EmitMessage(Id: int64; MsgType: TMessageType; - MsgNumber: integer; Fmt: String; const Args: array of const; +procedure TPasAnalyzer.EmitMessage(Id: TMaxPrecInt; MsgType: TMessageType; + MsgNumber: integer; Fmt: String; + const Args: array of {$ifdef pas2js}jsvalue{$else}const{$endif}; PosEl: TPasElement); var Msg: TPAMessage; @@ -2617,16 +2864,8 @@ begin end; function TPasAnalyzer.GetUsedElements: TFPList; -var - Node: TAVLTreeNode; begin - Result:=TFPList.Create; - Node:=FUsedElements.FindLowest; - while Node<>nil do - begin - Result.Add(Node.Data); - Node:=FUsedElements.FindSuccessor(Node); - end; + Result:=FUsedElements.GetList; end; end.