mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-02 18:00:26 +02:00
codetools: when cursor pos outside code: give more details
git-svn-id: trunk@35178 -
This commit is contained in:
parent
0e876bd527
commit
5f47718cdd
@ -328,6 +328,8 @@ type
|
|||||||
ClearNicePos: boolean = true); virtual;
|
ClearNicePos: boolean = true); virtual;
|
||||||
procedure RaiseExceptionFmt(const AMessage: string;
|
procedure RaiseExceptionFmt(const AMessage: string;
|
||||||
const args: array of const; ClearNicePos: boolean = true);
|
const args: array of const; ClearNicePos: boolean = true);
|
||||||
|
procedure RaiseExceptionAtErrorPos(const AMessage: string;
|
||||||
|
ClearNicePos: boolean = true); virtual;
|
||||||
// permanent errors, that the parser will raise again
|
// permanent errors, that the parser will raise again
|
||||||
procedure SaveRaiseException(const AMessage: string;
|
procedure SaveRaiseException(const AMessage: string;
|
||||||
ClearNicePos: boolean = true); virtual;
|
ClearNicePos: boolean = true); virtual;
|
||||||
@ -350,6 +352,7 @@ type
|
|||||||
): TCodeTreeNodeParseError;
|
): TCodeTreeNodeParseError;
|
||||||
procedure RaiseNodeParserError(Node: TCodeTreeNode;
|
procedure RaiseNodeParserError(Node: TCodeTreeNode;
|
||||||
CheckIgnoreErrorPos: boolean = true);
|
CheckIgnoreErrorPos: boolean = true);
|
||||||
|
procedure RaiseCursorOutsideCode(CursorPos: TCodeXYPosition);
|
||||||
property OnParserProgress: TOnParserProgress
|
property OnParserProgress: TOnParserProgress
|
||||||
read FOnParserProgress write FOnParserProgress;
|
read FOnParserProgress write FOnParserProgress;
|
||||||
|
|
||||||
@ -435,6 +438,18 @@ begin
|
|||||||
RaiseException(Format(AMessage,args),ClearNicePos);
|
RaiseException(Format(AMessage,args),ClearNicePos);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomCodeTool.RaiseExceptionAtErrorPos(const AMessage: string;
|
||||||
|
ClearNicePos: boolean);
|
||||||
|
begin
|
||||||
|
if ClearNicePos then
|
||||||
|
ErrorNicePosition:=CleanCodeXYPosition;
|
||||||
|
// raise the exception
|
||||||
|
if not RaiseUnhandableExceptions then
|
||||||
|
raise ECodeToolError.Create(Self,AMessage)
|
||||||
|
else
|
||||||
|
RaiseCatchableException(AMessage);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomCodeTool.SaveRaiseException(const AMessage: string;
|
procedure TCustomCodeTool.SaveRaiseException(const AMessage: string;
|
||||||
ClearNicePos: boolean);
|
ClearNicePos: boolean);
|
||||||
var
|
var
|
||||||
@ -2177,6 +2192,86 @@ begin
|
|||||||
RaiseException(NodeError.Msg,false);
|
RaiseException(NodeError.Msg,false);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomCodeTool.RaiseCursorOutsideCode(CursorPos: TCodeXYPosition);
|
||||||
|
var
|
||||||
|
Msg: String;
|
||||||
|
p: integer;
|
||||||
|
CleanPos: integer;
|
||||||
|
r: Integer;
|
||||||
|
i: Integer;
|
||||||
|
Link: TSourceLink;
|
||||||
|
NearestScanPos: Integer;
|
||||||
|
Node: TCodeTreeNode;
|
||||||
|
LastPos: Integer;
|
||||||
|
begin
|
||||||
|
ErrorPosition:=CursorPos;
|
||||||
|
// check position in code buffer
|
||||||
|
if CursorPos.Code=nil then
|
||||||
|
Msg:='cursor position without code buffer'
|
||||||
|
else if (CursorPos.Y<1) or (CursorPos.Y>CursorPos.Code.LineCount+1) then
|
||||||
|
Msg:='invalid line number '+IntToStr(CursorPos.Y)
|
||||||
|
else if (CursorPos.X<1) then
|
||||||
|
Msg:='invalid column number '+IntToStr(CursorPos.Y)
|
||||||
|
else begin
|
||||||
|
CursorPos.Code.LineColToPosition(CursorPos.Y,CursorPos.X,p);
|
||||||
|
if p<1 then
|
||||||
|
Msg:='cursor position is outside of code'
|
||||||
|
else begin
|
||||||
|
// check position in scanner
|
||||||
|
if Scanner=nil then
|
||||||
|
Msg:='missing scanner (called wrong or no pascal)'
|
||||||
|
else begin
|
||||||
|
r:=Scanner.CursorToCleanPos(p,CursorPos.Code,CleanPos);
|
||||||
|
if r<>0 then begin
|
||||||
|
NearestScanPos:=0;
|
||||||
|
for i:=0 to Scanner.LinkCount-1 do begin
|
||||||
|
Link:=Scanner.Links[i];
|
||||||
|
if Link.Code<>Pointer(CursorPos.Code) then continue;
|
||||||
|
if Link.SrcPos>p then continue;
|
||||||
|
NearestScanPos:=Link.SrcPos+Scanner.LinkSize(i);
|
||||||
|
end;
|
||||||
|
if NearestScanPos=0 then
|
||||||
|
Msg:='file was not reached by scanned'
|
||||||
|
else begin
|
||||||
|
if r=-1 then
|
||||||
|
Msg:='cursor position was skipped by scanner'
|
||||||
|
else
|
||||||
|
Msg:='cursor position is beyond scan range';
|
||||||
|
Msg:=Msg+' (last at '+CursorPos.Code.AbsoluteToLineColStr(NearestScanPos)+')'
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
// check position in tree
|
||||||
|
if (Tree=nil) or (Tree.Root=nil) then
|
||||||
|
Msg:='No pascal found (maybe function was called before BuildTree)'
|
||||||
|
else if CleanPos<Tree.Root.StartPos then begin
|
||||||
|
// in front of parsed code
|
||||||
|
Msg:='In front of code.';
|
||||||
|
if Tree.Root.StartPos<=SrcLen then begin
|
||||||
|
MoveCursorToCleanPos(Tree.Root.StartPos);
|
||||||
|
ReadNextAtom;
|
||||||
|
Msg:=Msg+' (pascal code starts with "'+GetAtom+'" at '
|
||||||
|
+CleanPosToStr(Tree.Root.StartPos)+')';
|
||||||
|
end else begin
|
||||||
|
Node:=Tree.Root;
|
||||||
|
while Node.NextBrother<>nil do Node:=Node.NextBrother;
|
||||||
|
if (Node.EndPos>0) and (p>Node.EndPos) then
|
||||||
|
LastPos:=Node.EndPos
|
||||||
|
else
|
||||||
|
LastPos:=Node.StartPos;
|
||||||
|
if p>LastPos then begin
|
||||||
|
Msg:='behind code (parser stopped at '+CleanPosToStr(LastPos)+')';
|
||||||
|
end else begin
|
||||||
|
Msg:='inconsistency: the position is in code, but caller thinks it is not.'
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
RaiseExceptionAtErrorPos(Msg);
|
||||||
|
end;
|
||||||
|
|
||||||
function TCustomCodeTool.StringIsKeyWord(const Word: string): boolean;
|
function TCustomCodeTool.StringIsKeyWord(const Word: string): boolean;
|
||||||
begin
|
begin
|
||||||
Result:=(Word<>'') and IsIdentStartChar[Word[1]]
|
Result:=(Word<>'') and IsIdentStartChar[Word[1]]
|
||||||
@ -2380,9 +2475,11 @@ begin
|
|||||||
// raise the exception
|
// raise the exception
|
||||||
if not RaiseUnhandableExceptions then
|
if not RaiseUnhandableExceptions then
|
||||||
raise TheException
|
raise TheException
|
||||||
else
|
else begin
|
||||||
|
TheException.Free;
|
||||||
RaiseCatchableException(TheException.Message);
|
RaiseCatchableException(TheException.Message);
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomCodeTool.RaiseExceptionClass(const AMessage: string;
|
procedure TCustomCodeTool.RaiseExceptionClass(const AMessage: string;
|
||||||
ExceptionClass: ECodeToolErrors; ClearNicePos: boolean);
|
ExceptionClass: ECodeToolErrors; ClearNicePos: boolean);
|
||||||
@ -2502,20 +2599,23 @@ function TCustomCodeTool.FindDeepestNodeAtPos(StartNode: TCodeTreeNode;
|
|||||||
MoveCursorToCleanPos(P);
|
MoveCursorToCleanPos(P);
|
||||||
// check if p is in parsed code
|
// check if p is in parsed code
|
||||||
if (Tree=nil) or (Tree.Root=nil) then begin
|
if (Tree=nil) or (Tree.Root=nil) then begin
|
||||||
|
debugln(['TCustomCodeTool.FindDeepestNodeAtPos there are no nodes, maybe you forgot to parse?']);
|
||||||
CTDumpStack;
|
CTDumpStack;
|
||||||
RaiseException('no pascal code or not yet parsed');
|
RaiseException('no pascal code or not yet parsed');
|
||||||
end;
|
end;
|
||||||
if p<Tree.Root.StartPos then begin
|
if p<Tree.Root.StartPos then begin
|
||||||
|
// in front of parsed code
|
||||||
Msg:='In front of code.';
|
Msg:='In front of code.';
|
||||||
if Tree.Root.StartPos<=SrcLen then begin
|
if Tree.Root.StartPos<=SrcLen then begin
|
||||||
MoveCursorToCleanPos(Tree.Root.StartPos);
|
MoveCursorToCleanPos(Tree.Root.StartPos);
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
Msg:=Msg+' The pascal code starts with "'+GetAtom+'" at '
|
Msg:=Msg+' (The pascal code starts with "'+GetAtom+'" at '
|
||||||
+CleanPosToStr(Tree.Root.StartPos)+'. No code';
|
+CleanPosToStr(Tree.Root.StartPos)+')';
|
||||||
end;
|
end;
|
||||||
MoveCursorToCleanPos(P);
|
MoveCursorToCleanPos(P);
|
||||||
RaiseException(Msg);
|
RaiseException(Msg);
|
||||||
end;
|
end;
|
||||||
|
// behind parsed code
|
||||||
Node:=Tree.Root;
|
Node:=Tree.Root;
|
||||||
while Node.NextBrother<>nil do Node:=Node.NextBrother;
|
while Node.NextBrother<>nil do Node:=Node.NextBrother;
|
||||||
if (Node.EndPos>0) and (p>Node.EndPos) then
|
if (Node.EndPos>0) and (p>Node.EndPos) then
|
||||||
@ -2523,7 +2623,7 @@ function TCustomCodeTool.FindDeepestNodeAtPos(StartNode: TCodeTreeNode;
|
|||||||
else
|
else
|
||||||
LastPos:=Node.StartPos;
|
LastPos:=Node.StartPos;
|
||||||
if p>LastPos then begin
|
if p>LastPos then begin
|
||||||
Msg:='Behind code. The last valid pascal code is at '+CleanPosToStr(LastPos)+'. No code';
|
Msg:='Behind code (The parser stopped at '+CleanPosToStr(LastPos)+')';
|
||||||
RaiseException(Msg);
|
RaiseException(Msg);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2666,9 +2766,9 @@ begin
|
|||||||
Result:='';
|
Result:='';
|
||||||
if WithFilename then
|
if WithFilename then
|
||||||
Result:=ExtractRelativepath(ExtractFilePath(MainFilename),CodePos.Code.Filename)+',';
|
Result:=ExtractRelativepath(ExtractFilePath(MainFilename),CodePos.Code.Filename)+',';
|
||||||
Result:=Result+'y='+IntToStr(CodePos.Y)+',x='+IntToStr(CodePos.X);
|
Result:=Result+'line '+IntToStr(CodePos.Y)+', column '+IntToStr(CodePos.X);
|
||||||
end else
|
end else
|
||||||
Result:='y=?,x=?,c='+IntToStr(CleanPos)+'('+dbgstr(copy(Src,CleanPos-5,5)+'|'+copy(Src,CleanPos,5))+')';
|
Result:='outside scan range, pos='+IntToStr(CleanPos)+'('+dbgstr(copy(Src,CleanPos-5,5)+'|'+copy(Src,CleanPos,5))+')';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomCodeTool.CleanPosToRelativeStr(CleanPos: integer;
|
function TCustomCodeTool.CleanPosToRelativeStr(CleanPos: integer;
|
||||||
|
@ -1422,7 +1422,8 @@ begin
|
|||||||
if (CursorPos.Y<1) or (CursorPos.Y>CursorPos.Code.LineCount)
|
if (CursorPos.Y<1) or (CursorPos.Y>CursorPos.Code.LineCount)
|
||||||
or (CursorPos.X<1) then exit;
|
or (CursorPos.X<1) then exit;
|
||||||
CursorPos.Code.GetLineRange(CursorPos.Y-1,LineRange);
|
CursorPos.Code.GetLineRange(CursorPos.Y-1,LineRange);
|
||||||
if LineRange.EndPos-LineRange.StartPos+1<CursorPos.X then exit;
|
if LineRange.EndPos-LineRange.StartPos+1<CursorPos.X then
|
||||||
|
exit; // beyond end of line
|
||||||
|
|
||||||
ActivateGlobalWriteLock;
|
ActivateGlobalWriteLock;
|
||||||
try
|
try
|
||||||
@ -1479,7 +1480,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
if CursorNode=nil then begin
|
if CursorNode=nil then begin
|
||||||
// raise exception
|
// raise exception
|
||||||
CursorNode:=FindDeepestNodeAtPos(CleanCursorPos,true);
|
RaiseCursorOutsideCode(CursorPos);
|
||||||
end;
|
end;
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
DebugLn('TFindDeclarationTool.FindDeclaration D CursorNode=',NodeDescriptionAsString(CursorNode.Desc),' HasChilds=',dbgs(CursorNode.FirstChild<>nil));
|
DebugLn('TFindDeclarationTool.FindDeclaration D CursorNode=',NodeDescriptionAsString(CursorNode.Desc),' HasChilds=',dbgs(CursorNode.FirstChild<>nil));
|
||||||
|
@ -5010,7 +5010,7 @@ var
|
|||||||
IgnorePos: TCodePosition;
|
IgnorePos: TCodePosition;
|
||||||
Node: TCodeTreeNode;
|
Node: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
//DebugLn(['TPascalParserTool.BuildTreeAndGetCleanPos ',MainFilename,' btSetIgnoreErrorPos=',btSetIgnoreErrorPos in BuildTreeFlags,' btKeepIgnoreErrorPos=',btKeepIgnoreErrorPos in BuildTreeFlags,' CursorPos=x=',CursorPos.X,',y=',CursorPos.Y]);
|
//DebugLn(['TPascalParserTool.BuildTreeAndGetCleanPos ',MainFilename,' btSetIgnoreErrorPos=',btSetIgnoreErrorPos in BuildTreeFlags,' btKeepIgnoreErrorPos=',btKeepIgnoreErrorPos in BuildTreeFlags,' CursorPos=',dbgs(CursorPos)]);
|
||||||
if (btSetIgnoreErrorPos in BuildTreeFlags) then begin
|
if (btSetIgnoreErrorPos in BuildTreeFlags) then begin
|
||||||
// ignore errors after cursor position
|
// ignore errors after cursor position
|
||||||
if (CursorPos.Code<>nil) then begin
|
if (CursorPos.Code<>nil) then begin
|
||||||
|
@ -807,7 +807,7 @@ var
|
|||||||
Column: integer;
|
Column: integer;
|
||||||
begin
|
begin
|
||||||
AbsoluteToLineCol(Position,Line,Column);
|
AbsoluteToLineCol(Position,Line,Column);
|
||||||
Result:='p='+IntToStr(Position)+',y='+IntToStr(Line)+',x='+IntToStr(Column);
|
Result:='p='+IntToStr(Position)+',line='+IntToStr(Line)+',col='+IntToStr(Column);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSourceLog.LoadFromFile(const Filename: string): boolean;
|
function TSourceLog.LoadFromFile(const Filename: string): boolean;
|
||||||
|
Loading…
Reference in New Issue
Block a user