codetools: parsing deeper nodes, even if higher node has errors, bug #8093

git-svn-id: trunk@26799 -
This commit is contained in:
mattias 2010-07-24 10:07:57 +00:00
parent 714834cb9c
commit 2b2c5d9831
22 changed files with 108 additions and 22 deletions

View File

@ -38,7 +38,8 @@ ResourceString
ctsUnknownSubDescriptor = '(unknown subdescriptor %s)';
ctsForward = 'Forward';
ctsUnparsed = 'Unparsed';
ctsHasError = 'HasError';
// linkscanner
ctsInvalidFlagValueForDirective = 'invalid flag value "%s" for directive %s';
ctsInvalidMode = 'invalid mode "%s"';

View File

@ -196,10 +196,10 @@ const
// CodeTreeNodeSubDescriptors
ctnsNone = 0;
ctnsForwardDeclaration = 1 shl 0;
ctnsNeedJITParsing = 1 shl 1;
ctnsHasParseError = 1 shl 2;
ctnsHasDefaultValue = 1 shl 3;
ctnsForwardDeclaration = 1 shl 3;
ctnsHasDefaultValue = 1 shl 4;
ClassSectionNodeType: array[TPascalClassSection] of TCodeTreeNodeDesc = (
ctnClassPrivate,

View File

@ -336,7 +336,8 @@ type
const ErrorCleanPos: integer;
const ErrorNiceCleanPos: TCodeXYPosition
): TCodeTreeNodeParseError;
procedure RaiseNodeParserError(Node: TCodeTreeNode);
procedure RaiseNodeParserError(Node: TCodeTreeNode;
CheckIgnoreErrorPos: boolean = true);
property OnParserProgress: TOnParserProgress
read FOnParserProgress write FOnParserProgress;
@ -585,6 +586,7 @@ begin
if (SubDesc and ctnsNeedJITParsing)>0 then Result:=Result+ctsUnparsed;
end;
end;
if (SubDesc and ctnsHasParseError)>0 then Result:=Result+','+ctsHasError;
end;
function TCustomCodeTool.AtomIs(const AnAtom: shortstring): boolean;
@ -1975,13 +1977,15 @@ begin
Result.NicePos:=ErrorNiceCleanPos;
end;
procedure TCustomCodeTool.RaiseNodeParserError(Node: TCodeTreeNode);
procedure TCustomCodeTool.RaiseNodeParserError(Node: TCodeTreeNode;
CheckIgnoreErrorPos: boolean);
var
NodeError: TCodeTreeNodeParseError;
begin
//debugln(['TCustomCodeTool.SetNodeParserError ',Node.DescAsString,' ',(ctnsHasParseError and Node.SubDesc)>0]);
if (ctnsHasParseError and Node.SubDesc)=0 then exit;
NodeError:=GetNodeParserError(Node);
if CleanPosIsAfterIgnorePos(NodeError.CleanPos) then exit;
//debugln(['TCustomCodeTool.RaiseNodeParserError ',Node.DescAsString,' Msg="',NodeError.Msg,'" ',CleanPosToStr(NodeError.CleanPos)]);
MoveCursorToCleanPos(NodeError.CleanPos);
ErrorNicePosition:=NodeError.NicePos;

View File

@ -359,6 +359,10 @@ msgstr ""
msgid "gtk2 interface directory"
msgstr "directori d'interfície del gtk2"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr "Directori de l'IDE"

View File

@ -361,6 +361,10 @@ msgstr "obecný identifikátor"
msgid "gtk2 interface directory"
msgstr "adresář rozhraní gtk2"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr "Adresář IDE"

View File

@ -362,6 +362,10 @@ msgstr "Allgemeine Bezeichner"
msgid "gtk2 interface directory"
msgstr "Gtk-Interface-Verzeichnis"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr "IDE-Verzeichnis"

View File

@ -359,6 +359,10 @@ msgstr "identificador genérico"
msgid "gtk2 interface directory"
msgstr "directorio de la interfase gtk2"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr "Directorio del IDE"

View File

@ -358,6 +358,10 @@ msgstr ""
msgid "gtk2 interface directory"
msgstr "directorio de la interfase gtk2"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr ""

View File

@ -354,6 +354,10 @@ msgstr ""
msgid "gtk2 interface directory"
msgstr ""
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr ""

View File

@ -360,6 +360,10 @@ msgstr "identificateur générique"
msgid "gtk2 interface directory"
msgstr "répertoire interface pour gtk2"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr "Répertoire de l'IDE"

View File

@ -360,6 +360,10 @@ msgstr "pengenal generik"
msgid "gtk2 interface directory"
msgstr "Direktori interface gtk2"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr "Direktori IDE"

View File

@ -358,6 +358,10 @@ msgstr "identificatore generico"
msgid "gtk2 interface directory"
msgstr "gtk2 directory di interfaccia"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr "Directory dell'IDE"

View File

@ -361,6 +361,10 @@ msgstr "daugybinis identifikatorius"
msgid "gtk2 interface directory"
msgstr "gtk2 interfeiso aplankas"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr "IKA aplankas"

View File

@ -359,6 +359,10 @@ msgstr ""
msgid "gtk2 interface directory"
msgstr ""
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr ""

View File

@ -359,6 +359,10 @@ msgstr "identificador genérico"
msgid "gtk2 interface directory"
msgstr "diretório de interface gtk2"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr "Diretório do IDE"

View File

@ -363,6 +363,10 @@ msgstr ""
msgid "gtk2 interface directory"
msgstr "katalog interfejsu gtk2"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr ""

View File

@ -354,6 +354,10 @@ msgstr ""
msgid "gtk2 interface directory"
msgstr ""
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr ""

View File

@ -359,6 +359,10 @@ msgstr "generic-идентификатор"
msgid "gtk2 interface directory"
msgstr "каталог интерфейса gtk2"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr "Каталог IDE"

View File

@ -360,6 +360,10 @@ msgstr ""
msgid "gtk2 interface directory"
msgstr ""
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr ""

View File

@ -354,6 +354,10 @@ msgstr ""
msgid "gtk2 interface directory"
msgstr "тека інтерфейсу gtk2"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr "Тека IDE"

View File

@ -362,6 +362,10 @@ msgstr "通用标识符"
msgid "gtk2 interface directory"
msgstr "gtk2 接口目录"
#: codetoolsstrconsts.ctshaserror
msgid "HasError"
msgstr ""
#: codetoolsstrconsts.ctsidedirectory
msgid "IDE Directory"
msgstr "IDE 目录"

View File

@ -718,17 +718,19 @@ procedure TPascalParserTool.BuildSubTreeForClass(ClassNode: TCodeTreeNode);
var OldPhase: integer;
begin
if (ClassNode.SubDesc and ctnsNeedJITParsing)=0 then
// class already parsed
exit;
if not (ClassNode.Desc in AllClassObjects) then
RaiseClassDescInvalid;
if (ClassNode.SubDesc and ctnsNeedJITParsing)=0 then begin
// class already parsed
if (ctnsHasParseError and ClassNode.SubDesc)>0 then
RaiseNodeParserError(ClassNode);
exit;
end;
// avoid endless loop
OldPhase:=CurrentPhase;
CurrentPhase:=CodeToolPhaseParse;
try
if (ctnsHasParseError and ClassNode.SubDesc)>0 then
RaiseNodeParserError(ClassNode);
ClassNode.SubDesc:=ClassNode.SubDesc and (not ctnsNeedJITParsing);
// set CursorPos after class head
MoveCursorToNodeStart(ClassNode);
// parse
@ -746,7 +748,7 @@ begin
then
RaiseClassKeyWordExpected;
ReadNextAtom;
// parse modifiers :
// parse modifiers
if CurPos.Flag=cafWord then begin
if UpAtomIs('SEALED') then begin
while UpAtomIs('SEALED') do begin
@ -792,7 +794,6 @@ begin
CurNode.EndPos:=CurPos.StartPos;
EndChildNode;
CurrentPhase:=OldPhase;
ClassNode.SubDesc:=ClassNode.SubDesc and (not ctnsNeedJITParsing);
except
CurrentPhase:=OldPhase;
{$IFDEF ShowIgnoreErrorAfter}
@ -827,15 +828,17 @@ begin
RaiseException(
'TPascalParserTool.BuildSubTreeForBeginBlock: BeginNode.Desc='
+BeginNode.DescAsString);
if (BeginNode.SubDesc and ctnsNeedJITParsing)=0 then
if (BeginNode.SubDesc and ctnsNeedJITParsing)=0 then begin
// block already parsed
if (ctnsHasParseError and BeginNode.SubDesc)>0 then
RaiseNodeParserError(BeginNode);
exit;
end;
OldPhase:=CurrentPhase;
CurrentPhase:=CodeToolPhaseParse;
try
if (ctnsHasParseError and BeginNode.SubDesc)>0 then
RaiseNodeParserError(BeginNode);
BeginNode.SubDesc:=BeginNode.SubDesc and (not ctnsNeedJITParsing);
// set CursorPos on 'begin'
MoveCursorToNodeStart(BeginNode);
ReadNextAtom;
@ -855,7 +858,6 @@ begin
ReadWithStatement(true,true);
until (CurPos.StartPos>=MaxPos);
CurrentPhase:=OldPhase;
BeginNode.SubDesc:=BeginNode.SubDesc and (not ctnsNeedJITParsing);
except
CurrentPhase:=OldPhase;
{$IFDEF ShowIgnoreErrorAfter}
@ -4904,13 +4906,16 @@ begin
end;
ProcHeadNode:=ProcNode.FirstChild;
if (ProcHeadNode<>nil)
and ((ProcHeadNode.SubDesc and ctnsNeedJITParsing)=0) then exit;
OldPhase:=CurrentPhase;
CurrentPhase:=CodeToolPhaseParse;
try
and ((ProcHeadNode.SubDesc and ctnsNeedJITParsing)=0) then begin
// proc head already parsed
if (ProcHeadNode<>nil) and ((ctnsHasParseError and ProcHeadNode.SubDesc)>0)
then
RaiseNodeParserError(ProcHeadNode);
exit;
end;
OldPhase:=CurrentPhase;
CurrentPhase:=CodeToolPhaseParse;
try
IsMethod:=ProcNode.Parent.Desc in (AllClasses+AllClassSections);
MoveCursorToNodeStart(ProcNode);
ReadNextAtom;
@ -4927,6 +4932,8 @@ begin
RaiseCharExpectedButAtomFound(';')
else
RaiseStringExpectedButAtomFound('identifier');
ProcHeadNode.SubDesc:=ProcHeadNode.SubDesc and (not ctnsNeedJITParsing);
if not IsProcType then begin
if not IsOperator then AtomIsIdentifier(true);
ReadNextAtom;
@ -4946,7 +4953,6 @@ begin
if IsProcType then Include(ParseAttr,pphIsType);
ReadTilProcedureHeadEnd(ParseAttr,HasForwardModifier);
CurrentPhase:=OldPhase;
ProcHeadNode.SubDesc:=ProcHeadNode.SubDesc and (not ctnsNeedJITParsing);
except
CurrentPhase:=OldPhase;
{$IFDEF ShowIgnoreErrorAfter}
@ -5020,10 +5026,13 @@ begin
while NodeNeedsBuildSubTree(Result) do begin
BuildSubTree(Result);
Node:=FindDeepestNodeAtPos(Result,P,ExceptionOnNotFound);
if Node=Result then exit;
if Node=Result then break;
Result:=Node;
//debugln('TPascalParserTool.BuildSubTreeAndFindDeepestNodeAtPos B ',Result.DescAsString,' ',dbgs(NodeNeedsBuildSubTree(Result)));
end;
// re-raise parse errors
if (Result<>nil) and ((ctnsHasParseError and Result.SubDesc)>0) then
RaiseNodeParserError(Result);
end;
function TPascalParserTool.FindInterfaceNode: TCodeTreeNode;