mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 12:16:18 +02:00
converted some silent sourcechangecache consistency checks to errors
git-svn-id: trunk@5065 -
This commit is contained in:
parent
3e62949c08
commit
a2ee1be748
@ -893,15 +893,23 @@ end;
|
||||
|
||||
function TCodeToolManager.HandleException(AnException: Exception): boolean;
|
||||
var ErrorSrcTool: TCustomCodeTool;
|
||||
DirtyPos: Integer;
|
||||
begin
|
||||
fErrorMsg:=AnException.Message;
|
||||
fErrorTopLine:=0;
|
||||
if (AnException is ELinkScannerError) then begin
|
||||
// linker error
|
||||
fErrorCode:=TCodeBuffer(ELinkScannerError(AnException).Sender.Code);
|
||||
if fErrorCode<>nil then begin
|
||||
fErrorCode.AbsoluteToLineCol(
|
||||
ELinkScannerError(AnException).Sender.SrcPos,fErrorLine,fErrorColumn);
|
||||
// link scanner error
|
||||
DirtyPos:=0;
|
||||
if AnException is ELinkScannerEditError then begin
|
||||
fErrorCode:=TCodeBuffer(ELinkScannerEditError(AnException).Buffer);
|
||||
if fErrorCode<>nil then
|
||||
DirtyPos:=ELinkScannerEditError(AnException).BufferPos;
|
||||
end else begin
|
||||
fErrorCode:=TCodeBuffer(ELinkScannerError(AnException).Sender.Code);
|
||||
DirtyPos:=ELinkScannerError(AnException).Sender.SrcPos;
|
||||
end;
|
||||
if (fErrorCode<>nil) and (DirtyPos>0) then begin
|
||||
fErrorCode.AbsoluteToLineCol(DirtyPos,fErrorLine,fErrorColumn);
|
||||
end;
|
||||
end else if (AnException is ECodeToolError) then begin
|
||||
// codetool error
|
||||
@ -909,6 +917,9 @@ begin
|
||||
fErrorCode:=ErrorSrcTool.ErrorPosition.Code;
|
||||
fErrorColumn:=ErrorSrcTool.ErrorPosition.X;
|
||||
fErrorLine:=ErrorSrcTool.ErrorPosition.Y;
|
||||
end else if (AnException is ESourceChangeCacheError) then begin
|
||||
// SourceChangeCache error
|
||||
fErrorCode:=nil;
|
||||
end else begin
|
||||
// unknown exception
|
||||
FErrorMsg:=AnException.ClassName+': '+FErrorMsg;
|
||||
|
@ -46,6 +46,7 @@ ResourceString
|
||||
ctsIncludeFileNotFound = 'include file not found "%s"';
|
||||
ctsErrorInDirectiveExpression = 'error in directive expression';
|
||||
ctsIncludeCircleDetected = 'Include circle detected';
|
||||
ctsfileIsReadOnly = 'file is read only';
|
||||
ctsCommentEndNotFound = 'Comment end not found';
|
||||
|
||||
// customcodetool
|
||||
|
@ -138,6 +138,13 @@ type
|
||||
|
||||
ELinkScannerAbort = class(ELinkScannerError)
|
||||
end;
|
||||
|
||||
ELinkScannerEditError = class(ELinkScannerError)
|
||||
Buffer: Pointer;
|
||||
BufferPos: integer;
|
||||
constructor Create(ASender: TLinkScanner; const AMessage: string;
|
||||
ABuffer: Pointer; ABufferPos: integer);
|
||||
end;
|
||||
|
||||
|
||||
{ TLinkScanner }
|
||||
@ -264,10 +271,12 @@ type
|
||||
LastErrorBehindIgnorePosition: boolean;
|
||||
LastErrorCheckedForIgnored: boolean;
|
||||
CleanedIgnoreErrorAfterPosition: integer;
|
||||
procedure RaiseExceptionFmt(const AMessage: string; args: array of const);
|
||||
procedure RaiseExceptionFmt(const AMessage: string; Args: array of const);
|
||||
procedure RaiseException(const AMessage: string);
|
||||
procedure RaiseExceptionClass(const AMessage: string;
|
||||
ExceptionClass: ELinkScannerErrors);
|
||||
procedure RaiseEditException(const AMessage: string; ABuffer: Pointer;
|
||||
ABufferPos: integer);
|
||||
procedure ClearLastError;
|
||||
procedure RaiseLastError;
|
||||
procedure DoCheckAbort;
|
||||
@ -311,7 +320,8 @@ type
|
||||
procedure RaiseLastErrorIfInFrontOfCleanedPos(ACleanedPos: integer);
|
||||
|
||||
// ranges
|
||||
function WholeRangeIsWritable(CleanStartPos, CleanEndPos: integer): boolean;
|
||||
function WholeRangeIsWritable(CleanStartPos, CleanEndPos: integer;
|
||||
ErrorOnFail: boolean): boolean;
|
||||
procedure FindCodeInRange(CleanStartPos, CleanEndPos: integer;
|
||||
UniqueSortedCodeList: TList);
|
||||
procedure DeleteRange(CleanStartPos,CleanEndPos: integer);
|
||||
@ -2780,20 +2790,37 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TLinkScanner.WholeRangeIsWritable(CleanStartPos, CleanEndPos: integer
|
||||
): boolean;
|
||||
var ACode: Pointer;
|
||||
function TLinkScanner.WholeRangeIsWritable(CleanStartPos, CleanEndPos: integer;
|
||||
ErrorOnFail: boolean): boolean;
|
||||
|
||||
procedure EditError(const AMessage: string; ACode: Pointer);
|
||||
begin
|
||||
if ErrorOnFail then
|
||||
RaiseEditException(AMessage,ACode,0);
|
||||
end;
|
||||
|
||||
var
|
||||
ACode: Pointer;
|
||||
LinkIndex: integer;
|
||||
CodeIsReadOnly: boolean;
|
||||
begin
|
||||
Result:=false;
|
||||
if (CleanStartPos<1) or (CleanStartPos>=CleanEndPos)
|
||||
or (CleanEndPos>CleanedLen+1) or (not Assigned(FOnGetSourceStatus)) then exit;
|
||||
or (CleanEndPos>CleanedLen+1) or (not Assigned(FOnGetSourceStatus)) then begin
|
||||
EditError('TLinkScanner.WholeRangeIsWritable: Invalid range',nil);
|
||||
exit;
|
||||
end;
|
||||
LinkIndex:=LinkIndexAtCleanPos(CleanStartPos);
|
||||
if LinkIndex<0 then exit;
|
||||
if LinkIndex<0 then begin
|
||||
EditError('TLinkScanner.WholeRangeIsWritable: position out of scan range',nil);
|
||||
exit;
|
||||
end;
|
||||
ACode:=FLinks[LinkIndex].Code;
|
||||
FOnGetSourceStatus(Self,ACode,CodeIsReadOnly);
|
||||
if CodeIsReadOnly then exit;
|
||||
if CodeIsReadOnly then begin
|
||||
EditError(ctsfileIsReadOnly, ACode);
|
||||
exit;
|
||||
end;
|
||||
repeat
|
||||
inc(LinkIndex);
|
||||
if (LinkIndex>=LinkCount) or (FLinks[LinkIndex].CleanedPos>CleanEndPos) then
|
||||
@ -2804,7 +2831,10 @@ begin
|
||||
if ACode<>FLinks[LinkIndex].Code then begin
|
||||
ACode:=FLinks[LinkIndex].Code;
|
||||
FOnGetSourceStatus(Self,ACode,CodeIsReadOnly);
|
||||
if CodeIsReadOnly then exit;
|
||||
if CodeIsReadOnly then begin
|
||||
EditError(ctsfileIsReadOnly, ACode);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
until false;
|
||||
end;
|
||||
@ -2892,6 +2922,12 @@ begin
|
||||
raise ExceptionClass.Create(Self,AMessage);
|
||||
end;
|
||||
|
||||
procedure TLinkScanner.RaiseEditException(const AMessage: string;
|
||||
ABuffer: Pointer; ABufferPos: integer);
|
||||
begin
|
||||
raise ELinkScannerEditError.Create(Self,AMessage,ABuffer,ABufferPos);
|
||||
end;
|
||||
|
||||
procedure TLinkScanner.ClearLastError;
|
||||
begin
|
||||
LastErrorIsValid:=false;
|
||||
@ -3094,6 +3130,16 @@ begin
|
||||
PSourceLinkMemManager.Free;
|
||||
end;
|
||||
|
||||
{ ELinkScannerEditError }
|
||||
|
||||
constructor ELinkScannerEditError.Create(ASender: TLinkScanner;
|
||||
const AMessage: string; ABuffer: Pointer; ABufferPos: integer);
|
||||
begin
|
||||
inherited Create(ASender,AMessage);
|
||||
Buffer:=ABuffer;
|
||||
BufferPos:=ABufferPos;
|
||||
end;
|
||||
|
||||
initialization
|
||||
InternalInit;
|
||||
|
||||
|
@ -42,8 +42,8 @@ interface
|
||||
{ $DEFINE CTDEBUG}
|
||||
|
||||
uses
|
||||
Classes, SysUtils, CodeCache, BasicCodeTools, SourceLog, LinkScanner,
|
||||
AVL_Tree, KeywordFuncLists;
|
||||
Classes, SysUtils, CodeToolsStrConsts, CodeCache, BasicCodeTools, SourceLog,
|
||||
LinkScanner, AVL_Tree, KeywordFuncLists;
|
||||
|
||||
type
|
||||
{ TBeautifyCodeOptions }
|
||||
@ -130,6 +130,9 @@ type
|
||||
constructor Create;
|
||||
end;
|
||||
|
||||
|
||||
{ TSourceChangeCache }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// in front of and after a text change can be set a gap.
|
||||
// A Gap is for example a space char or a newline. TSourceChangeLog will add
|
||||
@ -139,7 +142,6 @@ type
|
||||
gtNewLine, // at least a newline
|
||||
gtEmptyLine // at least two newlines
|
||||
);
|
||||
|
||||
|
||||
TSourceChangeCacheEntry = class
|
||||
public
|
||||
@ -180,6 +182,8 @@ type
|
||||
procedure SetMainScanner(NewScanner: TLinkScanner);
|
||||
function GetBuffersToModify(Index: integer): TCodeBuffer;
|
||||
procedure UpdateBuffersToModify;
|
||||
protected
|
||||
procedure RaiseException(const AMessage: string);
|
||||
public
|
||||
BeautifyCodeOptions: TBeautifyCodeOptions;
|
||||
procedure BeginUpdate;
|
||||
@ -207,6 +211,15 @@ type
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
{ ESourceChangeCacheError }
|
||||
|
||||
ESourceChangeCacheError = class(Exception)
|
||||
public
|
||||
Sender: TSourceChangeCache;
|
||||
constructor Create(ASender: TSourceChangeCache; const AMessage: string);
|
||||
end;
|
||||
|
||||
|
||||
const
|
||||
AtomTypeNames: array[TAtomType] of shortstring = (
|
||||
@ -412,6 +425,35 @@ function TSourceChangeCache.ReplaceEx(FrontGap, AfterGap: TGapTyp;
|
||||
FromPos, ToPos: integer;
|
||||
DirectCode: TCodeBuffer; FromDirectPos, ToDirectPos: integer;
|
||||
const Text: string): boolean;
|
||||
|
||||
procedure RaiseDataInvalid;
|
||||
begin
|
||||
if MainScanner=nil then
|
||||
RaiseException('TSourceChangeCache.ReplaceEx MainScanner=nil');
|
||||
if FromPos>ToPos then
|
||||
RaiseException('TSourceChangeCache.ReplaceEx FromPos>ToPos');
|
||||
if FromPos<1 then
|
||||
RaiseException('TSourceChangeCache.ReplaceEx FromPos<1');
|
||||
if ToPos>MainScanner.CleanedLen+1 then
|
||||
RaiseException('TSourceChangeCache.ReplaceEx ToPos>MainScanner.CleanedLen+1');
|
||||
end;
|
||||
|
||||
procedure RaiseIntersectionFound;
|
||||
begin
|
||||
RaiseException('TSourceChangeCache.ReplaceEx '
|
||||
+'IGNORED, because intersection found');
|
||||
end;
|
||||
|
||||
procedure RaiseCodeReadOnly(Buffer: TCodeBuffer);
|
||||
begin
|
||||
RaiseException(ctsfileIsReadOnly+' '+Buffer.Filename);
|
||||
end;
|
||||
|
||||
procedure RaiseNotInCleanCode;
|
||||
begin
|
||||
RaiseException('TSourceChangeCache.ReplaceEx not in clean code');
|
||||
end;
|
||||
|
||||
var
|
||||
NewEntry: TSourceChangeCacheEntry;
|
||||
p: pointer;
|
||||
@ -441,6 +483,7 @@ begin
|
||||
{$IFDEF CTDEBUG}
|
||||
writeln('TSourceChangeCache.ReplaceEx IGNORED, because data invalid');
|
||||
{$ENDIF}
|
||||
RaiseDataInvalid;
|
||||
exit;
|
||||
end;
|
||||
end else begin
|
||||
@ -457,21 +500,24 @@ begin
|
||||
IntersectionEntry.FromPos,'-',IntersectionEntry.ToPos,
|
||||
' IsDelete=',IntersectionEntry.IsDeleteOperation);
|
||||
{$ENDIF}
|
||||
RaiseIntersectionFound;
|
||||
exit;
|
||||
end;
|
||||
|
||||
if ToPos>FromPos then begin
|
||||
// this is a delete operation -> check the whole range for writable buffers
|
||||
if not MainScanner.WholeRangeIsWritable(FromPos,ToPos) then exit;
|
||||
if not MainScanner.WholeRangeIsWritable(FromPos,ToPos,true) then exit;
|
||||
end else if (DirectCode<>nil) and (FromDirectPos<ToDirectPos) then begin
|
||||
// this is a direct delete operation -> check if the DirectCode is writable
|
||||
if DirectCode.ReadOnly then exit;
|
||||
if DirectCode.ReadOnly then
|
||||
RaiseCodeReadOnly(DirectCode);
|
||||
end;
|
||||
if DirectCode=nil then begin
|
||||
if not MainScanner.CleanedPosToCursor(FromPos,FromDirectPos,p) then begin
|
||||
{$IFDEF CTDEBUG}
|
||||
writeln('TSourceChangeCache.ReplaceEx IGNORED, because not in clean pos');
|
||||
{$ENDIF}
|
||||
RaiseNotInCleanCode;
|
||||
exit;
|
||||
end;
|
||||
DirectCode:=TCodeBuffer(p);
|
||||
@ -831,6 +877,11 @@ begin
|
||||
FBuffersToModifyNeedsUpdate:=false;
|
||||
end;
|
||||
|
||||
procedure TSourceChangeCache.RaiseException(const AMessage: string);
|
||||
begin
|
||||
raise ESourceChangeCacheError.Create(Self,AMessage);
|
||||
end;
|
||||
|
||||
{ TBeautifyCodeOptions }
|
||||
|
||||
constructor TBeautifyCodeOptions.Create;
|
||||
@ -1237,6 +1288,14 @@ begin
|
||||
|
||||
end;
|
||||
|
||||
{ ESourceChangeCacheError }
|
||||
|
||||
constructor ESourceChangeCacheError.Create(ASender: TSourceChangeCache;
|
||||
const AMessage: string);
|
||||
begin
|
||||
inherited Create(AMessage);
|
||||
Sender:=ASender;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -2688,7 +2688,8 @@ function TStandardCodeTool.RenamePublishedVariable(const UpperClassName,
|
||||
UpperOldVarName: string; const NewVarName, VarType: shortstring;
|
||||
ExceptionOnClassNotFound: boolean;
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
var TypeNode, VarNode: TCodeTreeNode;
|
||||
var
|
||||
TypeNode, VarNode: TCodeTreeNode;
|
||||
begin
|
||||
Result:=false;
|
||||
VarNode:=FindPublishedVariable(UpperClassName,UpperOldVarName,
|
||||
|
Loading…
Reference in New Issue
Block a user