codetools: use global changesteps for quick updateneeded checks

git-svn-id: trunk@29787 -
This commit is contained in:
mattias 2011-03-10 22:22:47 +00:00
parent 06da501b26
commit 517bd4b789
10 changed files with 180 additions and 147 deletions

View File

@ -283,6 +283,7 @@ begin
inherited Create;
FItems:=TAVLTree.Create(@CompareCodeBuffers);
FIncludeLinks:=TAVLTree.Create(@CompareIncludedByLink);
FChangeStamp:=CTInvalidChangeStamp64;
end;
destructor TCodeCache.Destroy;
@ -969,10 +970,7 @@ end;
procedure TCodeCache.IncreaseChangeStamp;
begin
if FChangeStamp<high(FChangeStamp) then
inc(FChangeStamp)
else
FChangeStamp:=low(FChangeStamp);
CTIncreaseChangeStamp64(FChangeStamp);
end;
procedure TCodeCache.WriteAllFileNames;

View File

@ -147,8 +147,8 @@ type
Code: TCodeBuffer; GoToMainCode: boolean): TFindDeclarationTool;
function OnGetDirectoryCache(const ADirectory: string): TCTDirectoryCache;
procedure OnToolSetWriteLock(Lock: boolean);
procedure OnToolGetWriteLockInfo(out WriteLockIsSet: boolean;
out WriteLockStep: integer);
procedure OnToolGetChangeSteps(out SourcesChangeStep, FilesChangeStep,
InitValuesChangeStep: int64);
function OnParserProgress(Tool: TCustomCodeTool): boolean;
procedure OnToolTreeChange(Tool: TCustomCodeTool; NodesDeleting: boolean);
function OnScannerProgress(Sender: TLinkScanner): boolean;
@ -1245,7 +1245,7 @@ begin
Code.Scanner:=TLinkScanner.Create;
Code.Scanner.OnGetInitValues:=@OnScannerGetInitValues;
Code.Scanner.OnSetGlobalWriteLock:=@OnToolSetWriteLock;
Code.Scanner.OnGetGlobalWriteLockInfo:=@OnToolGetWriteLockInfo;
Code.Scanner.OnGetGlobalChangeSteps:=@OnToolGetChangeSteps;
Code.Scanner.OnProgress:=@OnScannerProgress;
end;
end;
@ -5032,7 +5032,6 @@ begin
TCodeTool(Result).OnGetSrcPathForCompiledUnit:=@DoOnGetSrcPathForCompiledUnit;
TCodeTool(Result).OnGetMethodName:=@OnInternalGetMethodName;
Result.OnSetGlobalWriteLock:=@OnToolSetWriteLock;
Result.OnGetGlobalWriteLockInfo:=@OnToolGetWriteLockInfo;
Result.OnTreeChange:=@OnToolTreeChange;
TCodeTool(Result).OnParserProgress:=@OnParserProgress;
end;
@ -5183,14 +5182,6 @@ begin
NodesDeletedStep:=FCodeTreeNodesDeletedStep;
end;
procedure TCodeToolManager.OnToolGetWriteLockInfo(out WriteLockIsSet: boolean;
out WriteLockStep: integer);
begin
WriteLockIsSet:=FWriteLockCount>0;
WriteLockStep:=FWriteLockStep;
//DebugLn(' FWriteLockCount=',FWriteLockCount,' FWriteLockStep=',FWriteLockStep);
end;
function TCodeToolManager.GetResourceTool: TResourceCodeTool;
begin
if FResourceTool=nil then FResourceTool:=TResourceCodeTool.Create;
@ -5332,6 +5323,14 @@ begin
if Lock then ActivateWriteLock else DeactivateWriteLock;
end;
procedure TCodeToolManager.OnToolGetChangeSteps(out SourcesChangeStep,
FilesChangeStep, InitValuesChangeStep: int64);
begin
SourcesChangeStep:=SourceCache.ChangeStamp;
FilesChangeStep:=FileStateCache.TimeStamp;
InitValuesChangeStep:=DefineTree.ChangeStep;
end;
procedure TCodeToolManager.ConsistencyCheck;
var
CurResult: LongInt;

View File

@ -135,7 +135,6 @@ type
private
FLastProgressPos: integer;
FNodesDeletedChangeStep: integer;
FOnGetGlobalWriteLockInfo: TOnGetWriteLockInfo;
FOnParserProgress: TOnParserProgress;
FOnSetGlobalWriteLock: TOnSetWriteLock;
FScanner: TLinkScanner;
@ -235,7 +234,7 @@ type
StopAtDirectives: boolean = true; SkipEmptyLines: boolean = false): integer;
function UpdateNeeded(Range: TLinkScannerRange): boolean;
function UpdateNeeded(OnlyInterfaceNeeded: boolean): boolean; deprecated;
function UpdateNeeded(OnlyInterfaceNeeded: boolean): boolean; deprecated; // use UpdateNeeded(lsrImplementationStart) or UpdateNeeded(lsrEnd)
procedure BeginParsing(Range: TLinkScannerRange); virtual;
procedure BeginParsingAndGetCleanPos(
Range: TLinkScannerRange; CursorPos: TCodeXYPosition;
@ -312,8 +311,6 @@ type
// write lock
procedure ActivateGlobalWriteLock; virtual;
procedure DeactivateGlobalWriteLock; virtual;
property OnGetGlobalWriteLockInfo: TOnGetWriteLockInfo
read FOnGetGlobalWriteLockInfo write FOnGetGlobalWriteLockInfo;
property OnSetGlobalWriteLock: TOnSetWriteLock
read FOnSetGlobalWriteLock write FOnSetGlobalWriteLock;

View File

@ -377,7 +377,7 @@ type
FFirstDefineTemplate: TDefineTemplate;
FCache: TAVLTree; // tree of TDirectoryDefines
FDefineStrings: TStringTree;
FChangeStep: integer;
FChangeStep: int64;
FErrorDescription: string;
FErrorTemplate: TDefineTemplate;
FMacroFunctions: TKeyWordFunctionList;
@ -406,7 +406,7 @@ type
public
property RootTemplate: TDefineTemplate
read FFirstDefineTemplate write FFirstDefineTemplate;
property ChangeStep: integer read FChangeStep;
property ChangeStep: int64 read FChangeStep;
property ErrorTemplate: TDefineTemplate read FErrorTemplate;
property ErrorDescription: string read FErrorDescription;
property OnGetVirtualDirectoryAlias: TOnGetVirtualDirectoryAlias
@ -3710,6 +3710,7 @@ end;
constructor TDefineTree.Create;
begin
inherited Create;
FChangeStep:=CTInvalidChangeStamp64;
FFirstDefineTemplate:=nil;
FCache:=TAVLTree.Create(@CompareDirectoryDefines);
FDefineStrings:=TStringTree.Create;
@ -4424,10 +4425,7 @@ end;
procedure TDefineTree.IncreaseChangeStep;
begin
if FChangeStep<>$7fffffff then
inc(FChangeStep)
else
FChangeStep:=-$7fffffff;
CTIncreaseChangeStamp64(FChangeStep);
if DirectoryCachePool<>nil then DirectoryCachePool.IncreaseConfigTimeStamp;
end;

View File

@ -1,10 +1,13 @@
#!/bin/bash
# do not include error.h - it only contains c macros for debugging
# do not include gerror.h - it only contains c macros for debugging
# do not include gslice.h, gmem.h - it only contains c macros for fast mem allocation
dir=~/cpp/gtk3/glib/glib
./h2pastest -uG_BEGIN_DECLS -uG_END_DECLS -uG_GNUC_CONST -dG_CONST_RETURN=const \
-uGLIB_VAR -uG_INLINE_FUNC -uG_GNUC_MAY_ALIAS -uG_GNUC_MALLOC \
-uG_GNUC_WARN_UNUSED_RESULT -uG_GNUC_NULL_TERMINATED \
-uG_GNUC_PURE \
$dir/glib.h \
$dir/galloca.h \
$dir/garray.h \
@ -43,7 +46,6 @@ dir=~/cpp/gtk3/glib/glib
$dir/gmain.h \
$dir/gmappedfile.h \
$dir/gmarkup.h \
$dir/gmem.h \
$dir/gmessages.h \
$dir/gmirroringtable.h \
$dir/gnode.h \
@ -63,7 +65,6 @@ dir=~/cpp/gtk3/glib/glib
$dir/gscripttable.h \
$dir/gsequence.h \
$dir/gshell.h \
$dir/gslice.h \
$dir/gslist.h \
$dir/gspawn.h \
$dir/gstdio.h \

View File

@ -251,7 +251,7 @@ function FileIsTextCached(const AFilename: string): boolean;
function FileAgeCached(const AFileName: string): Longint;
function FileAgeToStr(aFileAge: longint): string;
procedure InvalidateFileStateCache(const Filename: string = '');
procedure InvalidateFileStateCache(const Filename: string = ''); inline;
function CompareFileStateItems(Data1, Data2: Pointer): integer;
function CompareFilenameWithFileStateCacheItem(Key, Data: Pointer): integer;
@ -3139,7 +3139,8 @@ end;
constructor TFileStateCache.Create;
begin
FFiles:=TAVLTree.Create(@CompareFileStateItems);
FTimeStamp:=1; // one higher than default for new files
FTimeStamp:=CTInvalidChangeStamp64;
CTIncreaseChangeStamp64(FTimeStamp); // one higher than default for new files
end;
destructor TFileStateCache.Destroy;
@ -3180,10 +3181,7 @@ begin
if Self=nil then exit;
if AFilename='' then begin
// invalidate all
if FTimeStamp<high(FTimeStamp) then
inc(FTimeStamp)
else
FTimeStamp:=low(FTimeStamp);
CTIncreaseChangeStamp64(FTimeStamp);
for i:=0 to length(FChangeTimeStampHandler)-1 do
FChangeTimeStampHandler[i](Self);
end else begin

View File

@ -573,13 +573,13 @@ type
FOnGetSrcPathForCompiledUnit: TOnGetSrcPathForCompiledUnit;
FOnGetUnitSourceSearchPath: TOnGetSearchPath;
FFirstNodeCache: TCodeTreeNodeCache;
FLastNodeCachesGlobalWriteLockStep: integer;
FRootNodeCache: TCodeTreeNodeCache;
FFirstBaseTypeCache: TBaseTypeCache;
FDependentCodeTools: TAVLTree;// the codetools, that depend on this codetool
FDependsOnCodeTools: TAVLTree;// the codetools, that this codetool depends on
FClearingDependentNodeCaches: boolean;
FCheckingNodeCacheDependencies: boolean;
FSourcesChangeStep, FFilesChangeStep, FInitValuesChangeStep: int64;
{$IFDEF DebugPrefix}
DebugPrefix: string;
procedure IncPrefix;
@ -619,7 +619,6 @@ type
protected
// node caches
procedure DoDeleteNodes(StartNode: TCodeTreeNode); override;
function NodeCacheGlobalWriteLockStepDidNotChange: boolean;
function CheckDependsOnNodeCaches(CheckedTools: TAVLTree = nil): boolean;
procedure ClearNodeCaches(Force: boolean);
procedure ClearDependentNodeCaches;
@ -746,6 +745,7 @@ type
ExceptionOnNotFound: boolean): TFindDeclarationTool;
function CheckDirectoryCache: boolean;
public
constructor Create;
destructor Destroy; override;
procedure ConsistencyCheck; override;
procedure CalcMemSize(Stats: TCTMemStats); override;
@ -8797,6 +8797,14 @@ begin
Result:=FDirectoryCache<>nil;
end;
constructor TFindDeclarationTool.Create;
begin
inherited Create;
FSourcesChangeStep:=CTInvalidChangeStamp64;
FFilesChangeStep:=CTInvalidChangeStamp64;
FInitValuesChangeStep:=CTInvalidChangeStamp64;
end;
procedure TFindDeclarationTool.DoDeleteNodes(StartNode: TCodeTreeNode);
begin
ClearNodeCaches(true);
@ -8807,49 +8815,32 @@ begin
inherited DoDeleteNodes(StartNode);
end;
function TFindDeclarationTool.NodeCacheGlobalWriteLockStepDidNotChange: boolean;
// checks if a node cache check is in the same GlobalWriteLockStep
// returns true if _no_ update is needed
// returns false, if further checks are needed
var
GlobalWriteLockIsSet: boolean;
GlobalWriteLockStep: integer;
begin
Result:=false;
if Assigned(OnGetGlobalWriteLockInfo) then begin
OnGetGlobalWriteLockInfo(GlobalWriteLockIsSet,GlobalWriteLockStep);
if GlobalWriteLockIsSet then begin
// The global write lock is set. That means, input variables and code
// are frozen for all codetools and scanners, and therefore also for all
// node caches
if (FLastNodeCachesGlobalWriteLockStep=GlobalWriteLockStep) then begin
// source and values did not change since last NodeCache check
Result:=true;
end else begin
// this is the first check in this GlobalWriteLockStep
FLastNodeCachesGlobalWriteLockStep:=GlobalWriteLockStep;
// proceed normally ...
end;
end;
end;
{$IFDEF ShowCacheDependencies}
DebugLn('[TFindDeclarationTool.NodeCacheGlobalWriteLockStepDidNotChange] Result=',
DbgS(Result),' ',MainFilename);
{$ENDIF}
end;
function TFindDeclarationTool.CheckDependsOnNodeCaches
(CheckedTools: TAVLTree = nil): boolean;
function TFindDeclarationTool.CheckDependsOnNodeCaches(
CheckedTools: TAVLTree = nil): boolean;
var
ANode: TAVLTreeNode;
ATool: TFindDeclarationTool;
FreeCheckedTools: Boolean;
SourcesChangeStep, FilesChangeStep, InitValuesChangeStep: int64;
begin
Result:=false;
//debugln(['TFindDeclarationTool.CheckDependsOnNodeCaches ',MainFilename,' FDependsOnCodeTools=',FDependsOnCodeTools]);
if (FDependsOnCodeTools=nil) or FCheckingNodeCacheDependencies
or NodeCacheGlobalWriteLockStepDidNotChange
then exit;
if (FDependsOnCodeTools=nil) or FCheckingNodeCacheDependencies then exit;
if Scanner=nil then exit;
if Assigned(Scanner.OnGetGlobalChangeSteps) then begin
// check if any sources or values have changed
Scanner.OnGetGlobalChangeSteps(SourcesChangeStep,FilesChangeStep,
InitValuesChangeStep);
if (SourcesChangeStep=FSourcesChangeStep)
and (FilesChangeStep=FFilesChangeStep)
and (InitValuesChangeStep=FInitValuesChangeStep) then
// all sources and values are the same =>
exit;
FSourcesChangeStep:=SourcesChangeStep;
FFilesChangeStep:=FilesChangeStep;
FInitValuesChangeStep:=InitValuesChangeStep;
end;
if (CheckedTools<>nil) and (CheckedTools.Find(Self)<>nil) then exit;
{$IFDEF ShowCacheDependencies}
@ -8914,10 +8905,6 @@ begin
DbgS(Force),' ',MainFilename);
{$ENDIF}
// quick check: check if in the same GlobalWriteLockStep
if (not Force) and NodeCacheGlobalWriteLockStepDidNotChange then
exit;
// clear node caches
while FFirstNodeCache<>nil do begin
NodeCache:=FFirstNodeCache;
@ -8944,7 +8931,8 @@ var
ANode: TAVLTreeNode;
DependentTool: TFindDeclarationTool;
begin
if (FDependentCodeTools=nil) or FClearingDependentNodeCaches then exit;
if (FDependentCodeTools=nil) or (FDependentCodeTools.Count=0)
or FClearingDependentNodeCaches then exit;
FClearingDependentNodeCaches:=true;
{$IFDEF ShowCacheDependencies}
DebugLn('[TFindDeclarationTool.ClearDependentNodeCaches] ',MainFilename);
@ -8967,7 +8955,7 @@ var
ANode: TAVLTreeNode;
DependOnTool: TFindDeclarationTool;
begin
if FDependsOnCodeTools=nil then exit;
if (FDependsOnCodeTools=nil) or (FDependsOnCodeTools.Count=0) then exit;
{$IFDEF ShowCacheDependencies}
DebugLn('[TFindDeclarationTool.ClearDependsOnToolRelationships] ',MainFilename);
{$ENDIF}

View File

@ -82,8 +82,8 @@ type
out ChangeStep: integer): TExpressionEvaluator of object;
TOnIncludeCode = procedure(ParentCode, IncludeCode: Pointer) of object;
TOnSetWriteLock = procedure(Lock: boolean) of object;
TOnGetWriteLockInfo = procedure(out WriteLockIsSet: boolean;
out WriteLockStep: integer) of object;
TLSOnGetGlobalChangeSteps = procedure(out SourcesChangeStep, FilesChangeStep,
InitValuesChangeStep: int64) of object;
{ TSourceLink is used to map between the codefiles and the cleaned source }
PSourceLink = ^TSourceLink;
@ -226,6 +226,14 @@ type
constructor Create(ASender: TLinkScanner; const AMessage: string;
ABuffer: Pointer; ABufferPos: integer);
end;
TLinkScannerState = (
lssSourcesChanged, // used source buffers changed
lssInitValuesChanged, // used init values changed
lssFilesChanged, // used files on disk changed
lssIgnoreMissingIncludeFiles
);
TLinkScannerStates = set of TLinkScannerState;
{ TLinkScanner }
@ -254,13 +262,13 @@ type
FMainSourceFilename: string;
FMainCode: pointer;
FScanTill: TLinkScannerRange;
FIgnoreMissingIncludeFiles: boolean;
FNestedComments: boolean;
FForceUpdateNeeded: boolean;
FStates: TLinkScannerStates;
// global write lock
FLastGlobalWriteLockStep: integer;
FOnGetGlobalWriteLockInfo: TOnGetWriteLockInfo;
FOnSetGlobalWriteLock: TOnSetWriteLock;
FGlobalSourcesChangeStep: int64;
FGlobalFilesChangeStep: int64;
FGlobalInitValuesChangeStep: int64;
function GetLinks(Index: integer): TSourceLink;
procedure SetLinks(Index: integer; const Value: TSourceLink);
procedure SetSource(ACode: Pointer); // set current source
@ -269,6 +277,7 @@ type
procedure IncreaseChangeStep;
procedure SetMainCode(const Value: pointer);
procedure SetScanTill(const Value: TLinkScannerRange);
function GetIgnoreMissingIncludeFiles: boolean;
procedure SetIgnoreMissingIncludeFiles(const Value: boolean);
function TokenIs(const AToken: shortstring): boolean;
function UpTokenIs(const AToken: shortstring): boolean;
@ -314,6 +323,7 @@ type
FMacrosOn: boolean;
FMissingIncludeFiles: TMissingIncludeFiles;
FIncludeStack: TFPList; // list of TSourceLink
FOnGetGlobalChangeSteps: TLSOnGetGlobalChangeSteps;
FSkippingDirectives: TLSSkippingDirective;
FSkipIfLevel: integer;
FCompilerMode: TCompilerMode;
@ -455,8 +465,8 @@ type
// global write lock
procedure ActivateGlobalWriteLock;
procedure DeactivateGlobalWriteLock;
property OnGetGlobalWriteLockInfo: TOnGetWriteLockInfo
read FOnGetGlobalWriteLockInfo write FOnGetGlobalWriteLockInfo;
property OnGetGlobalChangeSteps: TLSOnGetGlobalChangeSteps
read FOnGetGlobalChangeSteps write FOnGetGlobalChangeSteps;
property OnSetGlobalWriteLock: TOnSetWriteLock
read FOnSetGlobalWriteLock write FOnSetGlobalWriteLock;
@ -477,7 +487,7 @@ type
read FOnIncludeCode write FOnIncludeCode;
property OnProgress: TLinkScannerProgress
read FOnProgress write FOnProgress;
property IgnoreMissingIncludeFiles: boolean read FIgnoreMissingIncludeFiles
property IgnoreMissingIncludeFiles: boolean read GetIgnoreMissingIncludeFiles
write SetIgnoreMissingIncludeFiles;
property InitialValues: TExpressionEvaluator
read FInitValues write FInitValues;
@ -1216,6 +1226,12 @@ begin
{$ENDIF}
ScanTill:=Range;
Clear;
if Assigned(OnGetGlobalChangeSteps) then
OnGetGlobalChangeSteps(FGlobalSourcesChangeStep,FGlobalFilesChangeStep,
FGlobalInitValuesChangeStep);
FStates:=FStates-[lssSourcesChanged,lssFilesChanged,lssInitValuesChanged];
{$IFDEF CTDEBUG}
DebugLn('TLinkScanner.Scan B ');
{$ENDIF}
@ -1236,7 +1252,7 @@ begin
IfLevel:=0;
FSkippingDirectives:=lssdNone;
//DebugLn('TLinkScanner.Scan D --------');
// initialize Defines
if Assigned(FOnGetInitValues) then
FInitValues.Assign(FOnGetInitValues(FMainCode,FInitValuesChangeStep));
@ -1312,7 +1328,6 @@ begin
end;
end;
IncreaseChangeStep;
FForceUpdateNeeded:=false;
FLastCleanedSrcLen:=CleanedLen;
except
on E: ELinkScannerError do begin
@ -1612,45 +1627,33 @@ end;
function TLinkScanner.UpdateNeeded(
Range: TLinkScannerRange; CheckFilesOnDisk: boolean): boolean;
{ the clean source must be rebuilt if
1. scanrange increased
2. unit source changed
3. one of its include files changed
4. init values changed (e.g. initial compiler defines)
5. FForceUpdateNeeded is set
6. a missing include file can now be found
1. a former check says so
2. scanrange increased
3. unit source changed
4. one of its include files changed
5. init values changed (e.g. initial compiler defines)
7. a missing include file can now be found
}
var i: integer;
SrcLog: TSourceLog;
NewInitValues: TExpressionEvaluator;
GlobalWriteLockIsSet: boolean;
GlobalWriteLockStep: integer;
NewInitValuesChangeStep: integer;
SrcChange: PSourceChangeStep;
CurSourcesChangeStep, CurFilesChangeStep, CurInitValuesChangeStep: int64;
begin
Result:=true;
if FForceUpdateNeeded then exit;
// do a quick test: check the GlobalWriteLockStep
if Assigned(OnGetGlobalWriteLockInfo) then begin
OnGetGlobalWriteLockInfo(GlobalWriteLockIsSet,GlobalWriteLockStep);
if GlobalWriteLockIsSet then begin
// The global write lock is set. That means, input variables and code are
// frozen
if (FLastGlobalWriteLockStep=GlobalWriteLockStep) then begin
// source and values did not change since last UpdateNeeded check
// -> check only if ScanTill has increased
if ord(Range)>ord(ScannedRange) then exit;
Result:=false;
exit;
end else begin
// this is the first check in this GlobalWriteLockStep
FLastGlobalWriteLockStep:=GlobalWriteLockStep;
// proceed normally ...
end;
end;
end;
// check if ScanRange has increased
if Range=lsrNone then exit(false);
if not Assigned(FOnCheckFileOnDisk) then CheckFilesOnDisk:=false;
// use the last check result
if [lssSourcesChanged,lssInitValuesChanged]*FStates<>[] then exit;
if CheckFilesOnDisk and (lssFilesChanged in FStates) then exit;
// check if range increased
// Note: if there was an error, then a range increase will raise the same error
// and no update is needed
if (ord(Range)>ord(ScannedRange)) and (not LastErrorIsValid) then begin
{$IFDEF VerboseUpdateNeeded}
DebugLn(['TLinkScanner.UpdateNeeded because range increased Range=',ord(Range),' ScannedRange=',ord(ScannedRange)]);
@ -1658,9 +1661,36 @@ begin
exit;
end;
// check if any input has changed ...
FForceUpdateNeeded:=true;
// do a quick test: check the global change steps for sources and values
if Assigned(OnGetGlobalChangeSteps) then begin
OnGetGlobalChangeSteps(CurSourcesChangeStep,CurFilesChangeStep,CurInitValuesChangeStep);
if (CurSourcesChangeStep=FGlobalSourcesChangeStep)
and (CurInitValuesChangeStep=FGlobalInitValuesChangeStep)
and ((not CheckFilesOnDisk) or (CurFilesChangeStep=FGlobalSourcesChangeStep))
then begin
// sources and values did not change since last check
Result:=false;
exit;
end;
FGlobalSourcesChangeStep:=CurSourcesChangeStep;
FGlobalInitValuesChangeStep:=CurInitValuesChangeStep;
if CheckFilesOnDisk then FGlobalSourcesChangeStep:=CurFilesChangeStep;
end;
// check initvalues
if Assigned(FOnGetInitValues) then begin
NewInitValues:=FOnGetInitValues(Code,NewInitValuesChangeStep);
if (NewInitValues<>nil)
and (NewInitValuesChangeStep<>FInitValuesChangeStep)
and (not FInitValues.Equals(NewInitValues)) then begin
{$IFDEF VerboseUpdateNeeded}
DebugLn(['TLinkScanner.UpdateNeeded because InitValues changed ',MainFilename]);
{$ENDIF}
Include(FStates,lssInitValuesChanged);
exit;
end;
end;
// check all used files
if Assigned(FOnGetSource) then begin
for i:=0 to FSourceChangeSteps.Count-1 do begin
@ -1669,45 +1699,38 @@ begin
//debugln(['TLinkScanner.UpdateNeeded ',ExtractFilename(MainFilename),' i=',i,' File=',FOnGetFileName(Self,SrcLog),' Last=',SrcChange^.ChangeStep,' Now=',SrcLog.ChangeStep]);
if SrcChange^.ChangeStep<>SrcLog.ChangeStep then begin
{$IFDEF VerboseUpdateNeeded}
DebugLn(['TLinkScanner.UpdateNeeded because file changed: ',OnGetFileName(Self,SrcLog),' MainFilename=',MainFilename]);
DebugLn(['TLinkScanner.UpdateNeeded because source buffer changed: ',OnGetFileName(Self,SrcLog),' MainFilename=',MainFilename]);
{$ENDIF}
Include(FStates,lssSourcesChanged);
exit;
end;
end;
if CheckFilesOnDisk and Assigned(FOnCheckFileOnDisk) then begin
if CheckFilesOnDisk then begin
// if files changed on disk, reload them
for i:=0 to FSourceChangeSteps.Count-1 do begin
SrcChange:=PSourceChangeStep(FSourceChangeSteps[i]);
SrcLog:=FOnGetSource(Self,SrcChange^.Code);
FOnCheckFileOnDisk(SrcLog);
if FOnCheckFileOnDisk(SrcLog) then begin
{$IFDEF VerboseUpdateNeeded}
DebugLn(['TLinkScanner.UpdateNeeded because file on disk changed: ',OnGetFileName(Self,SrcLog),' MainFilename=',MainFilename]);
{$ENDIF}
Include(FStates,lssFilesChanged);
exit;
end;
end;
end;
end;
// check initvalues
if Assigned(FOnGetInitValues) then begin
if FInitValues=nil then exit;
NewInitValues:=FOnGetInitValues(Code,NewInitValuesChangeStep);
if (NewInitValues<>nil)
and (NewInitValuesChangeStep<>FInitValuesChangeStep)
and (not FInitValues.Equals(NewInitValues)) then begin
{$IFDEF VerboseUpdateNeeded}
DebugLn(['TLinkScanner.UpdateNeeded because InitValues changed ',MainFilename]);
{$ENDIF}
exit;
end;
end;
// check missing include files
if MissingIncludeFilesNeedsUpdate then begin
if CheckFilesOnDisk and MissingIncludeFilesNeedsUpdate then begin
{$IFDEF VerboseUpdateNeeded}
DebugLn(['TLinkScanner.UpdateNeeded because MissingIncludeFilesNeedsUpdate']);
{$ENDIF}
Include(FStates,lssFilesChanged);
exit;
end;
// no update needed :)
FForceUpdateNeeded:=false;
//DebugLn('TLinkScanner.UpdateNeeded END');
Result:=false;
end;
@ -3084,7 +3107,10 @@ end;
procedure TLinkScanner.SetIgnoreMissingIncludeFiles(const Value: boolean);
begin
FIgnoreMissingIncludeFiles := Value;
if Value then
Include(FStates,lssIgnoreMissingIncludeFiles)
else
Exclude(FStates,lssIgnoreMissingIncludeFiles);
end;
procedure TLinkScanner.PushIncludeLink(ACleanedPos, ASrcPos: integer;
@ -3499,6 +3525,11 @@ begin
FCompilerModeSwitch:=cmsDefault;
end;
function TLinkScanner.GetIgnoreMissingIncludeFiles: boolean;
begin
Result:=lssIgnoreMissingIncludeFiles in FStates;
end;
procedure TLinkScanner.SetCompilerModeSwitch(const AValue: TCompilerModeSwitch
);
begin
@ -3791,8 +3822,6 @@ procedure TLinkScanner.DoCheckAbort;
begin
if not Assigned(OnProgress) then exit;
if OnProgress(Self) then exit;
// mark scanning results as invalid
FForceUpdateNeeded:=true;
// raise abort exception
RaiseExceptionClass('Abort',ELinkScannerAbort);
end;

View File

@ -1567,6 +1567,7 @@ Begin
// ' TextSelectedColor=',DbgS(TextSelectedColor),
// '');
end;
debugln(['TSourceEditCompletion.ccExecute ',DbgSName(SourceEditorManager.ActiveCompletionPlugin)]);
if (CurrentCompletionType=ctIdentCompletion) and (SourceEditorManager.ActiveCompletionPlugin=nil)
then
StartShowCodeHelp

View File

@ -3,6 +3,7 @@
./runtests --format=plain --suite=TestCTScanRange
./runtests --format=plain --suite=TestCTScanRangeAscending
./runtests --format=plain --suite=TestCTScanRangeProcModified
./runtests --format=plain --suite=TestCTScanRangeImplementationToEnd
}
unit TestCTRangeScan;
@ -39,6 +40,7 @@ type
procedure TestCTScanRangeAscending;
procedure TestCTScanRangeDescending;
procedure TestCTScanRangeProcModified;
procedure TestCTScanRangeImplementationToEnd;
end;
implementation
@ -93,7 +95,7 @@ begin
RootNode:=Tool.Tree.Root;
TreeChangeStep:=Tool.TreeChangeStep;
AssertEquals('Step1: RootNode<>nil',true,RootNode<>nil);
//Tool.WriteDebugTreeReport;
Tool.WriteDebugTreeReport;
// append a comment at end and scan again => this should result in no tree change
Code.Source:=GetSource([crsfWithCommentAtEnd]);
@ -213,6 +215,28 @@ begin
AssertEquals('step2: end. found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil);
end;
procedure TTestCodetoolsRangeScan.TestCTScanRangeImplementationToEnd;
var
Code: TCodeBuffer;
Tool: TEventsCodeTool;
begin
Code:=CodeToolBoss.CreateFile('TestRangeScan.pas');
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool;
Code.Source:='';
Tool.BuildTree(lsrInit);
// scan source
Code.Source:=GetSource([crsfWithProc1]);
Tool.BuildTree(lsrImplementationStart);
Tool.WriteDebugTreeReport;
AssertEquals('step1: implementation found',true,Tool.FindImplementationNode<>nil);
Tool.BuildTree(lsrEnd);
Tool.WriteDebugTreeReport;
AssertEquals('step2: end. found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil);
end;
initialization
AddToCodetoolsTestSuite(TTestCodetoolsRangeScan);