fcl-passrc: adapt pasuseanalyzer for pas2js

git-svn-id: trunk@40013 -
This commit is contained in:
Mattias Gaertner 2018-10-22 10:39:43 +00:00
parent 9bd931e931
commit ce4ccfc0aa
2 changed files with 353 additions and 103 deletions

View File

@ -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}

View File

@ -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.