IDE: added functions to search possible package/project for files

git-svn-id: trunk@12924 -
This commit is contained in:
mattias 2007-11-19 19:16:25 +00:00
parent b81ab6be63
commit e4ed360ac1
4 changed files with 169 additions and 60 deletions

View File

@ -59,6 +59,12 @@ type
ldmhDocChanging,
ldmhDocChanged
);
TLazDocParseResult = (
ldprParsing,
ldprFailed,
ldprSuccess
);
{ TLazDocManager }
@ -86,6 +92,9 @@ type
function GetFPDocFilenameForSource(SrcFilename: string;
ResolveIncludeFiles: Boolean): string;
function CodeNodeToElementName(Tool: TCodeTool; CodeNode: TCodeTreeNode): string;
function GetFPDocNode(Tool: TCodeTool; CodeNode: TCodeTreeNode; Complete: boolean;
out FPDocFile: TLazFPDocFile; out DOMNode: TDOMNode
): TLazDocParseResult;
public
// Event lists
procedure RemoveAllHandlersOfObject(AnObject: TObject);
@ -281,7 +290,6 @@ end;
function TLazDocManager.GetFPDocFilenameForSource(SrcFilename: string;
ResolveIncludeFiles: Boolean): string;
var
SrcDir: String;
FPDocName: String;
SearchPath: String;
@ -293,50 +301,33 @@ var
SearchPath:=SearchPath+';'+Paths;
end;
procedure CheckIfInProject(AProject: TLazProject);
var
ProjectDirs: String;
BaseDir: String;
Add: Boolean;
begin
if AProject=nil then exit;
if AProject.LazDocPaths='' then exit;
BaseDir:=ExtractFilePath(AProject.ProjectInfoFile);
if BaseDir='' then exit;
Add:=false;
// search in project files
if (AProject.FindFile(SrcFilename,[pfsfOnlyProjectFiles])<>nil) then begin
Add:=true;
end;
if (not Add) and FilenameIsAbsolute(SrcFilename) then begin
// search in project directories
ProjectDirs:=AProject.LazCompilerOptions.OtherUnitFiles+';.';
if not IDEMacros.CreateAbsoluteSearchPath(ProjectDirs,BaseDir) then exit;
if FindPathInSearchPath(PChar(SrcDir),length(SrcDir),
PChar(ProjectDirs),length(ProjectDirs))<>nil
then
Add:=true;
end;
if Add then
AddSearchPath(AProject.LazDocPaths,BaseDir);
end;
procedure CheckIfInAPackage;
procedure CheckUnitOwners(CheckSourceDirectories: boolean);
var
PkgList: TFPList;
i: Integer;
APackage: TLazPackage;
BaseDir: String;
AProject: TLazProject;
begin
if not FilenameIsAbsolute(SrcFilename) then exit;
if CheckSourceDirectories then begin
PkgList:=PackageEditingInterface.GetOwnersOfUnit(SrcFilename);
end else begin
PkgList:=PackageEditingInterface.GetPossibleOwnersOfUnit(SrcFilename,[]);
end;
// get all packages owning the file
PkgList:=PackageEditingInterface.GetOwnersOfUnit(SrcFilename);
if PkgList=nil then exit;
try
for i:=0 to PkgList.Count-1 do begin
if TObject(PkgList[i]) is TLazPackage then begin
if TObject(PkgList[i]) is TLazProject then begin
AProject:=TLazProject(PkgList[i]);
if AProject.LazDocPaths='' then continue;
BaseDir:=ExtractFilePath(AProject.ProjectInfoFile);
if BaseDir='' then continue;
// add lazdoc paths of project
AddSearchPath(AProject.LazDocPaths,BaseDir);
end else if TObject(PkgList[i]) is TLazPackage then begin
APackage:=TLazPackage(PkgList[i]);
if APackage.LazDocPaths='' then continue;
BaseDir:=APackage.Directory;
@ -379,15 +370,14 @@ begin
if not FilenameIsPascalSource(SrcFilename) then exit;
SrcDir:=ExtractFilePath(SrcFilename);
// first check if the file is owned by any project/package
SearchPath:='';
CheckIfInProject(LazarusIDE.ActiveProject);
CheckIfInAPackage;
CheckUnitOwners(false);
CheckUnitOwners(true);
CheckIfInLazarus;
// finally add default paths
// finally add the default paths
AddSearchPath(EnvironmentOptions.LazDocPaths,'');
FPDocName:=lowercase(ExtractFileNameOnly(SrcFilename))+'.xml';
DebugLn(['TLazDocManager.GetFPDocFilenameForSource Search ',FPDocName,' in "',SearchPath,'"']);
Result:=SearchFileInPath(FPDocName,'',SearchPath,';',ctsfcAllCase);
@ -418,6 +408,35 @@ begin
end;
end;
function TLazDocManager.GetFPDocNode(Tool: TCodeTool; CodeNode: TCodeTreeNode;
Complete: boolean; out FPDocFile: TLazFPDocFile; out DOMNode: TDOMNode
): TLazDocParseResult;
var
SrcFilename: String;
FPDocFilename: String;
ElementName: String;
begin
FPDocFile:=nil;
DOMNode:=nil;
// find corresponding FPDoc file
SrcFilename:=Tool.MainFilename;
FPDocFilename:=GetFPDocFilenameForSource(SrcFilename,false);
if FPDocFilename='' then exit(ldprFailed);
// load FPDoc file
if not LoadFPDocFile(FPDocFilename,true,false,FPDocFile) then
exit(ldprFailed);
// find FPDoc node
ElementName:=CodeNodeToElementName(Tool,CodeNode);
if ElementName='' then exit(ldprFailed);
DOMNode:=FPDocFile.GetElementWithName(ElementName);
if DOMNode=nil then exit(ldprFailed);
Result:=ldprSuccess;
end;
procedure TLazDocManager.FreeDocs;
var
AVLNode: TAvgLvlTreeNode;

View File

@ -67,6 +67,12 @@ const
);
type
TPkgIntfOwnerSearchFlag = (
piosfExcludeOwned, // file must not be marked as part of project/package
piosfIncludeSourceDirectories
);
TPkgIntfOwnerSearchFlags = set of TPkgIntfOwnerSearchFlag;
{ TPackageEditingInterface }
TPackageEditingInterface = class(TComponent)
@ -83,6 +89,8 @@ type
function GetOwnersOfUnit(const UnitFilename: string): TFPList; virtual; abstract;
procedure ExtendOwnerListWithUsedByOwners(OwnerList: TFPList); virtual; abstract;
function GetSourceFilesOfOwners(OwnerList: TFPList): TStrings; virtual; abstract;
function GetPossibleOwnersOfUnit(const UnitFilename: string;
Flags: TPkgIntfOwnerSearchFlags): TFPList; virtual; abstract;
end;
var

View File

@ -46,7 +46,7 @@ uses
MemCheck,
{$ENDIF}
// FPC + LCL
Classes, SysUtils, FileUtil, LCLProc, Forms, Controls, Dialogs,
Classes, SysUtils, FileProcs, FileUtil, LCLProc, Forms, Controls, Dialogs,
// codetools
AVL_Tree, Laz_XMLCfg, DefineTemplates, CodeCache, BasicCodeTools,
CodeToolManager,
@ -202,6 +202,9 @@ type
function FindFileInAllPackages(const TheFilename: string;
ResolveLinks, IgnoreDeleted,
FindNewFile: boolean): TPkgFile;
procedure FindPossibleOwnersOfUnit(const TheFilename: string;
OwnerList: TFPList;
ResolveLinks: boolean);
function FindLowestPkgNodeByName(const PkgName: string): TAVLTreeNode;
function FindNextSameName(ANode: TAVLTreeNode): TAVLTreeNode;
function FindNodeOfDependency(Dependency: TPkgDependency;
@ -875,6 +878,38 @@ begin
Result:=nil;
end;
procedure TLazPackageGraph.FindPossibleOwnersOfUnit(const TheFilename: string;
OwnerList: TFPList; ResolveLinks: boolean);
var
Cnt: Integer;
i: Integer;
AFilename: string;
APackage: TLazPackage;
PkgDirs: String;
SrcDir: String;
begin
if not FilenameIsAbsolute(TheFilename) then exit;
Cnt:=Count;
AFilename:=TheFilename;
if ResolveLinks then begin
AFilename:=ReadAllLinks(TheFilename,false);
if AFilename='' then AFilename:=TheFilename;
end;
SrcDir:=ExtractFilePath(TheFilename);
for i:=0 to Cnt-1 do begin
APackage:=Packages[i];
if APackage.IsVirtual then continue;
// source directories + unit path + base directory
PkgDirs:=APackage.CompilerOptions.GetParsedPath(pcosUnitPath,icoNone,false);
PkgDirs:=MergeSearchPaths(PkgDirs,APackage.SourceDirectories.CreateSearchPathFromAllFiles);
PkgDirs:=MergeSearchPaths(PkgDirs,APackage.Directory);
if FindPathInSearchPath(PChar(SrcDir),length(SrcDir),
PChar(PkgDirs),length(PkgDirs))<>nil
then
OwnerList.Add(APackage);
end;
end;
function TLazPackageGraph.FindPackageWithFilename(const TheFilename: string;
ResolveLinks: boolean): TLazPackage;
var

View File

@ -45,10 +45,10 @@ uses
MemCheck,
{$ENDIF}
// FCL, LCL
Classes, SysUtils, LCLProc, Forms, Controls, FileUtil, Dialogs, Menus,
Classes, SysUtils, LCLProc, Forms, Controls, Dialogs, Menus,
StringHashList, Translations,
// codetools
CodeToolManager, CodeCache, BasicCodeTools, DefineTemplates,
CodeToolManager, CodeCache, BasicCodeTools, DefineTemplates, FileProcs,
AVL_Tree, Laz_XMLCfg,
// IDE Interface
IDEExternToolIntf, NewItemIntf, ProjectIntf, PackageIntf, MenuIntf,
@ -208,6 +208,8 @@ type
function GetOwnersOfUnit(const UnitFilename: string): TFPList; override;
procedure ExtendOwnerListWithUsedByOwners(OwnerList: TFPList); override;
function GetSourceFilesOfOwners(OwnerList: TFPList): TStrings; override;
function GetPossibleOwnersOfUnit(const UnitFilename: string;
Flags: TPkgIntfOwnerSearchFlags): TFPList; override;
function GetPackageOfCurrentSourceEditor: TPkgFile;
function AddDependencyToOwners(OwnerList: TFPList; APackage: TLazPackage;
OnlyTestIfPossible: boolean = false): TModalResult; override;
@ -345,7 +347,7 @@ begin
OpenDialog.Title:=lisOpenPackageFile;
OpenDialog.Options:=OpenDialog.Options+[ofAllowMultiSelect];
OpenDialog.Filter:=lisLazarusPackage+' (*.lpk)|*.lpk'
+'|'+dlgAllFiles+' ('+GetAllFilesMask+')|'+GetAllFilesMask;
+'|'+dlgAllFiles+' ('+FileMask+')|'+FileMask;
if OpenDialog.Execute and (OpenDialog.Files.Count>0) then begin
OpenFlags:=[pofAddToRecent];
For I := 0 to OpenDialog.Files.Count-1 do
@ -2697,7 +2699,8 @@ begin
for i:=0 to PkgList.Count-1 do begin
APackage:=TLazPackage(PkgList[i]);
IncPath:=APackage.CompilerOptions.GetIncludePath(false);
Result:=SearchFileInPath(Filename,APackage.Directory,IncPath,';',[]);
Result:=SearchFileInPath(Filename,APackage.Directory,IncPath,';',
ctsfcDefault);
if Result<>'' then exit;
end;
finally
@ -2982,23 +2985,8 @@ begin
end;
function TPkgManager.GetOwnersOfUnit(const UnitFilename: string): TFPList;
var
PkgFile: TPkgFile;
begin
Result:=TFPList.Create;
// check if unit is part of project
if Project1<>nil then begin
if Project1.UnitInfoWithFilename(UnitFilename,
[pfsfResolveFileLinks,pfsfOnlyProjectFiles])<>nil
then
Result.Add(Project1);
end;
// find all packages owning file
PkgFile:=PackageGraph.FindFileInAllPackages(UnitFilename,false,true,true);
if (PkgFile<>nil) and (PkgFile.LazPackage<>nil) then
Result.Add(PkgFile.LazPackage);
if Result.Count=0 then
FreeThenNil(Result);
Result:=GetPossibleOwnersOfUnit(UnitFilename,[]);
end;
procedure TPkgManager.ExtendOwnerListWithUsedByOwners(OwnerList: TFPList);
@ -3086,6 +3074,65 @@ begin
end;
end;
function TPkgManager.GetPossibleOwnersOfUnit(const UnitFilename: string;
Flags: TPkgIntfOwnerSearchFlags): TFPList;
var
SrcDir: String;// ExtractFilePath(UnitFilename);
procedure SearchInProject(AProject: TProject);
var
BaseDir: String;
ProjectDirs: String;
Add: Boolean;
begin
if AProject=nil then exit;
if AProject.LazDocPaths='' then exit;
BaseDir:=ExtractFilePath(AProject.ProjectInfoFile);
if BaseDir='' then exit;
Add:=false;
if not (piosfExcludeOwned in Flags) then begin
if AProject.UnitInfoWithFilename(UnitFilename,
[pfsfResolveFileLinks,pfsfOnlyProjectFiles])<>nil
then
Add:=true;
end;
if (piosfIncludeSourceDirectories in Flags)
and FilenameIsAbsolute(UnitFilename) then begin
// search in project source directories
ProjectDirs:=AProject.LazCompilerOptions.OtherUnitFiles+';.';
if not IDEMacros.CreateAbsoluteSearchPath(ProjectDirs,BaseDir) then exit;
if FindPathInSearchPath(PChar(SrcDir),length(SrcDir),
PChar(ProjectDirs),length(ProjectDirs))<>nil
then
Add:=true;
end;
if Add then
Result.Add(AProject);
end;
var
PkgFile: TPkgFile;
begin
Result:=TFPList.Create;
SrcDir:=ExtractFilePath(UnitFilename);
SearchInProject(Project1);
// find all packages owning file
if piosfIncludeSourceDirectories in Flags then begin
PackageGraph.FindPossibleOwnersOfUnit(UnitFilename,Result,false);
end else if not (piosfExcludeOwned in Flags) then begin
PkgFile:=PackageGraph.FindFileInAllPackages(UnitFilename,false,true,true);
if (PkgFile<>nil) and (PkgFile.LazPackage<>nil) then
Result.Add(PkgFile.LazPackage);
end;
// clean up
if Result.Count=0 then
FreeThenNil(Result);
end;
function TPkgManager.GetPackageOfCurrentSourceEditor: TPkgFile;
var
SrcEdit: TSourceEditor;