codetools: fixed stop/continue searching for overload procs, bug #8632

git-svn-id: trunk@15270 -
This commit is contained in:
mattias 2008-05-28 12:47:36 +00:00
parent bd9d58aa42
commit 6db258bc44
2 changed files with 73 additions and 41 deletions

View File

@ -206,7 +206,7 @@ type
out Caret:TCodeXYPosition): boolean; // true=ok, false=invalid CleanPos out Caret:TCodeXYPosition): boolean; // true=ok, false=invalid CleanPos
function CleanPosToCaretAndTopLine(CleanPos: integer; function CleanPosToCaretAndTopLine(CleanPos: integer;
out Caret:TCodeXYPosition; out NewTopLine: integer): boolean; // true=ok, false=invalid CleanPos out Caret:TCodeXYPosition; out NewTopLine: integer): boolean; // true=ok, false=invalid CleanPos
function CleanPosToStr(CleanPos: integer): string; function CleanPosToStr(CleanPos: integer; WithFilename: boolean = false): string;
procedure GetCleanPosInfo(CodePosInFront, CleanPos: integer; procedure GetCleanPosInfo(CodePosInFront, CleanPos: integer;
ResolveComments: boolean; out SameArea: TAtomPosition); ResolveComments: boolean; out SameArea: TAtomPosition);
procedure GetLineInfo(ACleanPos: integer; procedure GetLineInfo(ACleanPos: integer;
@ -2219,13 +2219,17 @@ begin
end; end;
end; end;
function TCustomCodeTool.CleanPosToStr(CleanPos: integer): string; function TCustomCodeTool.CleanPosToStr(CleanPos: integer;
WithFilename: boolean): string;
var var
CodePos: TCodeXYPosition; CodePos: TCodeXYPosition;
begin begin
if CleanPosToCaret(CleanPos,CodePos) then if CleanPosToCaret(CleanPos,CodePos) then begin
Result:='y='+IntToStr(CodePos.Y)+',x='+IntToStr(CodePos.X) if WithFilename then
else Result:=CodePos.Code.Filename+',y='+IntToStr(CodePos.Y)+',x='+IntToStr(CodePos.X)
else
Result:='y='+IntToStr(CodePos.Y)+',x='+IntToStr(CodePos.X);
end else
Result:='y=?,x=?'; Result:='y=?,x=?';
end; end;

View File

@ -497,6 +497,7 @@ type
procedure ChangeFoundProc(const ProcContext: TFindContext; procedure ChangeFoundProc(const ProcContext: TFindContext;
ProcCompatibility: TTypeCompatibility; ProcCompatibility: TTypeCompatibility;
ParamCompatibilityList: TTypeCompatibilityList); ParamCompatibilityList: TTypeCompatibilityList);
function IsFinal: boolean;
procedure PrettifyResult; procedure PrettifyResult;
procedure ConvertResultCleanPosToCaretPos; procedure ConvertResultCleanPosToCaretPos;
procedure ClearResult(CopyCacheFlags: boolean); procedure ClearResult(CopyCacheFlags: boolean);
@ -2274,7 +2275,7 @@ var
FindIdentifierInContext:=NewResult; FindIdentifierInContext:=NewResult;
{$IFDEF ShowCollect} {$IFDEF ShowCollect}
if fdfCollect in Params.Flags then begin if fdfCollect in Params.Flags then begin
DebugLn('[TFindDeclarationTool.FindIdentifierInContext] COLLECT CheckResult Ident=', DebugLn('[TFindDeclarationTool.FindIdentifierInContext.CheckResult] COLLECT CheckResult Ident=',
'"',GetIdentifier(Params.Identifier),'"', '"',GetIdentifier(Params.Identifier),'"',
' File="',ExtractFilename(MainFilename)+'"', ' File="',ExtractFilename(MainFilename)+'"',
' Flags=[',FindDeclarationFlagsAsString(Params.Flags)+']', ' Flags=[',FindDeclarationFlagsAsString(Params.Flags)+']',
@ -2286,7 +2287,7 @@ var
// identifier found // identifier found
if CallOnIdentifierFound then begin if CallOnIdentifierFound then begin
{ {
debugln('[TFindDeclarationTool.FindIdentifierInContext] CallOnIdentifierFound Ident=', debugln('[TFindDeclarationTool.FindIdentifierInContext.CheckResult] CallOnIdentifierFound Ident=',
'"',GetIdentifier(Params.Identifier),'"', '"',GetIdentifier(Params.Identifier),'"',
' StartContext="',StartContextNode.DescAsString,'" "',copy(Src,StartContextNode.StartPos,20),'"', ' StartContext="',StartContextNode.DescAsString,'" "',copy(Src,StartContextNode.StartPos,20),'"',
' File="',ExtractFilename(MainFilename)+'"', ' File="',ExtractFilename(MainFilename)+'"',
@ -2295,6 +2296,9 @@ var
} }
IdentFoundResult:=Params.NewCodeTool.DoOnIdentifierFound(Params, IdentFoundResult:=Params.NewCodeTool.DoOnIdentifierFound(Params,
Params.NewNode); Params.NewNode);
{$IFDEF ShowProcSearch}
DebugLn(['[TFindDeclarationTool.FindIdentifierInContext.CheckResult] DoOnIdentifierFound=',IdentifierFoundResultNames[IdentFoundResult]]);
{$ENDIF}
if (IdentFoundResult=ifrSuccess) then if (IdentFoundResult=ifrSuccess) then
CacheResult(true,ContextNode); CacheResult(true,ContextNode);
Result:=IdentFoundResult<>ifrProceedSearch; Result:=IdentFoundResult<>ifrProceedSearch;
@ -2307,14 +2311,20 @@ var
end; end;
end; end;
if Params.FoundProc<>nil then begin if Params.FoundProc<>nil then begin
// there was a proc, only the search for the overloaded proc was // there was a proc,
// unsuccessful // either the search for the overloaded proc was unsuccessful
// or the searched proc was found in a recursive sub search
// -> return the found proc // -> return the found proc
if Params.FoundProc^.CacheValid
and (Params.FoundProc^.ProcCompatibility=tcExact) then begin
// stop the search
Result:=true;
end;
FindIdentifierInContext:=true;
Params.SetResult(Params.FoundProc^.Context.Tool, Params.SetResult(Params.FoundProc^.Context.Tool,
Params.FoundProc^.Context.Node); Params.FoundProc^.Context.Node);
FindIdentifierInContext:=true;
{$IFDEF ShowProcSearch} {$IFDEF ShowProcSearch}
DebugLn('[TFindDeclarationTool.FindIdentifierInContext] PROC Search ended with only one proc:'); DebugLn('[TFindDeclarationTool.FindIdentifierInContext] PROC Search ended with only one proc (normal when searching every used unit):');
Params.WriteDebugReport; Params.WriteDebugReport;
{$ENDIF} {$ENDIF}
exit; exit;
@ -2733,8 +2743,15 @@ begin
IdentifierFoundResult:= IdentifierFoundResult:=
FindIdentifierInProcContext(ContextNode,Params); FindIdentifierInProcContext(ContextNode,Params);
if IdentifierFoundResult in [ifrAbortSearch,ifrSuccess] then begin if IdentifierFoundResult in [ifrAbortSearch,ifrSuccess] then begin
if CheckResult(IdentifierFoundResult=ifrSuccess,true) then if CheckResult(IdentifierFoundResult=ifrSuccess,true) then begin
{$IFDEF ShowProcSearch}
DebugLn(['TFindDeclarationTool.FindIdentifierInContext ctnProcedure FOUND, stopping']);
{$ENDIF}
exit; exit;
end;
{$IFDEF ShowProcSearch}
DebugLn(['TFindDeclarationTool.FindIdentifierInContext ctnProcedure FOUND, continue']);
{$ENDIF}
end; end;
end; end;
@ -4054,6 +4071,7 @@ begin
if ((fdfCollect in Params.Flags) if ((fdfCollect in Params.Flags)
or CompareSrcIdentifiers(NameAtom.StartPos,Params.Identifier)) then begin or CompareSrcIdentifiers(NameAtom.StartPos,Params.Identifier)) then begin
// proc identifier found // proc identifier found
// the parameters will be checked by the caller
{$IFDEF ShowTriedContexts} {$IFDEF ShowTriedContexts}
DebugLn('[TFindDeclarationTool.FindIdentifierInProcContext] Proc-Identifier found="',GetIdentifier(Params.Identifier),'"'); DebugLn('[TFindDeclarationTool.FindIdentifierInProcContext] Proc-Identifier found="',GetIdentifier(Params.Identifier),'"');
{$ENDIF} {$ENDIF}
@ -4124,8 +4142,7 @@ begin
{$ENDIF} {$ENDIF}
Result:=ClassContext.Tool.FindIdentifierInContext(Params); Result:=ClassContext.Tool.FindIdentifierInContext(Params);
Params.Load(OldInput,true); Params.Load(OldInput,true);
if Result then if Result and Params.IsFinal then exit;
exit;
end; end;
end else begin end else begin
// proc is not a method // proc is not a method
@ -4649,7 +4666,7 @@ begin
-[fdfExceptionOnNotFound]; -[fdfExceptionOnNotFound];
Result:=NewCodeTool.FindIdentifierInInterface(Self,Params); Result:=NewCodeTool.FindIdentifierInInterface(Self,Params);
Params.Flags:=OldFlags; Params.Flags:=OldFlags;
if Result then exit; if Result and Params.IsFinal then exit;
// restore the cursor // restore the cursor
MoveCursorToCleanPos(UnitNameAtom.StartPos); MoveCursorToCleanPos(UnitNameAtom.StartPos);
end; end;
@ -4788,13 +4805,11 @@ begin
Result:=FindIdentifierInContext(Params); Result:=FindIdentifierInContext(Params);
Params.Load(OldInput,true); Params.Load(OldInput,true);
if (Params.NewCodeTool<>Self) then Result:=false;
// save result in cache // save result in cache
if Params.Flags*[fdfCollect,fdfDoNotCache]=[] then begin if Params.Flags*[fdfCollect,fdfDoNotCache]=[] then begin
if FInterfaceIdentifierCache=nil then if FInterfaceIdentifierCache=nil then
FInterfaceIdentifierCache:=TInterfaceIdentifierCache.Create(Self); FInterfaceIdentifierCache:=TInterfaceIdentifierCache.Create(Self);
if Result then begin if Result and (Params.NewCodeTool=Self) then begin
// identifier exists in interface // identifier exists in interface
if (Params.NewNode<>nil) and (Params.NewNode.Desc=ctnProcedure) then begin if (Params.NewNode<>nil) and (Params.NewNode.Desc=ctnProcedure) then begin
//DebugLn('NOTE: TFindDeclarationTool.FindIdentifierInInterface Node is proc'); //DebugLn('NOTE: TFindDeclarationTool.FindIdentifierInInterface Node is proc');
@ -4804,7 +4819,7 @@ begin
FInterfaceIdentifierCache.Add(OldInput.Identifier,Params.NewNode, FInterfaceIdentifierCache.Add(OldInput.Identifier,Params.NewNode,
Params.NewCleanPos); Params.NewCleanPos);
end; end;
end else begin end else if not Result then begin
// identifier does not exist in this interface // identifier does not exist in this interface
FInterfaceIdentifierCache.Add(OldInput.Identifier,nil,-1); FInterfaceIdentifierCache.Add(OldInput.Identifier,nil,-1);
end; end;
@ -5010,35 +5025,35 @@ begin
then begin then begin
// try hidden used unit 'systhrds' // try hidden used unit 'systhrds'
Result:=FindIdentifierInUsedUnit('SysThrds',Params); Result:=FindIdentifierInUsedUnit('SysThrds',Params);
if Result then exit; if Result and Params.IsFinal then exit;
end; end;
if (CurUnitType>sutHeapTrc) if (CurUnitType>sutHeapTrc)
and Scanner.InitialValues.IsDefined(ExternalMacroStart+'UseHeapTrcUnit') and Scanner.InitialValues.IsDefined(ExternalMacroStart+'UseHeapTrcUnit')
then begin then begin
// try hidden used unit 'heaptrc' // try hidden used unit 'heaptrc'
Result:=FindIdentifierInUsedUnit('HeapTrc',Params); Result:=FindIdentifierInUsedUnit('HeapTrc',Params);
if Result then exit; if Result and Params.IsFinal then exit;
end; end;
if (CurUnitType>sutLineInfo) if (CurUnitType>sutLineInfo)
and Scanner.InitialValues.IsDefined(ExternalMacroStart+'UseLineInfo') and Scanner.InitialValues.IsDefined(ExternalMacroStart+'UseLineInfo')
then begin then begin
// try hidden used unit 'lineinfo' // try hidden used unit 'lineinfo'
Result:=FindIdentifierInUsedUnit('LineInfo',Params); Result:=FindIdentifierInUsedUnit('LineInfo',Params);
if Result then exit; if Result and Params.IsFinal then exit;
end; end;
if (CurUnitType>sutObjPas) if (CurUnitType>sutObjPas)
and (Scanner.CompilerMode in [cmDELPHI,cmOBJFPC]) and (Scanner.CompilerMode in [cmDELPHI,cmOBJFPC])
and (Scanner.PascalCompiler=pcFPC) then begin and (Scanner.PascalCompiler=pcFPC) then begin
// try hidden used fpc unit 'objpas' // try hidden used fpc unit 'objpas'
Result:=FindIdentifierInUsedUnit('ObjPas',Params); Result:=FindIdentifierInUsedUnit('ObjPas',Params);
if Result then exit; if Result and Params.IsFinal then exit;
end; end;
if (CurUnitType>sutMacPas) if (CurUnitType>sutMacPas)
and (Scanner.CompilerMode=cmMacPas) and (Scanner.CompilerMode=cmMacPas)
and (Scanner.PascalCompiler=pcFPC) then begin and (Scanner.PascalCompiler=pcFPC) then begin
// try hidden used fpc unit 'macpas' // try hidden used fpc unit 'macpas'
Result:=FindIdentifierInUsedUnit('MacPas',Params); Result:=FindIdentifierInUsedUnit('MacPas',Params);
if Result then exit; if Result and Params.IsFinal then exit;
end; end;
if (CurUnitType>sutSystem) then begin if (CurUnitType>sutSystem) then begin
// try hidden used unit 'system' // try hidden used unit 'system'
@ -5053,7 +5068,7 @@ begin
Params.Load(OldInput,true); Params.Load(OldInput,true);
end; end;
end; end;
if Result then exit; if Result and Params.IsFinal then exit;
end; end;
end; end;
@ -6579,9 +6594,10 @@ begin
if (Params.FoundProc=nil) then begin if (Params.FoundProc=nil) then begin
// this is the first proc found // this is the first proc found
// -> save it and proceed the search to find all overloadeded procs // -> save it and proceed the search to find all overloadeded procs
{$IFDEF ShowFoundIdentifier} {$IF defined(ShowFoundIdentifier) or defined(ShowProcSearch)}
DebugLn('[TFindDeclarationTool.CheckSrcIdentifier]', DebugLn('[TFindDeclarationTool.CheckSrcIdentifier]',
' Ident=',GetIdentifier(Params.Identifier), ' Ident=',GetIdentifier(Params.Identifier),
' ',FoundContext.Tool.CleanPosToStr(FoundContext.Node.StartPos),
' FIRST PROC' ' FIRST PROC'
); );
{$ENDIF} {$ENDIF}
@ -6593,7 +6609,7 @@ begin
// create the input expression list // create the input expression list
// (the expressions in the brackets are parsed and converted to types) // (the expressions in the brackets are parsed and converted to types)
if Params.FoundProc^.ExprInputList=nil then begin if Params.FoundProc^.ExprInputList=nil then begin
{$IFDEF ShowFoundIdentifier} {$IF defined(ShowFoundIdentifier) or defined(ShowProcSearch)}
DebugLn('[TFindDeclarationTool.CheckSrcIdentifier]', DebugLn('[TFindDeclarationTool.CheckSrcIdentifier]',
' Ident=',GetIdentifier(Params.Identifier), ' Ident=',GetIdentifier(Params.Identifier),
' Creating Input Expression List ...' ' Creating Input Expression List ...'
@ -6661,7 +6677,7 @@ begin
// check the first found proc for compatibility // check the first found proc for compatibility
// (compare the expression list with the proc param list) // (compare the expression list with the proc param list)
if not Params.FoundProc^.CacheValid then begin if not Params.FoundProc^.CacheValid then begin
{$IFDEF ShowFoundIdentifier} {$IF defined(ShowFoundIdentifier) or defined(ShowProcSearch)}
DebugLn('[TFindDeclarationTool.CheckSrcIdentifier]', DebugLn('[TFindDeclarationTool.CheckSrcIdentifier]',
' Ident=',GetIdentifier(Params.Identifier), ' Ident=',GetIdentifier(Params.Identifier),
' Check the first found proc for compatibility ...' ' Check the first found proc for compatibility ...'
@ -6677,24 +6693,27 @@ begin
Params,Params.FoundProc^.ParamCompatibilityList); Params,Params.FoundProc^.ParamCompatibilityList);
Params.FoundProc^.ProcCompatibility:=ParamCompatibility; Params.FoundProc^.ProcCompatibility:=ParamCompatibility;
Params.FoundProc^.CacheValid:=true; Params.FoundProc^.CacheValid:=true;
{$IFDEF ShowFoundIdentifier}
DebugLn('[TFindDeclarationTool.CheckSrcIdentifier]',
' Ident=',GetIdentifier(Params.Identifier),
' First Proc ParamCompatibility=',TypeCompatibilityNames[ParamCompatibility]
);
{$ENDIF}
if ParamCompatibility=tcExact then begin if ParamCompatibility=tcExact then begin
// the first proc fits exactly -> stop the search
Params.SetResult(Params.FoundProc^.Context.Tool, Params.SetResult(Params.FoundProc^.Context.Tool,
Params.FoundProc^.Context.Node.FirstChild); Params.FoundProc^.Context.Node.FirstChild);
Result:=ifrSuccess;
exit;
end; end;
end; end;
if Params.FoundProc^.ProcCompatibility=tcExact then begin
{$IF defined(ShowFoundIdentifier) or defined(ShowProcSearch)}
DebugLn('[TFindDeclarationTool.CheckSrcIdentifier]',
' Ident=',GetIdentifier(Params.Identifier),
' First Proc ParamCompatibility=',TypeCompatibilityNames[Params.FoundProc^.ProcCompatibility]
);
{$ENDIF}
// the first proc fits exactly -> stop the search
Result:=ifrSuccess;
exit;
end;
// check the current proc for compatibility // check the current proc for compatibility
// (compare the expression list with the proc param list) // (compare the expression list with the proc param list)
{$IFDEF ShowFoundIdentifier} {$IF defined(ShowFoundIdentifier) or defined(ShowProcSearch)}
DebugLn('[TFindDeclarationTool.CheckSrcIdentifier]', DebugLn('[TFindDeclarationTool.CheckSrcIdentifier]',
' Ident=',GetIdentifier(Params.Identifier), ' Ident=',GetIdentifier(Params.Identifier),
' Check the current found proc for compatibility ...' ' Check the current found proc for compatibility ...'
@ -6715,7 +6734,7 @@ begin
Params.FoundProc^.ExprInputList, Params.FoundProc^.ExprInputList,
fdfIgnoreMissingParams in Params.Flags, fdfIgnoreMissingParams in Params.Flags,
Params,CurCompatibilityList); Params,CurCompatibilityList);
{$IFDEF ShowFoundIdentifier} {$IF defined(ShowFoundIdentifier) or defined(ShowProcSearch)}
DebugLn('[TFindDeclarationTool.CheckSrcIdentifier]', DebugLn('[TFindDeclarationTool.CheckSrcIdentifier]',
' Ident=',GetIdentifier(Params.Identifier), ' Ident=',GetIdentifier(Params.Identifier),
' Current Proc ParamCompatibility=',TypeCompatibilityNames[ParamCompatibility] ' Current Proc ParamCompatibility=',TypeCompatibilityNames[ParamCompatibility]
@ -8210,7 +8229,10 @@ begin
else else
DebugLn(' IdentifierTool=nil'); DebugLn(' IdentifierTool=nil');
if FoundProc<>nil then begin if FoundProc<>nil then begin
DebugLn(' FoundProc<>nil'); if FoundProc^.Context.Node<>nil then
DebugLn(' FoundProc=',FoundProc^.Context.Tool.CleanPosToStr(FoundProc^.Context.Node.StartPos,true))
else
DebugLn(' FoundProc<>nil');
end; end;
// global params // global params
@ -8273,6 +8295,12 @@ begin
end; end;
end; end;
function TFindDeclarationParams.IsFinal: boolean;
begin
Result:=(FoundProc=nil)
or (FoundProc^.CacheValid and (FoundProc^.ProcCompatibility=tcExact));
end;
procedure TFindDeclarationParams.PrettifyResult; procedure TFindDeclarationParams.PrettifyResult;
begin begin
// adjust result for nicer position // adjust result for nicer position