codetools: BuildTree: check if last error was in implementation and only interface is needed, bug #16867

git-svn-id: trunk@26551 -
This commit is contained in:
mattias 2010-07-09 20:18:28 +00:00
parent 6b96372e72
commit 1e473ef5c9
4 changed files with 95 additions and 67 deletions

View File

@ -31,6 +31,8 @@
{off $DEFINE CTDEBUG}
{off $DEFINE VerboseUpdateNeeded}
{$inline on}
// end.

View File

@ -1034,8 +1034,8 @@ var
begin
try
Result:=false;
BuildTree(false);
if not EndOfSourceFound then exit;
ClearIgnoreErrorAfter;
BuildTree(true);
UpperClassName:=UpperCaseStr(AComponent.ClassName);
{$IFDEF CTDEBUG}
DebugLn('[TEventsCodeTool.CompleteComponent] A Component="',AComponent.Name,':',AComponent.ClassName);
@ -1064,7 +1064,7 @@ begin
{$IFDEF CTDEBUG}
DebugLn('[TEventsCodeTool.CompleteComponent] invoke class completion');
{$ENDIF}
Result:=ApplyClassCompletion(true);
Result:=ApplyClassCompletion(false);
{$IFDEF CTDEBUG}
DebugLn('[TEventsCodeTool.CompleteComponent] END');
{$ENDIF}

View File

@ -36,6 +36,7 @@ interface
{$I codetools.inc}
{ $DEFINE ShowIgnoreErrorAfter}
{ $DEFINE VerboseUpdateNeeded}
uses
{$IFDEF MEM_CHECK}
@ -241,7 +242,15 @@ type
function FindFirstNodeOnSameLvl(StartNode: TCodeTreeNode): TCodeTreeNode;
function FindNextNodeOnSameLvl(StartNode: TCodeTreeNode): TCodeTreeNode;
function FindPrevNodeOnSameLvl(StartNode: TCodeTreeNode): TCodeTreeNode;
// sections
function FindInterfaceNode: TCodeTreeNode;
function FindImplementationNode: TCodeTreeNode;
function FindInitializationNode: TCodeTreeNode;
function FindFinalizationNode: TCodeTreeNode;
function FindMainBeginEndNode: TCodeTreeNode;
function FindFirstSectionChild: TCodeTreeNode;
function NodeHasParentOfType(ANode: TCodeTreeNode;
NodeDesc: TCodeTreeNodeDesc): boolean;
@ -552,21 +561,39 @@ end;
procedure TPascalParserTool.BuildTree(OnlyInterfaceNeeded: boolean);
var
SourceType: TCodeTreeNodeDesc;
Node: TCodeTreeNode;
begin
{$IFDEF MEM_CHECK}CheckHeap('TBasicCodeTool.BuildTree A '+IntToStr(MemCheck_GetMem_Cnt));{$ENDIF}
{$IFDEF CTDEBUG}
DebugLn('TPascalParserTool.BuildTree A ',MainFilename);
{$ENDIF}
ValidateToolDependencies;
debugln(['TPascalParserTool.BuildTree ']);
if not UpdateNeeded(OnlyInterfaceNeeded) then begin
// input is the same as last time -> output is the same
// -> if there was an error, raise it again
// => if there was an error, raise it again
//debugln(['TPascalParserTool.BuildTree ',ord(LastErrorPhase),' ',IgnoreErrorAfterValid]);
if (LastErrorPhase in [CodeToolPhaseScan,CodeToolPhaseParse])
and ((not IgnoreErrorAfterValid)
or (not IgnoreErrorAfterPositionIsInFrontOfLastErrMessage))
then
if (LastErrorPhase in [CodeToolPhaseScan,CodeToolPhaseParse]) then begin
// last time a parsing error occurred
if IgnoreErrorAfterValid
and IgnoreErrorAfterPositionIsInFrontOfLastErrMessage
then begin
// last error is behind needed code
// => ignore
exit;
end;
//debugln(['TPascalParserTool.BuildTree ',MainFilename,' OnlyInterfaceNeeded=',OnlyInterfaceNeeded,' ImplementationSectionFound=',ImplementationSectionFound]);
if OnlyInterfaceNeeded and ImplementationSectionFound then begin
Node:=FindImplementationNode;
if (Node<>nil) and not LastErrorIsInFrontOfCleanedPos(Node.StartPos)
then begin
// last error was after interface section and only interface is needed
// => ignore
exit;
end;
end;
RaiseLastError;
end;
exit;
end;
ClearLastError;
@ -575,6 +602,11 @@ begin
// scan code
BeginParsing(true,OnlyInterfaceNeeded);
{$IFDEF VerboseUpdateNeeded}
if FForceUpdateNeeded=true then
DebugLn(['TCustomCodeTool.BuildTree FForceUpdateNeeded:=false ',MainFilename]);
{$ENDIF}
FForceUpdateNeeded:=false;
// parse code and build codetree
CurrentPhase:=CodeToolPhaseParse;
@ -4987,6 +5019,58 @@ begin
end;
end;
function TPascalParserTool.FindInterfaceNode: TCodeTreeNode;
begin
Result:=Tree.Root;
while (Result<>nil) and (Result.Desc<>ctnInterface) do
Result:=Result.NextBrother;
end;
function TPascalParserTool.FindImplementationNode: TCodeTreeNode;
begin
Result:=Tree.Root;
while (Result<>nil) and (Result.Desc<>ctnImplementation) do
Result:=Result.NextBrother;
end;
function TPascalParserTool.FindInitializationNode: TCodeTreeNode;
begin
Result:=Tree.Root;
while (Result<>nil) and (Result.Desc<>ctnInitialization) do
Result:=Result.NextBrother;
end;
function TPascalParserTool.FindFinalizationNode: TCodeTreeNode;
begin
Result:=Tree.Root;
while (Result<>nil) and (Result.Desc<>ctnFinalization) do
Result:=Result.NextBrother;
end;
function TPascalParserTool.FindMainBeginEndNode: TCodeTreeNode;
begin
Result:=Tree.Root;
if (Result=nil) then exit;
if (Result.Desc in [ctnProgram,ctnLibrary]) then
Result:=Result.LastChild
else begin
Result:=FindImplementationNode;
if Result<>nil then
Result:=Result.LastChild;
end;
if Result=nil then exit;
if Result.Desc<>ctnBeginBlock then Result:=nil;
end;
function TPascalParserTool.FindFirstSectionChild: TCodeTreeNode;
begin
Result:=Tree.Root;
while (Result<>nil) and (Result.FirstChild=nil) do
Result:=Result.NextBrother;
if (Result=nil) then exit;
Result:=Result.FirstChild;
end;
end.

View File

@ -185,12 +185,6 @@ type
function GetSourceNamePos(var NamePos: TAtomPosition): boolean;
function PositionInSourceName(CleanPos: integer): boolean;
function ExtractSourceName: string;
function FindInterfaceNode: TCodeTreeNode;
function FindImplementationNode: TCodeTreeNode;
function FindInitializationNode: TCodeTreeNode;
function FindFinalizationNode: TCodeTreeNode;
function FindMainBeginEndNode: TCodeTreeNode;
function FindFirstSectionChild: TCodeTreeNode;
// uses sections
procedure MoveCursorToUsesStart(UsesNode: TCodeTreeNode);
@ -1672,58 +1666,6 @@ begin
Result:='';
end;
function TPascalReaderTool.FindInterfaceNode: TCodeTreeNode;
begin
Result:=Tree.Root;
while (Result<>nil) and (Result.Desc<>ctnInterface) do
Result:=Result.NextBrother;
end;
function TPascalReaderTool.FindImplementationNode: TCodeTreeNode;
begin
Result:=Tree.Root;
while (Result<>nil) and (Result.Desc<>ctnImplementation) do
Result:=Result.NextBrother;
end;
function TPascalReaderTool.FindInitializationNode: TCodeTreeNode;
begin
Result:=Tree.Root;
while (Result<>nil) and (Result.Desc<>ctnInitialization) do
Result:=Result.NextBrother;
end;
function TPascalReaderTool.FindFinalizationNode: TCodeTreeNode;
begin
Result:=Tree.Root;
while (Result<>nil) and (Result.Desc<>ctnFinalization) do
Result:=Result.NextBrother;
end;
function TPascalReaderTool.FindMainBeginEndNode: TCodeTreeNode;
begin
Result:=Tree.Root;
if (Result=nil) then exit;
if (Result.Desc in [ctnProgram,ctnLibrary]) then
Result:=Result.LastChild
else begin
Result:=FindImplementationNode;
if Result<>nil then
Result:=Result.LastChild;
end;
if Result=nil then exit;
if Result.Desc<>ctnBeginBlock then Result:=nil;
end;
function TPascalReaderTool.FindFirstSectionChild: TCodeTreeNode;
begin
Result:=Tree.Root;
while (Result<>nil) and (Result.FirstChild=nil) do
Result:=Result.NextBrother;
if (Result=nil) then exit;
Result:=Result.FirstChild;
end;
function TPascalReaderTool.NodeIsInAMethod(Node: TCodeTreeNode): boolean;
begin
Result:=false;