mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-10-24 05:41:32 +02:00
codetools: skipped code is now converted to special comments
git-svn-id: trunk@38521 -
This commit is contained in:
parent
a3eea5f52e
commit
20382c7ed0
@ -262,7 +262,7 @@ begin
|
||||
Result:=false;
|
||||
ProcHead:='';
|
||||
BuildTreeAndGetCleanPos(trTillCursor,lsrEnd,CursorPos,CleanCursorPos,
|
||||
[btSetIgnoreErrorPos,btLoadDirtySource,btCursorPosOutAllowed]);
|
||||
[btSetIgnoreErrorPos,btCursorPosOutAllowed]);
|
||||
ANode:=FindDeepestNodeAtPos(CleanCursorPos,True);
|
||||
while (ANode<>nil) and (ANode.Desc<>ctnProcedure) do
|
||||
ANode:=ANode.Parent;
|
||||
|
||||
@ -38,7 +38,6 @@ interface
|
||||
|
||||
{ $DEFINE ShowIgnoreError}
|
||||
{ $DEFINE VerboseUpdateNeeded}
|
||||
{$DEFINE ShowDirtySrc}
|
||||
|
||||
uses
|
||||
{$IFDEF MEM_CHECK}
|
||||
@ -74,41 +73,6 @@ type
|
||||
end;
|
||||
|
||||
|
||||
{ TDirtySource - class to store a dirty source }
|
||||
|
||||
TDirtySource = class
|
||||
public
|
||||
CursorPos: TCodeXYPosition;
|
||||
Src: string;
|
||||
GapSrc: string;
|
||||
Code: TCodeBuffer;
|
||||
Valid: boolean;
|
||||
CurPos: TAtomPosition;
|
||||
StartPos: integer;
|
||||
GapStart: integer;
|
||||
GapEnd: integer;
|
||||
LockCount: integer;
|
||||
Owner: TCustomCodeTool;
|
||||
procedure BeginUpdate;
|
||||
procedure EndUpdate;
|
||||
procedure SetGap(const NewCursorPos: TCodeXYPosition;
|
||||
NewDirtyStartPos, NewDirtyGapStart, NewDirtyGapEnd: integer);
|
||||
constructor Create(TheOwner: TCustomCodeTool);
|
||||
procedure Clear;
|
||||
procedure SetCursorToIdentStartEndAtPosition;
|
||||
function GetCursorSrcPos: PChar;
|
||||
function IsPCharInSrc(p: PChar): boolean;
|
||||
procedure MoveCursorToPos(APos: integer);
|
||||
procedure MoveCursorToPos(APos: PChar);
|
||||
function CalcMemSize: PtrUInt;
|
||||
end;
|
||||
|
||||
THybridCursorType = (
|
||||
hcClean,
|
||||
hcDirty
|
||||
);
|
||||
|
||||
|
||||
// types for user aborts
|
||||
TOnParserProgress = function(Tool: TCustomCodeTool): boolean of object;
|
||||
TCodeTreeChangeEvent = procedure(Tool: TCustomCodeTool;
|
||||
@ -169,8 +133,6 @@ type
|
||||
procedure RaiseLastError;
|
||||
procedure DoProgress; inline;
|
||||
procedure NotifyAboutProgress;
|
||||
// dirty/dead source
|
||||
procedure LoadDirtySource(const CursorPos: TCodeXYPosition);
|
||||
procedure FetchScannerSource(Range: TLinkScannerRange); virtual;
|
||||
function InternalAtomIsIdentifier: boolean; inline;
|
||||
public
|
||||
@ -190,9 +152,6 @@ type
|
||||
JumpCentered: boolean;
|
||||
CursorBeyondEOL: boolean;
|
||||
|
||||
DirtySrc: TDirtySource;
|
||||
HybridCursorType: THybridCursorType;
|
||||
|
||||
ErrorPosition: TCodeXYPosition;
|
||||
ErrorNicePosition: TCodeXYPosition;// if NiceErrorPosition is set, then it is in front of ErrorPosition
|
||||
|
||||
@ -243,7 +202,6 @@ type
|
||||
procedure BeginParsingAndGetCleanPosOLD(
|
||||
OnlyInterfaceNeeded: boolean; CursorPos: TCodeXYPosition;
|
||||
out CleanCursorPos: integer);
|
||||
function IsDirtySrcValid: boolean;
|
||||
|
||||
function StringIsKeyWord(const Word: string): boolean;
|
||||
|
||||
@ -255,9 +213,7 @@ type
|
||||
procedure MoveCursorToNearestAtom(ACleanPos: integer);
|
||||
procedure MoveCursorToLastNodeAtom(ANode: TCodeTreeNode);
|
||||
function IsPCharInSrc(ACleanPos: PChar): boolean;
|
||||
procedure MoveHybridCursorToPos(DirtyPos: PChar);
|
||||
function GetHybridCursorStart: integer;
|
||||
|
||||
|
||||
// read atoms
|
||||
procedure ReadNextAtom;
|
||||
procedure UndoReadNextAtom;
|
||||
@ -417,7 +373,6 @@ begin
|
||||
FreeAndNil(LastAtoms);
|
||||
FreeAndNil(Tree);
|
||||
FreeAndNil(KeyWordFuncList);
|
||||
FreeAndNil(DirtySrc);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
@ -540,40 +495,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomCodeTool.LoadDirtySource(const CursorPos: TCodeXYPosition);
|
||||
// - create the DirtySrc object
|
||||
// - load the unparsed source at CursorPos
|
||||
// - find the gap bounds
|
||||
var
|
||||
NewDirtyStartPos: integer;
|
||||
NewDirtyGapStart: integer;
|
||||
NewDirtyGapEnd: integer;
|
||||
CursorInLink: Boolean;
|
||||
BestLinkIndex: Integer;
|
||||
BestLink: TSourceLink;
|
||||
begin
|
||||
DebugLn('TCustomCodeTool.LoadDirtySource X=',dbgs(CursorPos.X),' Y=',dbgs(CursorPos.Y),
|
||||
' ',ExtractFilename(CursorPos.Code.Filename));
|
||||
if DirtySrc=nil then DirtySrc:=TDirtySource.Create(Self);
|
||||
CursorPos.Code.LineColToPosition(CursorPos.Y,CursorPos.X,NewDirtyStartPos);
|
||||
if NewDirtyStartPos<1 then
|
||||
RaiseCatchableException('NewDirtyStartPos<1');
|
||||
CursorInLink:=false;
|
||||
BestLinkIndex:=Scanner.LinkIndexNearCursorPos(NewDirtyStartPos,
|
||||
CursorPos.Code,CursorInLink);
|
||||
if BestLinkIndex<0 then
|
||||
RaiseCatchableException('BestLinkIndex<0');
|
||||
if CursorInLink then
|
||||
RaiseCatchableException('CursorInLink');
|
||||
BestLink:=Scanner.Links[BestLinkIndex];
|
||||
NewDirtyGapStart:=BestLink.SrcPos+Scanner.LinkSize(BestLinkIndex);
|
||||
if BestLinkIndex<Scanner.LinkCount then
|
||||
NewDirtyGapEnd:=Scanner.Links[BestLinkIndex+1].SrcPos
|
||||
else
|
||||
NewDirtyGapEnd:=CursorPos.Code.SourceLength;
|
||||
DirtySrc.SetGap(CursorPos,NewDirtyStartPos,NewDirtyGapStart,NewDirtyGapEnd);
|
||||
end;
|
||||
|
||||
procedure TCustomCodeTool.FetchScannerSource(Range: TLinkScannerRange);
|
||||
begin
|
||||
// update scanned code
|
||||
@ -590,8 +511,6 @@ begin
|
||||
DebugLn(['TCustomCodeTool.BeginParsing ',MainFilename]);
|
||||
{$ENDIF}
|
||||
FRangeValidTill:=lsrInit;
|
||||
DirtySrc.Free;
|
||||
DirtySrc:=nil;
|
||||
end;
|
||||
|
||||
// delete nodes
|
||||
@ -2101,11 +2020,6 @@ begin
|
||||
BeginParsingAndGetCleanPos(Range,CursorPos,CleanCursorPos);
|
||||
end;
|
||||
|
||||
function TCustomCodeTool.IsDirtySrcValid: boolean;
|
||||
begin
|
||||
Result:=(DirtySrc<>nil) and (DirtySrc.Code<>nil);
|
||||
end;
|
||||
|
||||
function TCustomCodeTool.IgnoreErrorAfterPositionIsInFrontOfLastErrMessage: boolean;
|
||||
var
|
||||
IgnoreErrorAfterCleanPos: integer;
|
||||
@ -2351,7 +2265,6 @@ begin
|
||||
LastAtoms.Clear;
|
||||
NextPos.StartPos:=-1;
|
||||
CurNode:=nil;
|
||||
HybridCursorType:=hcClean;
|
||||
end;
|
||||
|
||||
procedure TCustomCodeTool.MoveCursorToCleanPos(ACleanPos: PChar);
|
||||
@ -2423,23 +2336,6 @@ begin
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
procedure TCustomCodeTool.MoveHybridCursorToPos(DirtyPos: PChar);
|
||||
begin
|
||||
if IsDirtySrcValid and (not IsPCharInSrc(DirtyPos)) then begin
|
||||
DirtySrc.MoveCursorToPos(DirtyPos);
|
||||
HybridCursorType:=hcDirty;
|
||||
end else
|
||||
MoveCursorToCleanPos(DirtyPos);
|
||||
end;
|
||||
|
||||
function TCustomCodeTool.GetHybridCursorStart: integer;
|
||||
begin
|
||||
if HybridCursorType=hcDirty then
|
||||
Result:=DirtySrc.CurPos.StartPos
|
||||
else
|
||||
Result:=CurPos.StartPos;
|
||||
end;
|
||||
|
||||
procedure TCustomCodeTool.CreateChildNode;
|
||||
var NewNode: TCodeTreeNode;
|
||||
begin
|
||||
@ -2618,9 +2514,6 @@ begin
|
||||
if LastAtoms<>nil then
|
||||
Stats.Add('TCustomCodeTool.LastAtoms',
|
||||
LastAtoms.CalcMemSize);
|
||||
if DirtySrc<>nil then
|
||||
Stats.Add('TCustomCodeTool.DirtySrc',
|
||||
DirtySrc.CalcMemSize);
|
||||
end;
|
||||
|
||||
procedure TCustomCodeTool.CheckNodeTool(Node: TCodeTreeNode);
|
||||
@ -2850,6 +2743,17 @@ end;
|
||||
|
||||
procedure TCustomCodeTool.GetCleanPosInfo(CodePosInFront, CleanPos: integer;
|
||||
ResolveComments: boolean; out SameArea: TAtomPosition);
|
||||
{ Use this function to safely find out if a position is in a comment,
|
||||
a string constant, an atom or is in space
|
||||
|
||||
CodePosInFront: a position in code, where parsing starts
|
||||
If -1 it uses FindDeepestNodeAtPos
|
||||
CleanPos: target position
|
||||
ResolveComments: if CleanPos is in a comment, parse again in the comment (not recursive)
|
||||
SameArea: area around CleanPos, either an atom, comment, directive or space
|
||||
if CleanPos<CodePosInFront then CleanAtomPosition
|
||||
if CleanPos>SrcLen then CurPos.StartPos>SrcLen
|
||||
}
|
||||
var
|
||||
ANode: TCodeTreeNode;
|
||||
begin
|
||||
@ -2858,6 +2762,8 @@ begin
|
||||
ANode:=FindDeepestNodeAtPos(CleanPos,True);
|
||||
CodePosInFront:=ANode.StartPos;
|
||||
end;
|
||||
if CodePosInFront>CleanPos then
|
||||
exit;
|
||||
MoveCursorToCleanPos(CodePosInFront);
|
||||
repeat
|
||||
ReadNextAtom;
|
||||
@ -2893,6 +2799,7 @@ begin
|
||||
ReadTillCommentEnd;
|
||||
SameArea.EndPos:=CurPos.StartPos;
|
||||
if (SameArea.StartPos=SameArea.EndPos) then
|
||||
// inconsistency: some non space and non comment between two tokens
|
||||
RaiseException('TCustomCodeTool.GetCleanPosInfo Internal Error A');
|
||||
if CleanPos<SameArea.EndPos then begin
|
||||
// cursor is in comment
|
||||
@ -2900,11 +2807,19 @@ begin
|
||||
// take comment as normal code and search again
|
||||
CodePosInFront:=SameArea.StartPos;
|
||||
case Src[CodePosInFront] of
|
||||
'{': inc(CodePosInFront);
|
||||
'{':
|
||||
begin
|
||||
inc(CodePosInFront);
|
||||
if (CodePosInFront<=SrcLen) and (Src[CodePosInFront+1]=#3) then
|
||||
inc(CodePosInFront);
|
||||
end;
|
||||
'(','/': inc(CodePosInFront,2);
|
||||
else
|
||||
RaiseException('TCustomCodeTool.GetCleanPosInfo Internal Error B '+dbgstr(Src[CodePosInFront])+' at '+CleanPosToStr(CodePosInFront,true));
|
||||
end;
|
||||
if CodePosInFront>CleanPos then
|
||||
// CleanPos at start of comment => return comment
|
||||
exit;
|
||||
GetCleanPosInfo(CodePosInFront,CleanPos,true,SameArea);
|
||||
end;
|
||||
exit;
|
||||
@ -3209,134 +3124,6 @@ begin
|
||||
Filename:=AFilename;
|
||||
end;
|
||||
|
||||
{ TDirtySource }
|
||||
|
||||
procedure TDirtySource.BeginUpdate;
|
||||
begin
|
||||
inc(LockCount);
|
||||
end;
|
||||
|
||||
procedure TDirtySource.EndUpdate;
|
||||
begin
|
||||
if LockCount<=0 then
|
||||
RaiseCatchableException('TDirtySource.EndUpdate');
|
||||
dec(LockCount);
|
||||
end;
|
||||
|
||||
procedure TDirtySource.SetGap(const NewCursorPos: TCodeXYPosition;
|
||||
NewDirtyStartPos, NewDirtyGapStart, NewDirtyGapEnd: integer);
|
||||
begin
|
||||
// check for conflicts
|
||||
if (LockCount>0) then begin
|
||||
if (Code<>nil) and (Code<>NewCursorPos.Code) then
|
||||
RaiseCatchableException('TDirtySource.SetGap Code change');
|
||||
if (GapStart>0) then
|
||||
if (NewDirtyStartPos<>StartPos)
|
||||
or (NewDirtyGapStart<>GapStart)
|
||||
or (NewDirtyGapEnd<>GapEnd) then
|
||||
RaiseCatchableException('TDirtySource.SetGap Gap change');
|
||||
end;
|
||||
if (NewDirtyGapStart>NewDirtyStartPos)
|
||||
or (NewDirtyStartPos>NewDirtyGapEnd) then
|
||||
RaiseCatchableException('TDirtySource.SetGap Gap Bounds');
|
||||
|
||||
// set values
|
||||
CursorPos:=NewCursorPos;
|
||||
Code:=CursorPos.Code;
|
||||
StartPos:=NewDirtyStartPos;
|
||||
GapStart:=NewDirtyGapStart;
|
||||
GapEnd:=NewDirtyGapEnd;
|
||||
CurPos.StartPos:=StartPos;
|
||||
CurPos.EndPos:=StartPos;
|
||||
CurPos.Flag:=cafNone;
|
||||
|
||||
// get source
|
||||
if Code<>nil then
|
||||
Src:=Code.Source
|
||||
else
|
||||
Src:='';
|
||||
if (GapStart>0) then begin
|
||||
GapSrc:=copy(Src,GapStart,GapEnd-GapStart);
|
||||
{$IFDEF ShowDirtySrc}
|
||||
DebugLn('TDirtySource.SetGap Owner=',ExtractFilename(Owner.MainFilename),
|
||||
' Code=',ExtractFilename(Code.Filename),
|
||||
' Gap('+dbgs(GapStart)+','+dbgs(StartPos)+','+dbgs(GapEnd)+')',
|
||||
'"',StringToPascalConst(copy(GapSrc,1,20)),'"..',
|
||||
'"',StringToPascalConst(copy(GapSrc,length(GapSrc)-19,20)),'"'
|
||||
);
|
||||
{$ENDIF}
|
||||
end else begin
|
||||
GapSrc:='';
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TDirtySource.Create(TheOwner: TCustomCodeTool);
|
||||
begin
|
||||
Owner:=TheOwner;
|
||||
end;
|
||||
|
||||
procedure TDirtySource.Clear;
|
||||
begin
|
||||
SetGap(CodeXYPosition(0,0,nil),0,0,0);
|
||||
end;
|
||||
|
||||
procedure TDirtySource.SetCursorToIdentStartEndAtPosition;
|
||||
begin
|
||||
GetIdentStartEndAtPosition(GapSrc,CurPos.StartPos,
|
||||
CurPos.StartPos,CurPos.EndPos);
|
||||
end;
|
||||
|
||||
function TDirtySource.GetCursorSrcPos: PChar;
|
||||
begin
|
||||
Result:=@Src[CurPos.StartPos];
|
||||
end;
|
||||
|
||||
function TDirtySource.IsPCharInSrc(p: PChar): boolean;
|
||||
var NewPos: integer;
|
||||
begin
|
||||
Result:=false;
|
||||
if Src='' then exit;
|
||||
NewPos:=PtrInt(PtrUInt(p))-PtrInt(PtrUInt(@Src[1]))+1;
|
||||
if (NewPos<1) or (NewPos>length(Src)) then exit;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
procedure TDirtySource.MoveCursorToPos(APos: integer);
|
||||
begin
|
||||
CurPos.StartPos:=APos;
|
||||
CurPos.EndPos:=APos;
|
||||
CurPos.Flag:=cafNone;
|
||||
end;
|
||||
|
||||
procedure TDirtySource.MoveCursorToPos(APos: PChar);
|
||||
|
||||
procedure RaiseSrcEmpty;
|
||||
begin
|
||||
RaiseCatchableException('[TDirtySource.MoveCursorToPos - PChar] Src empty');
|
||||
end;
|
||||
|
||||
procedure RaiseNotInSrc;
|
||||
begin
|
||||
RaiseCatchableException('[TDirtySource.MoveCursorToPos - PChar] Pos not in Src');
|
||||
end;
|
||||
|
||||
var NewPos: integer;
|
||||
begin
|
||||
if Src='' then
|
||||
RaiseSrcEmpty;
|
||||
NewPos:=PtrInt(PtrUInt(APos))-PtrInt(PtrUInt(@Src[1]))+1;
|
||||
if (NewPos<1) or (NewPos>length(Src)) then
|
||||
RaiseNotInSrc;
|
||||
MoveCursorToPos(NewPos);
|
||||
end;
|
||||
|
||||
function TDirtySource.CalcMemSize: PtrUInt;
|
||||
begin
|
||||
Result:=PtrUInt(InstanceSize)
|
||||
+MemSizeString(Src)
|
||||
+MemSizeString(GapSrc);
|
||||
end;
|
||||
|
||||
{ TCodeTreeNodeParseError }
|
||||
|
||||
constructor TCodeTreeNodeParseError.Create(ANode: TCodeTreeNode);
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
<PackageName Value="CodeTools"/>
|
||||
</Item1>
|
||||
</RequiredPackages>
|
||||
<Units Count="4">
|
||||
<Units Count="5">
|
||||
<Unit0>
|
||||
<Filename Value="finddeclaration.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
@ -49,6 +49,11 @@
|
||||
<Filename Value="../../../../../amat/test/test.inc"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit3>
|
||||
<Unit4>
|
||||
<Filename Value="scanexamples/commentsidentifiers.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="commentsidentifiers"/>
|
||||
</Unit4>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
||||
@ -48,6 +48,7 @@ begin
|
||||
writeln('Usage:');
|
||||
writeln(' ',ParamStr(0));
|
||||
writeln(' ',ParamStr(0),' <filename> <X> <Y>');
|
||||
Halt(1);
|
||||
end;
|
||||
|
||||
// setup the Options
|
||||
|
||||
@ -43,7 +43,7 @@ uses
|
||||
MemCheck,
|
||||
{$ENDIF}
|
||||
Classes, SysUtils, LazUTF8, LazDbgLog, LazFileCache, LazFileUtils,
|
||||
lazutf8classes, AVL_Tree, CodeToolsStrConsts;
|
||||
lazutf8classes, LazLogger, AVL_Tree, CodeToolsStrConsts;
|
||||
|
||||
type
|
||||
TFPCStreamSeekType = int64;
|
||||
@ -289,6 +289,9 @@ function dbgMemRange(P: PByte; Count: integer; Width: integer = 0): string; over
|
||||
function DbgS(const i1,i2,i3,i4: integer): string; overload;
|
||||
function DbgStr(const StringWithSpecialChars: string): string; overload;
|
||||
function DbgStr(const StringWithSpecialChars: string; StartPos, Len: PtrInt): string; overload;
|
||||
function DbgText(const StringWithSpecialChars: string;
|
||||
KeepLines: boolean = true // true = add LineEnding for each line break
|
||||
): string; overload;
|
||||
|
||||
function MemSizeString(const s: string): PtrUInt; inline;
|
||||
function MemSizeFPList(const List: TFPList): PtrUInt; inline;
|
||||
@ -2061,15 +2064,15 @@ var
|
||||
s: String;
|
||||
begin
|
||||
Result:=StringWithSpecialChars;
|
||||
i:=1;
|
||||
while (i<=length(Result)) do begin
|
||||
i:=length(Result);
|
||||
while (i>0) do begin
|
||||
case Result[i] of
|
||||
' '..#126: inc(i);
|
||||
' '..#126: ;
|
||||
else
|
||||
s:='#'+IntToStr(ord(Result[i]));
|
||||
Result:=copy(Result,1,i-1)+s+copy(Result,i+1,length(Result)-i);
|
||||
inc(i,length(s));
|
||||
ReplaceSubstring(Result,i,1,s);
|
||||
end;
|
||||
dec(i);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -2079,6 +2082,38 @@ begin
|
||||
Result:=dbgstr(copy(StringWithSpecialChars,StartPos,Len));
|
||||
end;
|
||||
|
||||
function DbgText(const StringWithSpecialChars: string; KeepLines: boolean
|
||||
): string;
|
||||
var
|
||||
i: Integer;
|
||||
s: String;
|
||||
LastChar: Char;
|
||||
c: Char;
|
||||
begin
|
||||
Result:=StringWithSpecialChars;
|
||||
i:=1;
|
||||
LastChar:=#0;
|
||||
while (i<=length(Result)) do begin
|
||||
c:=Result[i];
|
||||
case c of
|
||||
' '..#126: inc(i);
|
||||
else
|
||||
s:='#'+IntToStr(ord(c));
|
||||
if (c in [#10,#13]) then begin
|
||||
if ((LastChar in [#10,#13])
|
||||
or (i=length(Result)) or (not (Result[i+1] in [#10,#13])))
|
||||
then begin
|
||||
s+=LineEnding;
|
||||
c:=#0; // line break was handled
|
||||
end;
|
||||
end;
|
||||
ReplaceSubstring(Result,i,1,s);
|
||||
inc(i,length(s));
|
||||
end;
|
||||
LastChar:=c;
|
||||
end;
|
||||
end;
|
||||
|
||||
function MemSizeString(const s: string): PtrUInt;
|
||||
begin
|
||||
Result:=LazDbgLog.MemSizeString(s);
|
||||
|
||||
@ -1236,7 +1236,6 @@ begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TFindDeclarationTool.FindDeclarationOfIdentifier A CursorPos=X',dbgs(CursorPos.X),',Y',dbgs(CursorPos.Y));
|
||||
{$ENDIF}
|
||||
if DirtySrc<>nil then DirtySrc.Clear;
|
||||
BuildTreeAndGetCleanPos(trTillCursor,lsrEnd,CursorPos,CleanCursorPos,
|
||||
[btSetIgnoreErrorPos]);
|
||||
{$IFDEF CTDEBUG}
|
||||
@ -1410,12 +1409,13 @@ begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TFindDeclarationTool.FindDeclaration A CursorPos=X',dbgs(CursorPos.X),',Y',dbgs(CursorPos.Y));
|
||||
{$ENDIF}
|
||||
if DirtySrc<>nil then DirtySrc.Clear;
|
||||
BuildTreeAndGetCleanPos(trTillCursor,lsrEnd,CursorPos,CleanCursorPos,
|
||||
[btSetIgnoreErrorPos,btLoadDirtySource,btCursorPosOutAllowed]);
|
||||
[btSetIgnoreErrorPos,btCursorPosOutAllowed]);
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TFindDeclarationTool.FindDeclaration C CleanCursorPos=',dbgs(CleanCursorPos));
|
||||
{$ENDIF}
|
||||
//debugln(['TFindDeclarationTool.FindDeclaration ',dbgtext(copy(Src,CleanCursorPos-30,30)),'|',dbgtext(copy(Src,CleanCursorPos,30))]);
|
||||
|
||||
// find CodeTreeNode at cursor
|
||||
if (Tree.Root<>nil) and (Tree.Root.StartPos<=CleanCursorPos) then begin
|
||||
CursorNode:=BuildSubTreeAndFindDeepestNodeAtPos(CleanCursorPos,true);
|
||||
@ -1444,8 +1444,7 @@ begin
|
||||
CleanPosInFront:=1;
|
||||
CursorNode:=nil;
|
||||
end;
|
||||
if (not IsDirtySrcValid)
|
||||
and IsIncludeDirectiveAtPos(CleanCursorPos,CleanPosInFront,NewPos.Code)
|
||||
if IsIncludeDirectiveAtPos(CleanCursorPos,CleanPosInFront,NewPos.Code)
|
||||
then begin
|
||||
// include directive
|
||||
//DebugLn(['TFindDeclarationTool.FindDeclaration IsIncludeDirectiveAtPos']);
|
||||
@ -1464,8 +1463,7 @@ begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TFindDeclarationTool.FindDeclaration D CursorNode=',NodeDescriptionAsString(CursorNode.Desc),' HasChildren=',dbgs(CursorNode.FirstChild<>nil));
|
||||
{$ENDIF}
|
||||
if (not IsDirtySrcValid)
|
||||
and (CursorNode.Desc in [ctnUsesSection,ctnUseUnit]) then begin
|
||||
if (CursorNode.Desc in [ctnUsesSection,ctnUseUnit]) then begin
|
||||
// in uses section
|
||||
//DebugLn(['TFindDeclarationTool.FindDeclaration IsUsesSection']);
|
||||
Result:=FindDeclarationInUsesSection(CursorNode,CleanCursorPos,
|
||||
@ -1485,19 +1483,13 @@ begin
|
||||
CheckIfCursorInPropertyNode;
|
||||
// set cursor on identifier
|
||||
MoveCursorToCleanPos(CleanCursorPos);
|
||||
if IsDirtySrcValid then begin
|
||||
DirtySrc.SetCursorToIdentStartEndAtPosition;
|
||||
CursorAtIdentifier:=DirtySrc.CurPos.StartPos<DirtySrc.CurPos.EndPos;
|
||||
IdentifierStart:=DirtySrc.GetCursorSrcPos;
|
||||
end else begin
|
||||
GetIdentStartEndAtPosition(Src,CleanCursorPos,
|
||||
CurPos.StartPos,CurPos.EndPos);
|
||||
CursorAtIdentifier:=CurPos.StartPos<CurPos.EndPos;
|
||||
if CursorAtIdentifier then
|
||||
IdentifierStart:=@Src[CurPos.StartPos]
|
||||
else
|
||||
IdentifierStart:=PChar(Src);
|
||||
end;
|
||||
GetIdentStartEndAtPosition(Src,CleanCursorPos,
|
||||
CurPos.StartPos,CurPos.EndPos);
|
||||
CursorAtIdentifier:=CurPos.StartPos<CurPos.EndPos;
|
||||
if CursorAtIdentifier then
|
||||
IdentifierStart:=@Src[CurPos.StartPos]
|
||||
else
|
||||
IdentifierStart:=PChar(Src);
|
||||
if CursorAtIdentifier then begin
|
||||
// find declaration of identifier
|
||||
Params:=TFindDeclarationParams.Create;
|
||||
@ -1510,7 +1502,6 @@ begin
|
||||
if fsfSkipClassForward in SearchSmartFlags then
|
||||
Include(Params.Flags,fdfSkipClassForward);
|
||||
if not DirectSearch then begin
|
||||
// ToDo: DirtySrc
|
||||
Result:=FindDeclarationOfIdentAtParam(Params);
|
||||
end else begin
|
||||
Include(Params.Flags,fdfIgnoreCurContextNode);
|
||||
@ -5163,9 +5154,8 @@ begin
|
||||
ActivateGlobalWriteLock;
|
||||
try
|
||||
// build code tree
|
||||
if DirtySrc<>nil then DirtySrc.Clear;
|
||||
BuildTreeAndGetCleanPos(trTillCursor,lsrEnd,CursorPos,CleanCursorPos,
|
||||
[btSetIgnoreErrorPos,btLoadDirtySource,btCursorPosOutAllowed]);
|
||||
[btSetIgnoreErrorPos,btCursorPosOutAllowed]);
|
||||
// find CodeTreeNode at cursor
|
||||
if (Tree.Root<>nil) and (Tree.Root.StartPos<=CleanCursorPos) then
|
||||
CursorNode := BuildSubTreeAndFindDeepestNodeAtPos(CleanCursorPos, True)
|
||||
@ -5182,16 +5172,10 @@ begin
|
||||
end;
|
||||
// set cursor on identifier
|
||||
MoveCursorToCleanPos(CleanCursorPos);
|
||||
if IsDirtySrcValid then begin
|
||||
DirtySrc.SetCursorToIdentStartEndAtPosition;
|
||||
if DirtySrc.CurPos.StartPos >= DirtySrc.CurPos.EndPos then Exit;
|
||||
Identifier := DirtySrc.GetCursorSrcPos;
|
||||
end else begin
|
||||
GetIdentStartEndAtPosition(Src,CleanCursorPos,
|
||||
CurPos.StartPos,CurPos.EndPos);
|
||||
if CurPos.StartPos >= CurPos.EndPos then Exit;
|
||||
Identifier := @Src[CurPos.StartPos];
|
||||
end;
|
||||
GetIdentStartEndAtPosition(Src,CleanCursorPos,
|
||||
CurPos.StartPos,CurPos.EndPos);
|
||||
if CurPos.StartPos >= CurPos.EndPos then Exit;
|
||||
Identifier := @Src[CurPos.StartPos];
|
||||
// find declaration of identifier
|
||||
Params := TFindDeclarationParams.Create;
|
||||
try
|
||||
|
||||
@ -2347,8 +2347,7 @@ begin
|
||||
ReadPriorAtom;
|
||||
CurrentIdentifierList.StartAtomInFront:=CurPos;
|
||||
if (ilcfStartInStatement in CurrentIdentifierList.ContextFlags)
|
||||
and (not IsDirtySrcValid) then
|
||||
begin
|
||||
then begin
|
||||
// check if LValue
|
||||
if (CurPos.Flag in [cafSemicolon,cafEnd,cafColon])
|
||||
or UpAtomIs('BEGIN')
|
||||
@ -2370,7 +2369,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
// context behind
|
||||
if (IdentEndPos<SrcLen) and (not IsDirtySrcValid) then begin
|
||||
if (IdentEndPos<SrcLen) then begin
|
||||
MoveCursorToCleanPos(IdentEndPos);
|
||||
InFrontOfDirective:=(CurPos.StartPos<SrcLen) and (Src[CurPos.StartPos]='{')
|
||||
and (Src[CurPos.StartPos+1]='$');
|
||||
|
||||
@ -26,9 +26,6 @@
|
||||
resulting source is called the cleaned source. A link points from a position
|
||||
of the cleaned source to its position in the real source.
|
||||
The link list makes it possible to change scanned code in the source files.
|
||||
|
||||
ToDo:
|
||||
- macros
|
||||
}
|
||||
unit LinkScanner;
|
||||
|
||||
@ -44,7 +41,6 @@ unit LinkScanner;
|
||||
{$I codetools.inc}
|
||||
|
||||
{ $DEFINE ShowIgnoreErrorAfter}
|
||||
{ $DEFINE EnableIncludeSkippedCode}
|
||||
|
||||
// debugging
|
||||
{ $DEFINE ShowUpdateCleanedSrc}
|
||||
@ -95,7 +91,10 @@ type
|
||||
{ TSourceLink is used to map between the codefiles and the cleaned source }
|
||||
TSourceLinkKind = (
|
||||
slkCode,
|
||||
slkMissingIncludeFile
|
||||
slkMissingIncludeFile,
|
||||
slkSkipStart, // start of skipped code due to IFDEFs {#3
|
||||
slkSkipEnd, // end of skipped code due to IFDEFs #3}
|
||||
slkCompilerString // e.g. {$I %FPCVERSION%}
|
||||
);
|
||||
TSourceLinkKinds = set of TSourceLinkKind;
|
||||
PSourceLink = ^TSourceLink;
|
||||
@ -349,15 +348,15 @@ type
|
||||
function ReturnFromIncludeFileAndIsEnd: boolean;
|
||||
function ReadIdentifier: string;
|
||||
function ReadUpperIdentifier: string;
|
||||
procedure SkipSpace; {$IFDEF UseInline}inline;{$ENDIF}
|
||||
procedure SkipCurlyComment;
|
||||
procedure SkipLineComment;
|
||||
procedure SkipRoundComment;
|
||||
procedure ReadSpace; {$IFDEF UseInline}inline;{$ENDIF}
|
||||
procedure ReadCurlyComment;
|
||||
procedure ReadLineComment;
|
||||
procedure ReadRoundComment;
|
||||
procedure CommentEndNotFound;
|
||||
procedure EndComment; {$IFDEF UseInline}inline;{$ENDIF}
|
||||
procedure IncCommentLevel; {$IFDEF UseInline}inline;{$ENDIF}
|
||||
procedure DecCommentLevel; {$IFDEF UseInline}inline;{$ENDIF}
|
||||
procedure HandleDirectives;
|
||||
procedure HandleDirective;
|
||||
procedure UpdateCleanedSource(NewCopiedSrcPos: integer);
|
||||
function ReturnFromIncludeFile: boolean;
|
||||
function ParseKeyWord(StartPos, WordLen: integer; LastTokenType: TLSTokenType
|
||||
@ -387,7 +386,9 @@ type
|
||||
procedure SetCompilerMode(const AValue: TCompilerMode);
|
||||
procedure SkipTillEndifElse(SkippingUntil: TLSSkippingDirective);
|
||||
function InternalIfDirective: boolean;
|
||||
|
||||
procedure EndSkipping;
|
||||
procedure AddSkipComment(IsStart: boolean);
|
||||
|
||||
function IfdefDirective: boolean;
|
||||
function IfCDirective: boolean;
|
||||
function IfndefDirective: boolean;
|
||||
@ -425,6 +426,7 @@ type
|
||||
function MissingIncludeFilesNeedsUpdate: boolean;
|
||||
procedure ClearMissingIncludeFiles;
|
||||
|
||||
// code macros
|
||||
procedure AddMacroValue(MacroName: PChar;
|
||||
ValueStart, ValueEnd: integer);
|
||||
procedure ClearMacros;
|
||||
@ -623,6 +625,7 @@ function IndexOfCodeInUniqueList(ACode: Pointer;
|
||||
UniqueSortedCodeList: TFPList): integer;
|
||||
function dbgs(r: TLinkScannerRange): string; overload;
|
||||
function dbgs(const ModeSwitches: TCompilerModeSwitches): string; overload;
|
||||
function dbgs(k: TSourceLinkKind): string; overload;
|
||||
|
||||
implementation
|
||||
|
||||
@ -689,6 +692,17 @@ begin
|
||||
Result:='['+Result+']';
|
||||
end;
|
||||
|
||||
function dbgs(k: TSourceLinkKind): string;
|
||||
begin
|
||||
case k of
|
||||
slkCode: Result:='Code';
|
||||
slkMissingIncludeFile: Result:='MissingInc';
|
||||
slkSkipStart: Result:='SkipStart';
|
||||
slkSkipEnd: Result:='SkipEnd';
|
||||
else Result:='?';
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure AddCodeToUniqueList(ACode: Pointer; UniqueSortedCodeList: TFPList);
|
||||
var l,m,r: integer;
|
||||
begin
|
||||
@ -751,7 +765,14 @@ var
|
||||
NewCapacity: Integer;
|
||||
Link: PSourceLink;
|
||||
begin
|
||||
if FLinkCount=FLinkCapacity then begin
|
||||
if (LinkCount>0) and (FLinks[FLinkCount-1].CleanedPos=CleanedLen+1) then begin
|
||||
// last link is empty => remove
|
||||
{$IFDEF ShowUpdateCleanedSrc}
|
||||
Link:=@FLinks[FLinkCount-1];
|
||||
debugln(['TLinkScanner.AddLink removing empty link: ',dbgs(Link^.Kind)]);
|
||||
{$ENDIF}
|
||||
dec(FLinkCount);
|
||||
end else if FLinkCount=FLinkCapacity then begin
|
||||
NewCapacity:=FLinkCapacity*2;
|
||||
if NewCapacity<16 then NewCapacity:=16;
|
||||
ReAllocMem(FLinks,NewCapacity*SizeOf(TSourceLink));
|
||||
@ -878,8 +899,6 @@ function TLinkScanner.FindFirstSiblingLink(LinkIndex: integer): integer;
|
||||
if LinkIndex is in an include file, the result will be the first link of
|
||||
the include file. If the include file is included multiple times, it is
|
||||
treated as if they are different files.
|
||||
|
||||
ToDo: if include file includes itself, directly or indirectly
|
||||
}
|
||||
var
|
||||
LastIndex: integer;
|
||||
@ -1043,7 +1062,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLinkScanner.HandleDirectives;
|
||||
procedure TLinkScanner.HandleDirective;
|
||||
var DirStart, DirLen: integer;
|
||||
begin
|
||||
SrcPos:=CommentInnerStartPos+1;
|
||||
@ -1052,7 +1071,7 @@ begin
|
||||
inc(SrcPos);
|
||||
DirLen:=SrcPos-DirStart;
|
||||
if DirLen>255 then DirLen:=255;
|
||||
FDirectiveName:=UpperCaseStr(copy(Src,DirStart,DirLen));
|
||||
FDirectiveName:=copy(Src,DirStart,DirLen);
|
||||
DoDirective(DirStart,DirLen);
|
||||
SrcPos:=CommentEndPos;
|
||||
end;
|
||||
@ -1108,20 +1127,20 @@ begin
|
||||
'{' :
|
||||
begin
|
||||
SrcPos:=p-PChar(Src)+1;
|
||||
SkipCurlyComment;
|
||||
ReadCurlyComment;
|
||||
p:=@Src[SrcPos];
|
||||
end;
|
||||
'/':
|
||||
if p[1]='/' then begin
|
||||
SrcPos:=p-PChar(Src)+1;
|
||||
SkipLineComment;
|
||||
ReadLineComment;
|
||||
p:=@Src[SrcPos];
|
||||
end else
|
||||
break;
|
||||
'(':
|
||||
if p[1]='*' then begin
|
||||
SrcPos:=p-PChar(Src)+1;
|
||||
SkipRoundComment;
|
||||
ReadRoundComment;
|
||||
p:=@Src[SrcPos];
|
||||
end else
|
||||
break;
|
||||
@ -1397,13 +1416,12 @@ begin
|
||||
LastTokenType:=TokenType;
|
||||
end;
|
||||
finally
|
||||
if FSkippingDirectives=lssdNone then begin
|
||||
{$IFDEF ShowUpdateCleanedSrc}
|
||||
DebugLn('TLinkScanner.Scan UpdatePos=',DbgS(SrcPos-1));
|
||||
{$ENDIF}
|
||||
if SrcPos>CopiedSrcPos then
|
||||
UpdateCleanedSource(SrcPos-1);
|
||||
end else begin
|
||||
{$IFDEF ShowUpdateCleanedSrc}
|
||||
DebugLn('TLinkScanner.Scan UpdatePos=',DbgS(SrcPos-1));
|
||||
{$ENDIF}
|
||||
if (SrcPos>CopiedSrcPos) then
|
||||
UpdateCleanedSource(SrcPos-1);
|
||||
if FSkippingDirectives<>lssdNone then begin
|
||||
{$IFDEF ShowUpdateCleanedSrc}
|
||||
DebugLn(['TLinkScanner.Scan missing $ENDIF']);
|
||||
{$ENDIF}
|
||||
@ -1431,7 +1449,7 @@ begin
|
||||
FLinks[Index]:=Value;
|
||||
end;
|
||||
|
||||
procedure TLinkScanner.SkipCurlyComment;
|
||||
procedure TLinkScanner.ReadCurlyComment;
|
||||
// a normal pascal {} comment
|
||||
var
|
||||
p: PChar;
|
||||
@ -1469,11 +1487,12 @@ begin
|
||||
CommentInnerEndPos:=SrcPos-1;
|
||||
if (CommentLevel>0) then CommentEndNotFound;
|
||||
// handle compiler switches
|
||||
if Src[CommentInnerStartPos]='$' then HandleDirectives;
|
||||
if Src[CommentInnerStartPos]='$' then
|
||||
HandleDirective;
|
||||
EndComment;
|
||||
end;
|
||||
|
||||
procedure TLinkScanner.SkipLineComment;
|
||||
procedure TLinkScanner.ReadLineComment;
|
||||
// a // newline comment
|
||||
var
|
||||
p: PChar;
|
||||
@ -1494,7 +1513,7 @@ begin
|
||||
EndComment;
|
||||
end;
|
||||
|
||||
procedure TLinkScanner.SkipRoundComment;
|
||||
procedure TLinkScanner.ReadRoundComment;
|
||||
// a delphi comment (* *)
|
||||
var
|
||||
p: PChar;
|
||||
@ -1539,7 +1558,8 @@ begin
|
||||
CommentInnerEndPos:=SrcPos-2;
|
||||
if (CommentLevel>0) then CommentEndNotFound;
|
||||
// handle compiler switches
|
||||
if Src[CommentInnerStartPos]='$' then HandleDirectives;
|
||||
if Src[CommentInnerStartPos]='$' then
|
||||
HandleDirective;
|
||||
EndComment;
|
||||
end;
|
||||
|
||||
@ -2352,7 +2372,6 @@ begin
|
||||
else if InitialValues.IsDefined('WIN32') then
|
||||
FHiddenUsedUnits:='SYSWIN32';
|
||||
end;
|
||||
// ToDo: heaptrc
|
||||
if InitialValues.IsDefined(MacroUseLineInfo) then
|
||||
FHiddenUsedUnits:=FHiddenUsedUnits+',lineinfo'
|
||||
else if InitialValues.IsDefined(MacroUselnfodwrf) then
|
||||
@ -2433,20 +2452,24 @@ end;
|
||||
|
||||
function TLinkScanner.ShortSwitchDirective: boolean;
|
||||
// example: {$H+} or {$H+, R- comment}
|
||||
var
|
||||
c: Char;
|
||||
begin
|
||||
FDirectiveName:=CompilerSwitchesNames[FDirectiveName[1]];
|
||||
c:=UpChars[FDirectiveName[1]];
|
||||
FDirectiveName:=CompilerSwitchesNames[c];
|
||||
if FDirectiveName<>'' then begin
|
||||
if (SrcPos<=SrcLen) and (Src[SrcPos] in ['-','+']) then begin
|
||||
if Src[SrcPos]='-' then
|
||||
Values.Variables[FDirectiveName]:='0'
|
||||
else
|
||||
Values.Variables[FDirectiveName]:='1';
|
||||
inc(SrcPos);
|
||||
Result:=ReadNextSwitchDirective;
|
||||
end else begin
|
||||
if FDirectiveName<>CompilerSwitchesNames['I'] then
|
||||
Result:=LongSwitchDirective
|
||||
if c='I' then
|
||||
Result:=IncludeDirective
|
||||
else
|
||||
Result:=IncludeDirective;
|
||||
Result:=LongSwitchDirective;
|
||||
end;
|
||||
end else
|
||||
Result:=true;
|
||||
@ -2468,17 +2491,17 @@ begin
|
||||
case UpChars[p^] of
|
||||
'A':
|
||||
case UpChars[p[1]] of
|
||||
'L': if CompareIdentifiers(p,'ALIGN')=0 then Result:=true;
|
||||
'S': if CompareIdentifiers(p,'ASSERTIONS')=0 then Result:=true;
|
||||
'L': if CompareIdentifiers(p,'ALIGN')=0 then Result:=LongSwitchDirective;
|
||||
'S': if CompareIdentifiers(p,'ASSERTIONS')=0 then Result:=LongSwitchDirective;
|
||||
end;
|
||||
'B':
|
||||
if CompareIdentifiers(p,'BOOLEVAL')=0 then Result:=true;
|
||||
if CompareIdentifiers(p,'BOOLEVAL')=0 then Result:=LongSwitchDirective;
|
||||
'D':
|
||||
case UpChars[p[1]] of
|
||||
'E':
|
||||
case UpChars[p[2]] of
|
||||
'F': if CompareIdentifiers(p,'DEFINE')=0 then Result:=DefineDirective;
|
||||
'B': if CompareIdentifiers(p,'DEBUGINFO')=0 then Result:=true;
|
||||
'B': if CompareIdentifiers(p,'DEBUGINFO')=0 then Result:=LongSwitchDirective;
|
||||
end;
|
||||
end;
|
||||
'E':
|
||||
@ -2498,7 +2521,7 @@ begin
|
||||
if CompareIdentifiers(p,'ENDC')=0 then Result:=EndCDirective
|
||||
else if CompareIdentifiers(p,'ENDIF')=0 then Result:=EndIfDirective;
|
||||
'X':
|
||||
if CompareIdentifiers(p,'EXTENDEDSYNTAX')=0 then Result:=true;
|
||||
if CompareIdentifiers(p,'EXTENDEDSYNTAX')=0 then Result:=LongSwitchDirective;
|
||||
end;
|
||||
'I':
|
||||
case UpChars[p[1]] of
|
||||
@ -2514,36 +2537,36 @@ begin
|
||||
'N':
|
||||
if CompareIdentifiers(p,'INCLUDE')=0 then Result:=IncludeDirective
|
||||
else if CompareIdentifiers(p,'INCLUDEPATH')=0 then Result:=IncludePathDirective;
|
||||
'O': if CompareIdentifiers(p,'IOCHECKS')=0 then Result:=true;
|
||||
'O': if CompareIdentifiers(p,'IOCHECKS')=0 then Result:=LongSwitchDirective;
|
||||
end;
|
||||
'L':
|
||||
if CompareIdentifiers(p,'LOCALSYMBOLS')=0 then Result:=true
|
||||
else if CompareIdentifiers(p,'LONGSTRINGS')=0 then Result:=true;
|
||||
if CompareIdentifiers(p,'LOCALSYMBOLS')=0 then Result:=LongSwitchDirective
|
||||
else if CompareIdentifiers(p,'LONGSTRINGS')=0 then Result:=LongSwitchDirective;
|
||||
'M':
|
||||
if CompareIdentifiers(p,'MODE')=0 then Result:=ModeDirective
|
||||
else if CompareIdentifiers(p,'MODESWITCH')=0 then Result:=ModeSwitchDirective
|
||||
else if CompareIdentifiers(p,'MACRO')=0 then Result:=MacroDirective;
|
||||
'O':
|
||||
if CompareIdentifiers(p,'OPENSTRINGS')=0 then Result:=true
|
||||
else if CompareIdentifiers(p,'OVERFLOWCHECKS')=0 then Result:=true;
|
||||
if CompareIdentifiers(p,'OPENSTRINGS')=0 then Result:=LongSwitchDirective
|
||||
else if CompareIdentifiers(p,'OVERFLOWCHECKS')=0 then Result:=LongSwitchDirective;
|
||||
'R':
|
||||
if CompareIdentifiers(p,'RANGECHECKS')=0 then Result:=true
|
||||
else if CompareIdentifiers(p,'REFERENCEINFO')=0 then Result:=true;
|
||||
if CompareIdentifiers(p,'RANGECHECKS')=0 then Result:=LongSwitchDirective
|
||||
else if CompareIdentifiers(p,'REFERENCEINFO')=0 then Result:=LongSwitchDirective;
|
||||
'S':
|
||||
if CompareIdentifiers(p,'SETC')=0 then Result:=SetCDirective
|
||||
else if CompareIdentifiers(p,'STACKFRAMES')=0 then Result:=true;
|
||||
else if CompareIdentifiers(p,'STACKFRAMES')=0 then Result:=LongSwitchDirective;
|
||||
'T':
|
||||
if CompareIdentifiers(p,'THREADING')=0 then Result:=ThreadingDirective
|
||||
else if CompareIdentifiers(p,'TYPEADDRESS')=0 then Result:=true
|
||||
else if CompareIdentifiers(p,'TYPEINFO')=0 then Result:=true;
|
||||
else if CompareIdentifiers(p,'TYPEADDRESS')=0 then Result:=LongSwitchDirective
|
||||
else if CompareIdentifiers(p,'TYPEINFO')=0 then Result:=LongSwitchDirective;
|
||||
'U':
|
||||
if CompareIdentifiers(p,'UNDEF')=0 then Result:=UndefDirective;
|
||||
'V':
|
||||
if CompareIdentifiers(p,'VARSTRINGCHECKS')=0 then Result:=true;
|
||||
if CompareIdentifiers(p,'VARSTRINGCHECKS')=0 then Result:=LongSwitchDirective;
|
||||
end;
|
||||
end;
|
||||
end else begin
|
||||
// skipping code, but still have to read if directives
|
||||
// skipping code => read only IF directives
|
||||
case UpChars[p^] of
|
||||
'E':
|
||||
case UpChars[p[1]] of
|
||||
@ -2582,7 +2605,7 @@ function TLinkScanner.LongSwitchDirective: boolean;
|
||||
// example: {$ASSERTIONS ON comment}
|
||||
var ValStart: integer;
|
||||
begin
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
ValStart:=SrcPos;
|
||||
while (SrcPos<=SrcLen) and IsWordChar[Src[SrcPos]] do
|
||||
inc(SrcPos);
|
||||
@ -2594,9 +2617,9 @@ begin
|
||||
and (FDirectiveName='ASSERTIONS') then
|
||||
Values.Variables[FDirectiveName]:='PRELOAD'
|
||||
else if (FDirectiveName='LOCALSYMBOLS') then
|
||||
// ignore link object directive
|
||||
// ignore "localsymbols <something>"
|
||||
else if (FDirectiveName='RANGECHECKS') then
|
||||
// ignore link object directive
|
||||
// ignore "rangechecks <something>"
|
||||
else if (FDirectiveName='ALIGN') then
|
||||
// set record align size
|
||||
else begin
|
||||
@ -2610,7 +2633,7 @@ function TLinkScanner.MacroDirective: boolean;
|
||||
var
|
||||
ValStart: LongInt;
|
||||
begin
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
ValStart:=SrcPos;
|
||||
while (SrcPos<=SrcLen) and (IsWordChar[Src[SrcPos]]) do
|
||||
inc(SrcPos);
|
||||
@ -2630,7 +2653,7 @@ var ValStart: integer;
|
||||
AMode: TCompilerMode;
|
||||
ModeValid: boolean;
|
||||
begin
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
ValStart:=SrcPos;
|
||||
while (SrcPos<=SrcLen) and (IsWordChar[Src[SrcPos]]) do
|
||||
inc(SrcPos);
|
||||
@ -2669,7 +2692,7 @@ var
|
||||
ModeSwitch: TCompilerModeSwitch;
|
||||
s: TCompilerModeSwitches;
|
||||
begin
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
ValStart:=SrcPos;
|
||||
while (SrcPos<=SrcLen) and (IsIdentChar[Src[SrcPos]]) do
|
||||
inc(SrcPos);
|
||||
@ -2696,7 +2719,7 @@ function TLinkScanner.ThreadingDirective: boolean;
|
||||
var
|
||||
ValStart: integer;
|
||||
begin
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
ValStart:=SrcPos;
|
||||
while (SrcPos<=SrcLen) and (IsWordChar[Src[SrcPos]]) do
|
||||
inc(SrcPos);
|
||||
@ -2713,7 +2736,7 @@ end;
|
||||
function TLinkScanner.ReadNextSwitchDirective: boolean;
|
||||
var DirStart, DirLen: integer;
|
||||
begin
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
if (SrcPos<=SrcLen) and (Src[SrcPos]=',') then begin
|
||||
inc(SrcPos);
|
||||
DirStart:=SrcPos;
|
||||
@ -2721,7 +2744,7 @@ begin
|
||||
inc(SrcPos);
|
||||
DirLen:=SrcPos-DirStart;
|
||||
if DirLen>255 then DirLen:=255;
|
||||
FDirectiveName:=UpperCaseStr(copy(Src,DirStart,DirLen));
|
||||
FDirectiveName:=copy(Src,DirStart,DirLen);
|
||||
Result:=DoDirective(DirStart,DirLen);
|
||||
end else
|
||||
Result:=true;
|
||||
@ -2733,7 +2756,7 @@ var VariableName: string;
|
||||
begin
|
||||
inc(IfLevel);
|
||||
if FSkippingDirectives<>lssdNone then exit(true);
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
VariableName:=ReadUpperIdentifier;
|
||||
if (VariableName<>'') and (not Values.IsDefined(VariableName)) then
|
||||
SkipTillEndifElse(lssdTillElse);
|
||||
@ -2749,7 +2772,7 @@ begin
|
||||
Result:=InternalIfDirective;
|
||||
end;
|
||||
|
||||
procedure TLinkScanner.SkipSpace;
|
||||
procedure TLinkScanner.ReadSpace;
|
||||
begin
|
||||
while (SrcPos<=SrcLen) and (IsSpaceChar[Src[SrcPos]]) do inc(SrcPos);
|
||||
end;
|
||||
@ -2791,7 +2814,7 @@ var VariableName: string;
|
||||
begin
|
||||
inc(IfLevel);
|
||||
if FSkippingDirectives<>lssdNone then exit(true);
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
VariableName:=ReadUpperIdentifier;
|
||||
if (VariableName<>'') and (Values.IsDefined(VariableName)) then
|
||||
SkipTillEndifElse(lssdTillElse);
|
||||
@ -2810,8 +2833,11 @@ begin
|
||||
if IfLevel<=0 then
|
||||
RaiseAWithoutB;
|
||||
dec(IfLevel);
|
||||
if IfLevel<FSkipIfLevel then begin
|
||||
FSkippingDirectives:=lssdNone;
|
||||
if (IfLevel<FSkipIfLevel) and (FSkippingDirectives<>lssdNone) then begin
|
||||
{$IFDEF ShowUpdateCleanedSrc}
|
||||
debugln(['TLinkScanner.EndifDirective end skip']);
|
||||
{$ENDIF}
|
||||
EndSkipping;
|
||||
end;
|
||||
Result:=true;
|
||||
end;
|
||||
@ -2829,8 +2855,11 @@ begin
|
||||
if IfLevel<=0 then
|
||||
RaiseAWithoutB;
|
||||
dec(IfLevel);
|
||||
if IfLevel<FSkipIfLevel then begin
|
||||
FSkippingDirectives:=lssdNone;
|
||||
if (IfLevel<FSkipIfLevel) and (FSkippingDirectives<>lssdNone) then begin
|
||||
{$IFDEF ShowUpdateCleanedSrc}
|
||||
debugln(['TLinkScanner.EndCDirective end skip']);
|
||||
{$ENDIF}
|
||||
EndSkipping;
|
||||
end;
|
||||
Result:=true;
|
||||
end;
|
||||
@ -2847,8 +2876,11 @@ begin
|
||||
if IfLevel<=0 then
|
||||
RaiseAWithoutB;
|
||||
dec(IfLevel);
|
||||
if IfLevel<FSkipIfLevel then begin
|
||||
FSkippingDirectives:=lssdNone;
|
||||
if (IfLevel<FSkipIfLevel) and (FSkippingDirectives<>lssdNone) then begin
|
||||
{$IFDEF ShowUpdateCleanedSrc}
|
||||
debugln(['TLinkScanner.IfEndDirective end skip']);
|
||||
{$ENDIF}
|
||||
EndSkipping;
|
||||
end;
|
||||
Result:=true;
|
||||
end;
|
||||
@ -2866,12 +2898,15 @@ begin
|
||||
RaiseAWithoutB;
|
||||
case FSkippingDirectives of
|
||||
lssdNone:
|
||||
// last block was executed, skip all other
|
||||
SkipTillEndifElse(lssdTillEndIf);
|
||||
lssdTillElse:
|
||||
if IfLevel=FSkipIfLevel then
|
||||
FSkippingDirectives:=lssdNone;
|
||||
// else: continue skip;
|
||||
lssdTillEndIf: ; // continue skip
|
||||
if IfLevel=FSkipIfLevel then begin
|
||||
{$IFDEF ShowUpdateCleanedSrc}
|
||||
debugln(['TLinkScanner.ElseDirective skipped front, using ELSE part']);
|
||||
{$ENDIF}
|
||||
EndSkipping;
|
||||
end;
|
||||
end;
|
||||
Result:=true;
|
||||
end;
|
||||
@ -2890,12 +2925,15 @@ begin
|
||||
RaiseAWithoutB;
|
||||
case FSkippingDirectives of
|
||||
lssdNone:
|
||||
// last block was executed, skip all other
|
||||
SkipTillEndifElse(lssdTillEndIf);
|
||||
lssdTillElse:
|
||||
if IfLevel=FSkipIfLevel then
|
||||
FSkippingDirectives:=lssdNone;
|
||||
// else: continue skip;
|
||||
lssdTillEndIf: ; // continue skip
|
||||
if IfLevel=FSkipIfLevel then begin
|
||||
{$IFDEF ShowUpdateCleanedSrc}
|
||||
debugln(['TLinkScanner.ElseCDirective skipped front, using ELSEC part']);
|
||||
{$ENDIF}
|
||||
EndSkipping;
|
||||
end;
|
||||
end;
|
||||
Result:=true;
|
||||
end;
|
||||
@ -2911,13 +2949,15 @@ function TLinkScanner.ElseIfDirective: boolean;
|
||||
begin
|
||||
if IfLevel=0 then
|
||||
RaiseAWithoutB;
|
||||
if (FSkippingDirectives=lssdTillElse) and (IfLevel=FSkipIfLevel) then begin
|
||||
Result:=InternalIfDirective;
|
||||
end else begin
|
||||
if (FSkippingDirectives=lssdNone) then
|
||||
SkipTillEndifElse(lssdTillEndIf);
|
||||
Result:=true;
|
||||
case FSkippingDirectives of
|
||||
lssdNone:
|
||||
// last block was executed, skip all other
|
||||
SkipTillEndifElse(lssdTillEndIf);
|
||||
lssdTillElse:
|
||||
if IfLevel=FSkipIfLevel then
|
||||
exit(InternalIfDirective);
|
||||
end;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TLinkScanner.ElIfCDirective: boolean;
|
||||
@ -2932,13 +2972,15 @@ begin
|
||||
//DebugLn(['TLinkScanner.ElIfCDirective FSkippingDirectives=',ord(FSkippingDirectives),' IfLevel=',IfLevel]);
|
||||
if IfLevel=0 then
|
||||
RaiseAWithoutB;
|
||||
if (FSkippingDirectives=lssdTillElse) and (IfLevel=FSkipIfLevel) then begin
|
||||
Result:=InternalIfDirective;
|
||||
end else begin
|
||||
if (FSkippingDirectives=lssdNone) then
|
||||
SkipTillEndifElse(lssdTillEndIf);
|
||||
Result:=true;
|
||||
case FSkippingDirectives of
|
||||
lssdNone:
|
||||
// last block was executed, skip all other
|
||||
SkipTillEndifElse(lssdTillEndIf);
|
||||
lssdTillElse:
|
||||
if IfLevel=FSkipIfLevel then
|
||||
exit(InternalIfDirective);
|
||||
end;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TLinkScanner.DefineDirective: boolean;
|
||||
@ -2946,17 +2988,17 @@ function TLinkScanner.DefineDirective: boolean;
|
||||
var VariableName, NewValue: string;
|
||||
NamePos: LongInt;
|
||||
begin
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
NamePos:=SrcPos;
|
||||
VariableName:=ReadUpperIdentifier;
|
||||
if (VariableName<>'') then begin
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
if FMacrosOn and (SrcPos<SrcLen)
|
||||
and (Src[SrcPos]=':') and (Src[SrcPos+1]='=')
|
||||
then begin
|
||||
// makro => store the value
|
||||
inc(SrcPos,2);
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
NewValue:=copy(Src,SrcPos,CommentInnerEndPos-SrcPos);
|
||||
if CompareIdentifiers(PChar(NewValue),'false')=0 then
|
||||
NewValue:='0'
|
||||
@ -2976,7 +3018,7 @@ function TLinkScanner.UndefDirective: boolean;
|
||||
// {$undefine name}
|
||||
var VariableName: string;
|
||||
begin
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
VariableName:=ReadUpperIdentifier;
|
||||
if (VariableName<>'') then
|
||||
Values.Undefine(VariableName);
|
||||
@ -2987,15 +3029,15 @@ function TLinkScanner.SetCDirective: boolean;
|
||||
// {$setc name} or {$setc name:=value}
|
||||
var VariableName, NewValue: string;
|
||||
begin
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
VariableName:=ReadUpperIdentifier;
|
||||
if (VariableName<>'') then begin
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
if FMacrosOn and (SrcPos<SrcLen)
|
||||
and (Src[SrcPos]=':') and (Src[SrcPos+1]='=')
|
||||
then begin
|
||||
inc(SrcPos,2);
|
||||
SkipSpace;
|
||||
ReadSpace;
|
||||
NewValue:=copy(Src,SrcPos,CommentInnerEndPos-SrcPos);
|
||||
if CompareIdentifiers(PChar(NewValue),'false')=0 then
|
||||
NewValue:='0'
|
||||
@ -3016,7 +3058,23 @@ var IncFilename: string;
|
||||
DynamicExtension: Boolean;
|
||||
begin
|
||||
inc(SrcPos);
|
||||
if (Src[SrcPos]<>'%') then begin
|
||||
if (Src[SrcPos]='%') then begin
|
||||
// ToDo: insert string constant: %date%, %fpcversion%
|
||||
UpdateCleanedSource(CommentStartPos-1);
|
||||
// insert ''
|
||||
if 2>length(FCleanedSrc)-CleanedLen then begin
|
||||
// expand cleaned source string by at least 1024
|
||||
SetLength(FCleanedSrc,length(FCleanedSrc)+1024);
|
||||
end;
|
||||
AddLink(1,nil,slkCompilerString);
|
||||
inc(CleanedLen);
|
||||
FCleanedSrc[CleanedLen]:='''';
|
||||
inc(CleanedLen);
|
||||
FCleanedSrc[CleanedLen]:='''';
|
||||
// continue after directive
|
||||
CopiedSrcPos:=CommentEndPos-1;
|
||||
AddLink(CommentEndPos,Code);
|
||||
end else begin
|
||||
IncFilename:=Trim(copy(Src,SrcPos,CommentInnerEndPos-SrcPos));
|
||||
if (IncFilename<>'') and (IncFilename[1]='''')
|
||||
and (IncFilename[length(IncFilename)]='''') then
|
||||
@ -3481,10 +3539,35 @@ begin
|
||||
//DebugLn(['TLinkScanner.AddMacroSource END Token=',copy(Src,TokenStart,SrcPos-TokenStart)]);
|
||||
end;
|
||||
|
||||
procedure TLinkScanner.AddSkipComment(IsStart: boolean);
|
||||
begin
|
||||
//DebugLn(['TLinkScanner.AddSkipComment InFront="',dbgstr(CleanedSrc,CleanedLen-12,13),'" isstart=',IsStart]);
|
||||
// insert {#3 or #3}
|
||||
if 2>length(FCleanedSrc)-CleanedLen then begin
|
||||
// expand cleaned source string by at least 1024
|
||||
SetLength(FCleanedSrc,length(FCleanedSrc)+1024);
|
||||
end;
|
||||
if IsStart then begin
|
||||
AddLink(1,nil,slkSkipStart);
|
||||
inc(CleanedLen);
|
||||
FCleanedSrc[CleanedLen]:='{';
|
||||
inc(CleanedLen);
|
||||
FCleanedSrc[CleanedLen]:=#3;
|
||||
end else begin
|
||||
AddLink(1,nil,slkSkipEnd);
|
||||
inc(CleanedLen);
|
||||
FCleanedSrc[CleanedLen]:=#3;
|
||||
inc(CleanedLen);
|
||||
FCleanedSrc[CleanedLen]:='}';
|
||||
end;
|
||||
// SrcPos was not touched and still stands at the same position
|
||||
//DebugLn(['TLinkScanner.AddSkipComment END']);
|
||||
end;
|
||||
|
||||
function TLinkScanner.ReturnFromIncludeFile: boolean;
|
||||
var OldPos: TSourceLink;
|
||||
begin
|
||||
if FSkippingDirectives=lssdNone then begin
|
||||
if (SrcPos-1>CopiedSrcPos) then begin
|
||||
{$IFDEF ShowUpdateCleanedSrc}
|
||||
DebugLn('TLinkScanner.ReturnFromIncludeFile A UpdatePos=',DbgS(SrcPos-1));
|
||||
{$ENDIF}
|
||||
@ -3547,7 +3630,7 @@ end;
|
||||
function TLinkScanner.DoSourceTypeToken: boolean;
|
||||
// program, unit, library, package
|
||||
// unit unit1;
|
||||
// unit unit1 platform;
|
||||
// unit a.b.unit1 platform;
|
||||
// unit unit1 unimplemented;
|
||||
begin
|
||||
if ScannedRange<>lsrInit then exit(false);
|
||||
@ -3653,10 +3736,11 @@ begin
|
||||
|
||||
SrcPos:=CommentEndPos;
|
||||
{$IFDEF ShowUpdateCleanedSrc}
|
||||
DebugLn('TLinkScanner.SkipTillEndifElse A UpdatePos=',DbgS(SrcPos-1),' Src=',DbgStr(copy(Src,SrcPos-15,15))+'|'+DbgStr(copy(Src,SrcPos,15)));
|
||||
DebugLn('TLinkScanner.SkipTillEndifElse A UpdatePos=',DbgS(SrcPos-1),' Src=',DbgStr(Src,SrcPos-15,15)+'|'+DbgStr(Src,SrcPos,15));
|
||||
{$ENDIF}
|
||||
UpdateCleanedSource(SrcPos-1);
|
||||
|
||||
AddSkipComment(true);
|
||||
|
||||
// parse till $else, $elseif or $endif
|
||||
FSkipIfLevel:=IfLevel;
|
||||
if (SrcPos<=SrcLen) then begin
|
||||
@ -3666,14 +3750,14 @@ begin
|
||||
'{':
|
||||
begin
|
||||
SrcPos:=p-PChar(Src)+1;
|
||||
SkipCurlyComment;
|
||||
ReadCurlyComment;
|
||||
if (FSkippingDirectives=lssdNone) or (SrcPos>SrcLen) then break;
|
||||
p:=@Src[SrcPos];
|
||||
end;
|
||||
'/':
|
||||
if p[1]='/' then begin
|
||||
SrcPos:=p-PChar(Src)+1;
|
||||
SkipLineComment;
|
||||
ReadLineComment;
|
||||
if (FSkippingDirectives=lssdNone) or (SrcPos>SrcLen) then break;
|
||||
p:=@Src[SrcPos];
|
||||
end else
|
||||
@ -3681,7 +3765,7 @@ begin
|
||||
'(':
|
||||
if p[1]='*' then begin
|
||||
SrcPos:=p-PChar(Src)+1;
|
||||
SkipRoundComment;
|
||||
ReadRoundComment;
|
||||
if (FSkippingDirectives=lssdNone) or (SrcPos>SrcLen) then break;
|
||||
p:=@Src[SrcPos];
|
||||
end else
|
||||
@ -3696,10 +3780,11 @@ begin
|
||||
end;
|
||||
#0:
|
||||
begin
|
||||
// FPC allows that corresponding IFDEF and ENDIF are in different files
|
||||
SrcPos:=p-PChar(Src)+1;
|
||||
if (SrcPos>SrcLen) then begin
|
||||
if not ReturnFromIncludeFile then begin
|
||||
CommentStartPos:=0;
|
||||
CopiedSrcPos:=SrcLen+1;
|
||||
break;
|
||||
end;
|
||||
p:=@Src[SrcPos];
|
||||
@ -3711,10 +3796,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
SrcPos:=p-PChar(Src)+1;
|
||||
end;
|
||||
if CommentStartPos>0 then begin
|
||||
CopiedSrcPos:=CommentStartPos-1;
|
||||
AddLink(CommentStartPos,Code);
|
||||
end else begin
|
||||
CopiedSrcPos:=SrcLen+1;
|
||||
end;
|
||||
@ -3740,24 +3821,60 @@ begin
|
||||
end;
|
||||
|
||||
function TLinkScanner.InternalIfDirective: boolean;
|
||||
// {$if expression} or {$ifc expression} or indirectly called by {$elifc expression}
|
||||
// {$if expression} or {$ifc expression}
|
||||
// or indirectly called by {$elifc expression} or {$elseif expression}
|
||||
|
||||
procedure RaiseMissingExpr;
|
||||
begin
|
||||
RaiseException('missing expression');
|
||||
end;
|
||||
|
||||
var
|
||||
ExprResult: Boolean;
|
||||
begin
|
||||
//DebugLn(['TLinkScanner.InternalIfDirective FSkippingDirectives=',ord(FSkippingDirectives),' IfLevel=',IfLevel]);
|
||||
inc(SrcPos);
|
||||
if SrcPos>SrcLen then
|
||||
RaiseMissingExpr;
|
||||
ExprResult:=Values.EvalBoolean(@Src[SrcPos],CommentInnerEndPos-SrcPos);
|
||||
Result:=true;
|
||||
//DebugLn(['TLinkScanner.InternalIfDirective ExprResult=',ExprResult]);
|
||||
if Values.ErrorPosition>=0 then begin
|
||||
inc(SrcPos,Values.ErrorPosition);
|
||||
RaiseException(Values.ErrorMsg)
|
||||
end else if ExprResult then
|
||||
FSkippingDirectives:=lssdNone
|
||||
else
|
||||
end else if ExprResult then begin
|
||||
// expression evaluates to true => stop skipping and parse block
|
||||
if FSkippingDirectives<>lssdNone then begin
|
||||
{$IFDEF ShowUpdateCleanedSrc}
|
||||
debugln(['TLinkScanner.InternalIfDirective skipped front, using ELIFC part']);
|
||||
{$ENDIF}
|
||||
EndSkipping;
|
||||
end;
|
||||
end else
|
||||
// expression evaluates to false => skip this block
|
||||
SkipTillEndifElse(lssdTillElse);
|
||||
end;
|
||||
|
||||
procedure TLinkScanner.EndSkipping;
|
||||
|
||||
procedure ErrorNotSkipping;
|
||||
begin
|
||||
debugln(['ErrorNotSkipping internal error, please report this bug']);
|
||||
CTDumpStack;
|
||||
end;
|
||||
|
||||
begin
|
||||
if FSkippingDirectives=lssdNone then begin
|
||||
ErrorNotSkipping;
|
||||
exit;
|
||||
end;
|
||||
FSkippingDirectives:=lssdNone;
|
||||
UpdateCleanedSource(CommentStartPos-1);
|
||||
AddSkipComment(false);
|
||||
AddLink(CommentStartPos,Code);
|
||||
FSkipIfLevel:=-1;
|
||||
end;
|
||||
|
||||
function TLinkScanner.CursorToCleanPos(ACursorPos: integer; ACode: pointer;
|
||||
out ACleanPos: integer): integer;
|
||||
// 0=valid CleanPos
|
||||
|
||||
@ -106,7 +106,6 @@ type
|
||||
TBuildTreeFlag = (
|
||||
btSetIgnoreErrorPos,
|
||||
btKeepIgnoreErrorPos,
|
||||
btLoadDirtySource,
|
||||
btCursorPosOutAllowed
|
||||
);
|
||||
TBuildTreeFlags = set of TBuildTreeFlag;
|
||||
@ -4877,8 +4876,6 @@ var
|
||||
Node: TCodeTreeNode;
|
||||
DeleteNode: TCodeTreeNode;
|
||||
begin
|
||||
DirtySrc.Free;
|
||||
DirtySrc:=nil;
|
||||
// update scanned code
|
||||
if FLastScannerChangeStep=Scanner.ChangeStep then begin
|
||||
if LastErrorValid then
|
||||
@ -5134,10 +5131,6 @@ begin
|
||||
CaretType:=CaretToCleanPos(CursorPos, CleanCursorPos);
|
||||
if (CaretType=0) or (CaretType=-1) then begin
|
||||
BuildSubTree(CleanCursorPos);
|
||||
if (CaretType=-1) and (btLoadDirtySource in BuildTreeFlags) then begin
|
||||
// cursor position lies in dead code (skipped code between IFDEF/ENDIF)
|
||||
LoadDirtySource(CursorPos);
|
||||
end;
|
||||
exit;
|
||||
end
|
||||
else if (CaretType=-2) or (not (btCursorPosOutAllowed in BuildTreeFlags)) then
|
||||
|
||||
@ -816,7 +816,7 @@ begin
|
||||
dec(BaseDirLen);
|
||||
if BaseDirLen=0 then exit;
|
||||
|
||||
//WriteLn('CreateRelativePath START ',copy(CmpBaseDirectory,1,BaseDirLen),' ',copy(CmpFilename,1,FileNameLength));
|
||||
//DebugLn(['CreateRelativePath START ',copy(CmpBaseDirectory,1,BaseDirLen),' ',copy(CmpFilename,1,FileNameLength)]);
|
||||
|
||||
// count shared directories
|
||||
p:=1;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user