mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2026-01-05 23:41:23 +01:00
codetools: cache for parsing ppu files
git-svn-id: trunk@29455 -
This commit is contained in:
parent
a32a5f13a0
commit
da98b47570
@ -43,7 +43,8 @@ uses
|
||||
Classes, SysUtils, FileProcs, BasicCodeTools, CodeToolsStrConsts, TypInfo,
|
||||
EventCodeTool, CodeTree, CodeAtom, SourceChanger, DefineTemplates, CodeCache,
|
||||
ExprEval, LinkScanner, KeywordFuncLists, FindOverloads, CodeBeautifier,
|
||||
FindDeclarationCache, DirectoryCacher, AVL_Tree, LFMTrees, DirectivesTree,
|
||||
FindDeclarationCache, DirectoryCacher, AVL_Tree,
|
||||
PPUCodeTools, LFMTrees, DirectivesTree,
|
||||
PascalParserTool, CodeToolsConfig, CustomCodeTool, FindDeclarationTool,
|
||||
IdentCompletionTool, StdCodeTools, ResourceCodeTool, CodeToolsStructs,
|
||||
CodeTemplatesTool, ExtractProcTool;
|
||||
@ -167,6 +168,7 @@ type
|
||||
DefineTree: TDefineTree; // cache for defines (e.g. initial compiler values)
|
||||
SourceCache: TCodeCache; // cache for source (units, include files, ...)
|
||||
SourceChangeCache: TSourceChangeCache; // cache for write accesses
|
||||
PPUCache: TPPUTools;
|
||||
GlobalValues: TExpressionEvaluator;
|
||||
DirectoryCachePool: TCTDirectoryCachePool;
|
||||
FPCDefinesCache: TFPCDefinesCache;
|
||||
@ -849,6 +851,7 @@ begin
|
||||
DirectoryCachePool.OnIterateFPCUnitsFromSet:=@DirectoryCachePoolIterateFPCUnitsFromSet;
|
||||
DefineTree.DirectoryCachePool:=DirectoryCachePool;
|
||||
FPCDefinesCache:=TFPCDefinesCache.Create(nil);
|
||||
PPUCache:=TPPUTools.Create(SourceCache);
|
||||
FAddInheritedCodeToOverrideMethod:=true;
|
||||
FAdjustTopLineDueToComment:=true;
|
||||
FCatchExceptions:=true;
|
||||
@ -884,6 +887,7 @@ begin
|
||||
FreeAndNil(FPascalTools);
|
||||
FDirectivesTools.FreeAndClear;
|
||||
FreeAndNil(FDirectivesTools);
|
||||
FreeAndNil(PPUCache);
|
||||
FreeAndNil(FResourceTool);
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('[TCodeToolManager.Destroy] C');
|
||||
|
||||
@ -71,16 +71,20 @@ type
|
||||
ctdusInFilenameNormal, // unit 'in' filename -> filename
|
||||
ctdusInFilenameCaseInsensitive, // unit 'in' filename case insensitive -> filename
|
||||
ctdusUnitFileNormal, // AUnitName.ext (case depends on OS) -> filename
|
||||
ctdusUnitFileCaseInsensitive // AUnitName.ext case insensitive -> filename
|
||||
ctdusUnitFileCaseInsensitive, // AUnitName.ext case insensitive -> filename
|
||||
ctdusPPUNormal, // UnitName (case depends on OS) => filename
|
||||
ctdusPPUCaseInsensitive // UnitName case insensitive => filename
|
||||
);
|
||||
|
||||
const
|
||||
ctdusCaseNormal = [ctdusUnitNormal,
|
||||
ctdusInFilenameNormal,
|
||||
ctdusUnitFileNormal];
|
||||
ctdusUnitFileNormal,
|
||||
ctdusPPUNormal];
|
||||
ctdusCaseInsensitive = [ctdusUnitCaseInsensitive,
|
||||
ctdusInFilenameCaseInsensitive,
|
||||
ctdusUnitFileCaseInsensitive];
|
||||
ctdusUnitFileCaseInsensitive,
|
||||
ctdusPPUCaseInsensitive];
|
||||
|
||||
type
|
||||
|
||||
@ -155,7 +159,7 @@ type
|
||||
SearchPath: string; AnyCase: boolean): string;
|
||||
function FindUnitSourceInCompletePath(var AUnitName, InFilename: string;
|
||||
AnyCase: boolean): string;
|
||||
function FindCompiledUnitInCompletePath(var ShortFilename: string;
|
||||
function FindCompiledUnitInCompletePath(const AnUnitname: string;
|
||||
AnyCase: boolean): string;
|
||||
procedure IterateFPCUnitsInSet(const Iterate: TCTOnIterateFile);
|
||||
procedure WriteListing;
|
||||
@ -215,7 +219,7 @@ type
|
||||
var AUnitName, InFilename: string;
|
||||
AnyCase: boolean = false): string;
|
||||
function FindCompiledUnitInCompletePath(const Directory: string;
|
||||
var ShortFilename: string;
|
||||
var AnUnitname: string;
|
||||
AnyCase: boolean = false): string;
|
||||
property FileTimeStamp: cardinal read FFileTimeStamp;
|
||||
property ConfigTimeStamp: cardinal read FConfigTimeStamp;
|
||||
@ -596,17 +600,15 @@ procedure TCTDirectoryCache.AddToCache(const UnitSrc: TCTDirectoryUnitSources;
|
||||
const Search, Filename: string);
|
||||
var
|
||||
Files: TStringToStringTree;
|
||||
CaseSensitive: Boolean;
|
||||
begin
|
||||
Files:=FUnitSources[UnitSrc].Files;
|
||||
if Files=nil then begin
|
||||
case UnitSrc of
|
||||
ctdusUnitNormal: Files:=TStringToStringTree.Create(FilenamesCaseSensitive);
|
||||
ctdusUnitCaseInsensitive: Files:=TStringToStringTree.Create(false);
|
||||
ctdusInFilenameNormal: Files:=TFilenameToStringTree.Create(false);
|
||||
ctdusInFilenameCaseInsensitive:Files:=TFilenameToStringTree.Create(true);
|
||||
ctdusUnitFileNormal: Files:=TFilenameToStringTree.Create(false);
|
||||
ctdusUnitFileCaseInsensitive: Files:=TFilenameToStringTree.Create(true);
|
||||
end;
|
||||
if UnitSrc in [ctdusUnitNormal,ctdusPPUNormal] then
|
||||
CaseSensitive:=FilenamesCaseSensitive
|
||||
else
|
||||
CaseSensitive:=UnitSrc in ctdusCaseNormal;
|
||||
Files:=TFilenameToStringTree.Create(CaseSensitive);
|
||||
FUnitSources[UnitSrc].Files:=Files;
|
||||
end;
|
||||
Files[Search]:=Filename;
|
||||
@ -1063,20 +1065,19 @@ begin
|
||||
end;
|
||||
|
||||
function TCTDirectoryCache.FindCompiledUnitInCompletePath(
|
||||
var ShortFilename: string; AnyCase: boolean): string;
|
||||
const AnUnitname: string; AnyCase: boolean): string;
|
||||
var
|
||||
UnitPath: string;
|
||||
NewShortFilename: String;
|
||||
UnitSrc: TCTDirectoryUnitSources;
|
||||
CurDir: String;
|
||||
SearchCase: TCTSearchFileCase;
|
||||
begin
|
||||
Result:='';
|
||||
if AnyCase then
|
||||
UnitSrc:=ctdusUnitFileCaseInsensitive
|
||||
UnitSrc:=ctdusPPUCaseInsensitive
|
||||
else
|
||||
UnitSrc:=ctdusUnitFileNormal;
|
||||
if GetUnitSourceCacheValue(UnitSrc,ShortFilename,Result) then begin
|
||||
UnitSrc:=ctdusPPUNormal;
|
||||
if GetUnitSourceCacheValue(UnitSrc,AnUnitname,Result) then begin
|
||||
// found in cache
|
||||
if Result<>'' then begin
|
||||
// unit found
|
||||
@ -1095,19 +1096,13 @@ begin
|
||||
|
||||
// search in unit path
|
||||
UnitPath:=Strings[ctdcsUnitPath];
|
||||
Result:=SearchPascalFileInPath(ShortFilename,CurDir,UnitPath,';',SearchCase);
|
||||
Result:=SearchPascalFileInPath(AnUnitname+'.ppu',CurDir,UnitPath,';',SearchCase);
|
||||
if Result='' then begin
|
||||
// search in unit set
|
||||
Result:=FindCompiledUnitInUnitSet(ShortFilename);
|
||||
end;
|
||||
if Result<>'' then begin
|
||||
NewShortFilename:=ExtractFileName(Result);
|
||||
if (NewShortFilename<>lowercase(NewShortFilename))
|
||||
and (ShortFilename<>NewShortFilename) then
|
||||
ShortFilename:=NewShortFilename;
|
||||
Result:=FindCompiledUnitInUnitSet(AnUnitname);
|
||||
end;
|
||||
|
||||
AddToCache(UnitSrc,ShortFilename,Result);
|
||||
AddToCache(UnitSrc,AnUnitname,Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1382,13 +1377,13 @@ begin
|
||||
end;
|
||||
|
||||
function TCTDirectoryCachePool.FindCompiledUnitInCompletePath(
|
||||
const Directory: string; var ShortFilename: string; AnyCase: boolean
|
||||
const Directory: string; var AnUnitname: string; AnyCase: boolean
|
||||
): string;
|
||||
var
|
||||
Cache: TCTDirectoryCache;
|
||||
begin
|
||||
Cache:=GetCache(Directory,true,false);
|
||||
Result:=Cache.FindCompiledUnitInCompletePath(ShortFilename,AnyCase);
|
||||
Result:=Cache.FindCompiledUnitInCompletePath(AnUnitname,AnyCase);
|
||||
end;
|
||||
|
||||
{ TCTDirectoryListing }
|
||||
|
||||
@ -35,7 +35,8 @@ uses
|
||||
// IDEIntf
|
||||
IDECommands, MenuIntf, ProjectIntf, LazIDEIntf, IDEDialogs, IDEWindowIntf,
|
||||
// codetools
|
||||
BasicCodeTools, FileProcs, CodyStrConsts, CodeToolManager, CodeCache;
|
||||
BasicCodeTools, FileProcs, CodyStrConsts, CodeToolManager, CodeCache,
|
||||
PPUCodeTools;
|
||||
|
||||
const
|
||||
PPUFileNotFound = ' ';
|
||||
@ -358,10 +359,16 @@ var
|
||||
Code: TCodeBuffer;
|
||||
MainUsesSection: TStrings;
|
||||
ImplementationUsesSection: TStrings;
|
||||
ProjectDir: String;
|
||||
BaseDir: String;
|
||||
Scanned: Boolean;
|
||||
PPUTool: TPPUTool;
|
||||
OutputDir: String;
|
||||
begin
|
||||
StartTime:=Now;
|
||||
ProjectDir:=ExtractFilePath(AProject.ProjectInfoFile);
|
||||
|
||||
BaseDir:=ExtractFilePath(AProject.ProjectInfoFile);
|
||||
OutputDir:=AProject.LazCompilerOptions.GetUnitOutputDirectory(false);
|
||||
|
||||
while FSearchingItems.Count>0 do begin
|
||||
Node:=FSearchingItems.Root;
|
||||
Item:=TPPUListItem(Node.Data);
|
||||
@ -370,17 +377,22 @@ begin
|
||||
|
||||
if Item.SrcFile='' then begin
|
||||
// search source
|
||||
debugln(['TPPUListDialog.OnIdle search source of ',AnUnitName]);
|
||||
//debugln(['TPPUListDialog.OnIdle search source of ',AnUnitName]);
|
||||
InFilename:='';
|
||||
Item.SrcFile:=CodeToolBoss.DirectoryCachePool.FindUnitSourceInCompletePath(
|
||||
'',AnUnitName,InFilename);
|
||||
BaseDir,AnUnitName,InFilename);
|
||||
end;
|
||||
|
||||
if Item.PPUFile='' then begin
|
||||
// search ppu file
|
||||
debugln(['TPPUListDialog.OnIdle search ppu of ',AnUnitName]);
|
||||
//debugln(['TPPUListDialog.OnIdle search ppu of ',AnUnitName]);
|
||||
Item.PPUFile:=CodeToolBoss.DirectoryCachePool.FindCompiledUnitInCompletePath(
|
||||
ProjectDir,AnUnitName);
|
||||
BaseDir,AnUnitName);
|
||||
if (Item.PPUFile='') and (OutputDir<>'') then begin
|
||||
// fallback: search in output directory
|
||||
Item.PPUFile:=SearchPascalFileInDir(AnUnitName+'.ppu',OutputDir,
|
||||
ctsfcLoUpCase);
|
||||
end;
|
||||
Item.OFile:=ChangeFileExt(Item.PPUFile,'.o');
|
||||
if not FileExistsCached(Item.PPUFile) then
|
||||
Item.PPUFile:=PPUFileNotFound
|
||||
@ -394,14 +406,32 @@ begin
|
||||
|
||||
if Item.UsesUnits=nil then begin
|
||||
Item.UsesUnits:=TStringList.Create;
|
||||
Item.UsedByUnits:=TStringList.Create;
|
||||
debugln(['TPPUListDialog.OnIdle search used units of ',AnUnitName]);
|
||||
if Item.UsedByUnits=nil then
|
||||
Item.UsedByUnits:=TStringList.Create;
|
||||
//debugln(['TPPUListDialog.OnIdle search used units of ',AnUnitName]);
|
||||
// scan for used units
|
||||
Scanned:=false;
|
||||
if Item.PPUFile<>PPUFileNotFound then begin
|
||||
debugln(['TPPUListDialog.OnIdle search used units of ppu "',Item.PPUFile,'"']);
|
||||
|
||||
end else if Item.SrcFile<>'' then begin
|
||||
debugln(['TPPUListDialog.OnIdle search used units of source "',Item.SrcFile,'"']);
|
||||
//debugln(['TPPUListDialog.OnIdle search used units of ppu "',Item.PPUFile,'" ...']);
|
||||
PPUTool:=CodeToolBoss.PPUCache.LoadFile(Item.PPUFile,true,false);
|
||||
if (PPUTool<>nil) and (PPUTool.ErrorMsg='') then begin
|
||||
//debugln(['TPPUListDialog.OnIdle parsed ppu "',Item.PPUFile,'"']);
|
||||
MainUsesSection:=nil;
|
||||
ImplementationUsesSection:=nil;
|
||||
try
|
||||
PPUTool.PPU.GetMainUsesSectionNames(MainUsesSection);
|
||||
AddUses(Item,MainUsesSection);
|
||||
PPUTool.PPU.GetImplementationUsesSectionNames(ImplementationUsesSection);
|
||||
AddUses(Item,ImplementationUsesSection);
|
||||
Scanned:=true;
|
||||
finally
|
||||
MainUsesSection.Free;
|
||||
ImplementationUsesSection.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if (not Scanned) and (Item.SrcFile<>'') then begin
|
||||
//debugln(['TPPUListDialog.OnIdle search used units of source "',Item.SrcFile,'"']);
|
||||
Code:=CodeToolBoss.LoadFile(Item.SrcFile,true,false);
|
||||
if Code<>nil then begin
|
||||
MainUsesSection:=nil;
|
||||
@ -436,10 +466,10 @@ var
|
||||
UsedUnit: TPPUListItem;
|
||||
begin
|
||||
if UsedUnits=nil then exit;
|
||||
debugln(['TPPUListDialog.AddUses Src=',SrcItem.TheUnitName,' UsedUnits="',UsedUnits.DelimitedText,'"']);
|
||||
//debugln(['TPPUListDialog.AddUses Src=',SrcItem.TheUnitName,' UsedUnits="',UsedUnits.DelimitedText,'"']);
|
||||
for i:=0 to UsedUnits.Count-1 do begin
|
||||
AnUnitName:=UsedUnits[i];
|
||||
debugln(['TPPUListDialog.AddUses ',SrcItem.TheUnitName,' uses ',AnUnitName]);
|
||||
//debugln(['TPPUListDialog.AddUses ',SrcItem.TheUnitName,' uses ',AnUnitName]);
|
||||
UsedUnit:=FindUnit(AnUnitName);
|
||||
if UsedUnit=nil then begin
|
||||
// new unit
|
||||
|
||||
@ -30,9 +30,189 @@ unit PPUCodeTools;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils;
|
||||
Classes, SysUtils, PPUParser, CodeCache, AVL_Tree, FileProcs;
|
||||
|
||||
type
|
||||
|
||||
{ TPPUTool }
|
||||
|
||||
TPPUTool = class
|
||||
public
|
||||
PPU: TPPU;
|
||||
Code: TCodeBuffer;
|
||||
CodeChangeStep: integer;
|
||||
ErrorMsg: string;
|
||||
constructor Create(aCode: TCodeBuffer);
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
{ TPPUTools }
|
||||
|
||||
TPPUTools = class
|
||||
private
|
||||
fItems: TAVLTree; // tree of TPPUTool sorted for Code
|
||||
FSourceCache: TCodeCache;
|
||||
public
|
||||
constructor Create(SrcCache: TCodeCache);
|
||||
destructor Destroy; override;
|
||||
procedure ClearCaches;
|
||||
|
||||
property SourceCache: TCodeCache read FSourceCache;
|
||||
function FindFile(Code: TCodeBuffer): TPPUTool;
|
||||
function FindFile(const ExpandedFilename: string): TPPUTool;
|
||||
function LoadFile(const ExpandedFilename: string;
|
||||
UpdateFromDisk, Revert: boolean): TPPUTool;
|
||||
|
||||
// uses section
|
||||
procedure GetMainUsesSectionNames(Code: TCodeBuffer; var List: TStrings);
|
||||
procedure GetImplementationUsesSectionNames(Code: TCodeBuffer; var List: TStrings);
|
||||
end;
|
||||
|
||||
function ComparePPUTools(Tool1, Tool2: Pointer): integer;
|
||||
function CompareCodeWithPPUTool(Code, Tool: Pointer): integer;
|
||||
|
||||
implementation
|
||||
|
||||
function ComparePPUTools(Tool1, Tool2: Pointer): integer;
|
||||
begin
|
||||
Result:=ComparePointers(TPPUTool(Tool1).Code,TPPUTool(Tool2).Code);
|
||||
end;
|
||||
|
||||
function CompareCodeWithPPUTool(Code, Tool: Pointer): integer;
|
||||
begin
|
||||
Result:=ComparePointers(Code,TPPUTool(Tool).Code);
|
||||
end;
|
||||
|
||||
{ TPPUTools }
|
||||
|
||||
constructor TPPUTools.Create(SrcCache: TCodeCache);
|
||||
begin
|
||||
FSourceCache:=SrcCache;
|
||||
fItems:=TAVLTree.Create(@ComparePPUTools);
|
||||
end;
|
||||
|
||||
destructor TPPUTools.Destroy;
|
||||
begin
|
||||
fItems.FreeAndClear;
|
||||
FreeAndNil(fItems);
|
||||
FSourceCache:=nil;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TPPUTools.ClearCaches;
|
||||
var
|
||||
Node: TAVLTreeNode;
|
||||
Tool: TPPUTool;
|
||||
begin
|
||||
Node:=fItems.FindLowest;
|
||||
while Node<>nil do begin
|
||||
Tool:=TPPUTool(Node.Data);
|
||||
FreeAndNil(Tool.PPU);
|
||||
Tool.ErrorMsg:='';
|
||||
Node:=fItems.FindSuccessor(Node);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPPUTools.FindFile(Code: TCodeBuffer): TPPUTool;
|
||||
var
|
||||
Node: TAVLTreeNode;
|
||||
begin
|
||||
Result:=nil;
|
||||
if Code=nil then exit;
|
||||
Node:=fItems.FindKey(Code,@CompareCodeWithPPUTool);
|
||||
if Node<>nil then
|
||||
Result:=TPPUTool(Node.Data);
|
||||
end;
|
||||
|
||||
function TPPUTools.FindFile(const ExpandedFilename: string): TPPUTool;
|
||||
var
|
||||
Code: TCodeBuffer;
|
||||
begin
|
||||
Code:=SourceCache.FindFile(ExpandedFilename);
|
||||
if Code<>nil then
|
||||
Result:=FindFile(Code)
|
||||
else
|
||||
Result:=nil;
|
||||
end;
|
||||
|
||||
function TPPUTools.LoadFile(const ExpandedFilename: string; UpdateFromDisk,
|
||||
Revert: boolean): TPPUTool;
|
||||
var
|
||||
Code: TCodeBuffer;
|
||||
ss: TStringStream;
|
||||
begin
|
||||
Result:=FindFile(ExpandedFilename);
|
||||
if (not UpdateFromDisk) and (not Revert) then begin
|
||||
// no update needed
|
||||
if Result<>nil then exit;
|
||||
Code:=SourceCache.FindFile(ExpandedFilename);
|
||||
if (Code=nil) or Code.IsDeleted then exit(nil);
|
||||
end;
|
||||
|
||||
// load file
|
||||
Code:=SourceCache.LoadFile(ExpandedFilename);
|
||||
if Code=nil then exit(nil);
|
||||
if Revert then begin
|
||||
if not Code.Revert then
|
||||
exit(nil);
|
||||
end else if UpdateFromDisk and Code.AutoRevertFromDisk
|
||||
and Code.FileNeedsUpdate then begin
|
||||
//debugln(['TPPUTools.LoadFile ',ExpandedFilename,' AutoRevert=',Result.AutoRevertFromDisk,' Modified=',Result.Modified,' NeedLoad=',Result.FileNeedsUpdate]);
|
||||
Code.Reload;
|
||||
end;
|
||||
|
||||
// check if tool needs update
|
||||
if Result=nil then begin
|
||||
Result:=TPPUTool.Create(Code);
|
||||
fItems.Add(Result);
|
||||
end;
|
||||
Result.Code:=Code;
|
||||
if (Result.PPU<>nil) and (Result.CodeChangeStep=Code.ChangeStep) then
|
||||
exit;
|
||||
//debugln(['TPPUTools.LoadFile parsing ppu ',Code.Filename,' ...']);
|
||||
Result.ErrorMsg:='';
|
||||
if Result.PPU=nil then
|
||||
Result.PPU:=TPPU.Create;
|
||||
ss:=TStringStream.Create(Code.Source);
|
||||
try
|
||||
try
|
||||
Result.PPU.LoadFromStream(ss);
|
||||
except
|
||||
on E: Exception do begin
|
||||
Result.ErrorMsg:=E.Message;
|
||||
debugln(['TPPUTools.LoadFile ',Code.Filename,' ERROR: ', Result.ErrorMsg]);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
ss.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPPUTools.GetMainUsesSectionNames(Code: TCodeBuffer;
|
||||
var List: TStrings);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TPPUTools.GetImplementationUsesSectionNames(Code: TCodeBuffer;
|
||||
var List: TStrings);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
{ TPPUTool }
|
||||
|
||||
constructor TPPUTool.Create(aCode: TCodeBuffer);
|
||||
begin
|
||||
Code:=aCode;
|
||||
CodeChangeStep:=Code.ChangeStep;
|
||||
end;
|
||||
|
||||
destructor TPPUTool.Destroy;
|
||||
begin
|
||||
FreeAndNil(PPU);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
||||
@ -546,6 +546,7 @@ type
|
||||
function GetLibraryPath(RelativeToBaseDir: boolean;
|
||||
Parsed: TCompilerOptionsParseType = coptParsed;
|
||||
WithBaseDir: boolean = true): string;
|
||||
function GetUnitOutputDirectory(RelativeToBaseDir: boolean): string; override;
|
||||
function GetUnitOutPath(RelativeToBaseDir: boolean;
|
||||
Parsed: TCompilerOptionsParseType = coptParsed): string;
|
||||
function GetObjectPath(RelativeToBaseDir: boolean;
|
||||
@ -1915,6 +1916,12 @@ begin
|
||||
WithBaseDir);
|
||||
end;
|
||||
|
||||
function TBaseCompilerOptions.GetUnitOutputDirectory(RelativeToBaseDir: boolean
|
||||
): string;
|
||||
begin
|
||||
Result:=GetUnitOutPath(RelativeToBaseDir);
|
||||
end;
|
||||
|
||||
function TBaseCompilerOptions.GetUnitOutPath(RelativeToBaseDir: boolean;
|
||||
Parsed: TCompilerOptionsParseType): string;
|
||||
begin
|
||||
|
||||
@ -303,6 +303,7 @@ type
|
||||
function IsActive: boolean; virtual;
|
||||
function TrimCustomOptions(o: string): string; virtual; abstract;
|
||||
function CreatePPUFilename(const SourceFileName: string): string; virtual; abstract;
|
||||
function GetUnitOutputDirectory(RelativeToBaseDir: boolean): string; virtual; abstract;
|
||||
public
|
||||
property Owner: TObject read fOwner write fOwner;
|
||||
property Modified: boolean read GetModified write SetModified;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user