mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 00:29:24 +02:00
fcl-passrc: fixed searching overload in mode delphi
This commit is contained in:
parent
49ad3b0d2c
commit
309d8a90fd
@ -1556,8 +1556,8 @@ type
|
|||||||
TFindCallElData = record
|
TFindCallElData = record
|
||||||
Params: TParamsExpr;
|
Params: TParamsExpr;
|
||||||
TemplCnt: integer;
|
TemplCnt: integer;
|
||||||
Found: TPasElement; // TPasProcedure or TPasUnresolvedSymbolRef(built in proc) or TPasType (typecast)
|
Found: TPasElement; // TPasProcedure or TPasUnresolvedSymbolRef(built in proc) or TPasType (typecast), best candidate so far
|
||||||
LastProc: TPasProcedure;
|
LastProc: TPasProcedure; // last checked TPasProcedure
|
||||||
ElScope, StartScope: TPasScope;
|
ElScope, StartScope: TPasScope;
|
||||||
Distance: integer; // compatibility distance
|
Distance: integer; // compatibility distance
|
||||||
Count: integer;
|
Count: integer;
|
||||||
@ -1595,7 +1595,7 @@ type
|
|||||||
procedure OnFindProcDeclaration(El: TPasElement; ElScope, StartScope: TPasScope;
|
procedure OnFindProcDeclaration(El: TPasElement; ElScope, StartScope: TPasScope;
|
||||||
FindProcData: Pointer; var Abort: boolean); virtual;
|
FindProcData: Pointer; var Abort: boolean); virtual;
|
||||||
function IsSameProcContext(ProcParentA, ProcParentB: TPasElement): boolean;
|
function IsSameProcContext(ProcParentA, ProcParentB: TPasElement): boolean;
|
||||||
function IsProcOverload(LastProc, LastExactProc, CurProc: TPasProcedure): boolean;
|
function IsProcOverloading(LastProc, CurProc: TPasProcedure): boolean;
|
||||||
function FindProcSameSignature(const ProcName: string; Proc: TPasProcedure;
|
function FindProcSameSignature(const ProcName: string; Proc: TPasProcedure;
|
||||||
Scope: TPasIdentifierScope; OnlyLocal: boolean): TPasProcedure;
|
Scope: TPasIdentifierScope; OnlyLocal: boolean): TPasProcedure;
|
||||||
protected
|
protected
|
||||||
@ -5018,7 +5018,7 @@ procedure TPasResolver.OnFindFirst_GenericEl(El: TPasElement; ElScope,
|
|||||||
var
|
var
|
||||||
Data: PPRFindGenericData absolute FindFirstGenericData;
|
Data: PPRFindGenericData absolute FindFirstGenericData;
|
||||||
GenericTemplateTypes: TFPList;
|
GenericTemplateTypes: TFPList;
|
||||||
Proc, LastExactProc: TPasProcedure;
|
Proc: TPasProcedure;
|
||||||
ProcScope: TPasProcedureScope;
|
ProcScope: TPasProcedureScope;
|
||||||
begin
|
begin
|
||||||
Proc:=nil;
|
Proc:=nil;
|
||||||
@ -5037,11 +5037,7 @@ begin
|
|||||||
|
|
||||||
if (Data^.LastProc<>nil) then
|
if (Data^.LastProc<>nil) then
|
||||||
begin
|
begin
|
||||||
if Data^.Find.Found is TPasProcedure then
|
if not IsProcOverloading(Data^.LastProc,Proc) then
|
||||||
LastExactProc:=TPasProcedure(Data^.Find.Found)
|
|
||||||
else
|
|
||||||
LastExactProc:=nil;
|
|
||||||
if not IsProcOverload(Data^.LastProc,LastExactProc,Proc) then
|
|
||||||
begin
|
begin
|
||||||
Abort:=true;
|
Abort:=true;
|
||||||
exit;
|
exit;
|
||||||
@ -5126,11 +5122,40 @@ begin
|
|||||||
El:=Proc;
|
El:=Proc;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if (msDelphi in ProcScope.ModeSwitches) and not IsProcOverload(Proc) then
|
||||||
|
begin
|
||||||
|
Abort:=true; // stop searching after this proc
|
||||||
|
if Data^.LastProc<>nil then
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (Data^.LastProc<>nil) then
|
||||||
|
begin
|
||||||
|
if (TPasProcedureScope(Data^.LastProc.CustomData).OverriddenProc=Proc) then
|
||||||
|
begin
|
||||||
|
// already checked the override -> skip
|
||||||
|
Data^.LastProc:=Proc;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if not IsProcOverloading(Data^.LastProc,Proc) then
|
||||||
|
begin
|
||||||
|
Abort:=true;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
if Data^.Found is TPasProcedure then
|
if Data^.Found is TPasProcedure then
|
||||||
begin
|
begin
|
||||||
// there is already a previous proc
|
// there is already a previous proc
|
||||||
PrevProc:=TPasProcedure(Data^.Found);
|
PrevProc:=TPasProcedure(Data^.Found);
|
||||||
|
|
||||||
|
if (TPasProcedureScope(PrevProc.CustomData).OverriddenProc=Proc) then
|
||||||
|
begin
|
||||||
|
// already checked the override -> skip
|
||||||
|
Data^.LastProc:=Proc;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
if (Data^.Distance=cExact) and (PrevProc.Parent<>Proc.Parent)
|
if (Data^.Distance=cExact) and (PrevProc.Parent<>Proc.Parent)
|
||||||
and (PrevProc.Parent.ClassType=TPasClassType) then
|
and (PrevProc.Parent.ClassType=TPasClassType) then
|
||||||
begin
|
begin
|
||||||
@ -5138,18 +5163,8 @@ begin
|
|||||||
Abort:=true;
|
Abort:=true;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not IsProcOverload(Data^.LastProc,PrevProc,Proc) then
|
|
||||||
begin
|
|
||||||
Abort:=true;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if (msDelphi in ProcScope.ModeSwitches) and not IsProcOverload(Proc) then
|
|
||||||
Abort:=true; // stop searching after this proc
|
|
||||||
|
|
||||||
CandidateFound:=true;
|
CandidateFound:=true;
|
||||||
if Data^.TemplCnt>0 then
|
if Data^.TemplCnt>0 then
|
||||||
begin
|
begin
|
||||||
@ -5639,8 +5654,8 @@ begin
|
|||||||
Result:=false;
|
Result:=false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPasResolver.IsProcOverload(LastProc, LastExactProc,
|
function TPasResolver.IsProcOverloading(LastProc, CurProc: TPasProcedure
|
||||||
CurProc: TPasProcedure): boolean;
|
): boolean;
|
||||||
begin
|
begin
|
||||||
if msDelphi in TPasProcedureScope(LastProc.CustomData).ModeSwitches then
|
if msDelphi in TPasProcedureScope(LastProc.CustomData).ModeSwitches then
|
||||||
begin
|
begin
|
||||||
@ -5660,13 +5675,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// check if previous found proc is override of found proc
|
|
||||||
if (LastExactProc<>nil) and IsProcOverride(CurProc,LastExactProc) then
|
|
||||||
begin
|
|
||||||
// previous found proc is override of found proc -> skip
|
|
||||||
exit(false);
|
|
||||||
end;
|
|
||||||
|
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -431,6 +431,7 @@ type
|
|||||||
Procedure TestProcOverloadObjFPCUnitWithoutOverloadMod;
|
Procedure TestProcOverloadObjFPCUnitWithoutOverloadMod;
|
||||||
Procedure TestProcOverloadDelphiWithObjFPC;
|
Procedure TestProcOverloadDelphiWithObjFPC;
|
||||||
Procedure TestProcOverloadDelphiOverride;
|
Procedure TestProcOverloadDelphiOverride;
|
||||||
|
Procedure TestProcOverloadDelphiOverrideOne;
|
||||||
Procedure TestProcDuplicate;
|
Procedure TestProcDuplicate;
|
||||||
Procedure TestNestedProc;
|
Procedure TestNestedProc;
|
||||||
Procedure TestNestedProc_ResultString;
|
Procedure TestNestedProc_ResultString;
|
||||||
@ -7085,6 +7086,45 @@ begin
|
|||||||
ParseProgram;
|
ParseProgram;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolver.TestProcOverloadDelphiOverrideOne;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'{$mode delphi}',
|
||||||
|
'type',
|
||||||
|
' TObject = class',
|
||||||
|
' constructor Create(b: boolean); virtual;',
|
||||||
|
' end;',
|
||||||
|
' TBird = class',
|
||||||
|
' // add first an overload',
|
||||||
|
' constructor Create(w: word); overload;',
|
||||||
|
' // and then override the previous',
|
||||||
|
' constructor Create(b: boolean); override; overload;',
|
||||||
|
' end;',
|
||||||
|
' TEagle = class(TBird)',
|
||||||
|
' constructor Create(b: boolean); override; overload;',
|
||||||
|
' end;',
|
||||||
|
'constructor TObject.Create(b: boolean);',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'constructor TBird.Create(w: word);',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'constructor TBird.Create(b: boolean);',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'constructor TEagle.Create(b: boolean);',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
|
' TBird.Create(false);',
|
||||||
|
' TBird.Create(2);',
|
||||||
|
' TEagle.Create(true);',
|
||||||
|
' TEagle.Create(3);',
|
||||||
|
'']);
|
||||||
|
ParseProgram;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestResolver.TestProcDuplicate;
|
procedure TTestResolver.TestProcDuplicate;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user