mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-09 03:48:08 +02:00
codetools: use global changesteps for quick updateneeded checks
git-svn-id: trunk@29787 -
This commit is contained in:
parent
06da501b26
commit
517bd4b789
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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;
|
||||
|
@ -1567,6 +1567,7 @@ Begin
|
||||
// ' TextSelectedColor=',DbgS(TextSelectedColor),
|
||||
// '');
|
||||
end;
|
||||
debugln(['TSourceEditCompletion.ccExecute ',DbgSName(SourceEditorManager.ActiveCompletionPlugin)]);
|
||||
if (CurrentCompletionType=ctIdentCompletion) and (SourceEditorManager.ActiveCompletionPlugin=nil)
|
||||
then
|
||||
StartShowCodeHelp
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user