IDE: fpdoc editor: create fpdoc files for fpc units

git-svn-id: trunk@34847 -
This commit is contained in:
mattias 2012-01-21 17:23:50 +00:00
parent 1b5dde8f63
commit 4be5c93609
4 changed files with 122 additions and 75 deletions

View File

@ -4297,7 +4297,7 @@ var
MinPos, MaxPos: Integer; MinPos, MaxPos: Integer;
CursorNode: TCodeTreeNode; CursorNode: TCodeTreeNode;
UnitStartFound, Found: Boolean; UnitStartFound, Found: Boolean;
StartPos: integer; StartPos: integer; // keep this here, it is modified at several places
procedure AddReference(ACleanPos: integer); procedure AddReference(ACleanPos: integer);
var var

View File

@ -44,7 +44,7 @@ uses
// codetools // codetools
CodeAtom, CodeTree, CodeToolManager, FindDeclarationTool, BasicCodeTools, CodeAtom, CodeTree, CodeToolManager, FindDeclarationTool, BasicCodeTools,
KeywordFuncLists, PascalParserTool, CodeCache, CacheCodeTools, CustomCodeTool, KeywordFuncLists, PascalParserTool, CodeCache, CacheCodeTools, CustomCodeTool,
FileProcs, CTXMLFixFragment, FileProcs, CTXMLFixFragment, DefineTemplates,
{$IFNDEF OldXMLCfg} {$IFNDEF OldXMLCfg}
Laz2_DOM, Laz2_XMLRead, Laz2_XMLWrite, Laz2_DOM, Laz2_XMLRead, Laz2_XMLWrite,
{$ELSE} {$ELSE}
@ -61,6 +61,7 @@ uses
const const
IDEProjectName = 'Lazarus'; IDEProjectName = 'Lazarus';
FPCDocsRepositoryURL = 'http://svn.freepascal.org/svn/fpcdocs/trunk';
type type
TFPDocItem = ( TFPDocItem = (
fpdiShort, fpdiShort,
@ -1120,12 +1121,30 @@ function TCodeHelpManager.DoCreateFPDocFileForSource(const SrcFilename: string;
if (Result<>'') then if (Result<>'') then
Result:=CreateRelativePath(Result,BaseDir); Result:=CreateRelativePath(Result,BaseDir);
end; end;
function FindSuitableDirectory(SearchPath, BaseDir: string; Writable: boolean): string;
var
p: Integer;
begin
//debugln(['FindSuitableDirectory SearchPath="',SearchPath,'"']);
p:=1;
repeat
Result:=GetNextDirectoryInSearchPath(SearchPath,p);
if Result='' then exit;
if not FilenameIsAbsolute(Result) then
Result:=ChompPathDelim(AppendPathDelim(BaseDir)+Result);
//debugln(['FindSuitableDirectory Dir="',Result,'" exists=',DirPathExistsCached(Result),' writable=',DirectoryIsWritableCached(Result)]);
if not DirPathExistsCached(Result) then continue;
if Writable and not DirectoryIsWritableCached(Result) then
continue;
exit;
until false;
end;
var var
PkgList: TFPList; OwnerList: TFPList;
AProject: TLazProject; AProject: TLazProject;
APackage: TLazPackage; APackage: TLazPackage;
p: Integer;
FPDocPaths: String; FPDocPaths: String;
FPDocPackageName: String; FPDocPackageName: String;
NewPath: String; NewPath: String;
@ -1133,6 +1152,8 @@ var
Code: TCodeBuffer; Code: TCodeBuffer;
CurUnitName: String; CurUnitName: String;
AVLNode: TAvgLvlTreeNode; AVLNode: TAvgLvlTreeNode;
UnitSet: TFPCUnitSetCache;
IsInFPCSrc: Boolean;
begin begin
Result:=''; Result:='';
NewOwner:=nil; NewOwner:=nil;
@ -1142,87 +1163,105 @@ begin
exit; exit;
end; end;
PkgList:=nil; OwnerList:=nil;
try try
IsInFPCSrc:=false;
// get all packages owning the file // get all packages owning the file
PkgList:=PackageEditingInterface.GetOwnersOfUnit(SrcFilename); OwnerList:=PackageEditingInterface.GetOwnersOfUnit(SrcFilename);
CleanUpPkgList(PkgList); CleanUpPkgList(OwnerList);
if (PkgList=nil) then begin if (OwnerList=nil) then begin
PkgList:=PackageEditingInterface.GetPossibleOwnersOfUnit(SrcFilename, OwnerList:=PackageEditingInterface.GetPossibleOwnersOfUnit(SrcFilename,
[piosfIncludeSourceDirectories]); [piosfIncludeSourceDirectories]);
CleanUpPkgList(PkgList); CleanUpPkgList(OwnerList);
end; end;
if (PkgList=nil) and IsIDESrcFile(SrcFilename) then begin if (OwnerList=nil) and IsIDESrcFile(SrcFilename) then begin
PkgList:=TFPList.Create; OwnerList:=TFPList.Create;
PkgList.Add(LazarusHelp); OwnerList.Add(LazarusHelp);
end; end;
if PkgList=nil then begin if OwnerList=nil then begin
// no package/project found UnitSet:=CodeToolBoss.GetUnitSetForDirectory(ExtractFilePath(SrcFilename));
MessageDlg(lisProjAddPackageNotFound, if (UnitSet<>nil) and FileIsInPath(SrcFilename,UnitSet.FPCSourceDirectory)
Format(lisLDTheUnitIsNotOwnedBeAnyPackageOrProjectPleaseAddThe, [ then begin
SrcFilename, #13, #13]), mtError, [mbCancel], 0); // in FPC sources
exit; IsInFPCSrc:=true;
end; BaseDir:=GetCurrentDirUTF8;
FPDocPaths:=EnvironmentOptions.FPDocPaths;
NewOwner:=TObject(PkgList[0]); FPDocPackageName:='fcl';
if NewOwner is TLazProject then begin NewPath:=CreateRelativePath(SrcFilename,UnitSet.FPCSourceDirectory);
AProject:=TLazProject(NewOwner); if copy(NewPath,1,4)='rtl'+PathDelim then
BaseDir:=ExtractFilePath(AProject.ProjectInfoFile); FPDocPackageName:='rtl';
if AProject.FPDocPaths='' then end else begin
AProject.FPDocPaths:=SelectNewFPDocPaths(AProject.ShortDescription,BaseDir); // no package/project found
FPDocPaths:=AProject.FPDocPaths; MessageDlg(lisProjAddPackageNotFound,
FPDocPackageName:=GetFPDocPackageNameByOwner(AProject); Format(lisLDTheUnitIsNotOwnedBeAnyPackageOrProjectPleaseAddThe, [
end else if NewOwner is TLazPackage then begin SrcFilename, #13, #13]), mtError, [mbCancel], 0);
APackage:=TLazPackage(NewOwner); exit;
BaseDir:=APackage.DirectoryExpanded; end;
if APackage.FPDocPaths='' then
APackage.FPDocPaths:=SelectNewFPDocPaths(APackage.Name,BaseDir);
FPDocPaths:=APackage.FPDocPaths;
FPDocPackageName:=GetFPDocPackageNameByOwner(APackage);
end else if NewOwner=LazarusHelp then begin
BaseDir:=EnvironmentOptions.LazarusDirectory;
FPDocPaths:=GetIDESrcFPDocPath;
FPDocPackageName:=IDEProjectName;
end else begin end else begin
DebugLn(['TCodeHelpManager.DoCreateFPDocFileForSource unknown owner type ',dbgsName(NewOwner)]); NewOwner:=TObject(OwnerList[0]);
NewOwner:=nil; if NewOwner is TLazProject then begin
exit; AProject:=TLazProject(NewOwner);
BaseDir:=ExtractFilePath(AProject.ProjectInfoFile);
if AProject.FPDocPaths='' then
AProject.FPDocPaths:=SelectNewFPDocPaths(AProject.ShortDescription,BaseDir);
FPDocPaths:=AProject.FPDocPaths;
FPDocPackageName:=GetFPDocPackageNameByOwner(AProject);
end else if NewOwner is TLazPackage then begin
APackage:=TLazPackage(NewOwner);
BaseDir:=APackage.DirectoryExpanded;
if APackage.FPDocPaths='' then
APackage.FPDocPaths:=SelectNewFPDocPaths(APackage.Name,BaseDir);
FPDocPaths:=APackage.FPDocPaths;
FPDocPackageName:=GetFPDocPackageNameByOwner(APackage);
end else if NewOwner=LazarusHelp then begin
// in IDE
BaseDir:=EnvironmentOptions.LazarusDirectory;
FPDocPaths:=GetIDESrcFPDocPath;
FPDocPackageName:=IDEProjectName;
end else begin
DebugLn(['TCodeHelpManager.DoCreateFPDocFileForSource unknown owner type ',dbgsName(NewOwner)]);
NewOwner:=nil;
exit;
end;
end; end;
IDEMacros.CreateAbsoluteSearchPath(FPDocPaths,BaseDir); IDEMacros.CreateAbsoluteSearchPath(FPDocPaths,BaseDir);
p:=1; // search a writable directory
repeat NewPath:=FindSuitableDirectory(FPDocPaths,BaseDir,true);
NewPath:=GetNextDirectoryInSearchPath(FPDocPaths,p); if NewPath='' then
if not FilenameIsAbsolute(NewPath) then NewPath:=FindSuitableDirectory(FPDocPaths,BaseDir,false);
NewPath:=AppendPathDelim(BaseDir)+NewPath; if NewPath='' then begin
if DirPathExistsCached(NewPath) then begin // no valid directory found
// fpdoc directory found DebugLn(['TCodeHelpManager.DoCreateFPDocFileForSource FPDocPackageName="',FPDocPackageName,'" FPDocPaths="',FPDocPaths,'" ']);
Result:=AppendPathDelim(NewPath)+lowercase(ExtractFileNameOnly(SrcFilename))+'.xml'; if IsInFPCSrc then
Code:=CodeToolBoss.LoadFile(SrcFilename,true,false); MessageDlg(lisLDNoValidFPDocPath,
// get unitname Format(lisTheUnitIsPartOfTheFPCSourcesButTheCorrespondingFpd, [
CurUnitName:=ExtractFileNameOnly(SrcFilename); SrcFilename, #13, #13, FPCDocsRepositoryURL, #13, #13])
if Code<>nil then , mtError, [mbCancel], 0)
CurUnitName:=CodeToolBoss.GetSourceName(Code,false); else
// remove cache (source to fpdoc filename) MessageDlg(lisLDNoValidFPDocPath,
AVLNode:=FSrcToDocMap.FindKey(Pointer(SrcFilename), Format(lisLDDoesNotHaveAnyValidFPDocPathUnableToCreateTheFpdo, [
@CompareAnsistringWithLDSrc2DocSrcFile); FPDocPackageName, #13, SrcFilename]), mtError, [mbCancel], 0);
if AVLNode<>nil then exit;
FSrcToDocMap.FreeAndDelete(AVLNode); end;
// create fpdoc file // fpdoc directory found
if CreateFPDocFile(Result,FPDocPackageName,CurUnitName)=nil then Result:=AppendPathDelim(NewPath)+lowercase(ExtractFileNameOnly(SrcFilename))+'.xml';
Result:=''; Code:=CodeToolBoss.LoadFile(SrcFilename,true,false);
exit; // get unitname
end; CurUnitName:=ExtractFileNameOnly(SrcFilename);
until false; if Code<>nil then
CurUnitName:=CodeToolBoss.GetSourceName(Code,false);
// no valid directory found // remove cache (source to fpdoc filename)
DebugLn(['TCodeHelpManager.DoCreateFPDocFileForSource FPDocModul="',FPDocPackageName,'" FPDocPaths="',FPDocPaths,'" ']); AVLNode:=FSrcToDocMap.FindKey(Pointer(SrcFilename),
MessageDlg(lisLDNoValidFPDocPath, @CompareAnsistringWithLDSrc2DocSrcFile);
Format(lisLDDoesNotHaveAnyValidFPDocPathUnableToCreateTheFpdo, [ if AVLNode<>nil then
FPDocPackageName, #13, SrcFilename]), mtError, [mbCancel], 0); FSrcToDocMap.FreeAndDelete(AVLNode);
// create fpdoc file
if CreateFPDocFile(Result,FPDocPackageName,CurUnitName)=nil then
Result:='';
finally finally
PkgList.Free; OwnerList.Free;
end; end;
end; end;
@ -1740,6 +1779,7 @@ begin
or FileIsInPath(SrcFilename,LazDir+'debugger') or FileIsInPath(SrcFilename,LazDir+'debugger')
or FileIsInPath(SrcFilename,LazDir+'packager') or FileIsInPath(SrcFilename,LazDir+'packager')
or FileIsInPath(SrcFilename,LazDir+'converter') or FileIsInPath(SrcFilename,LazDir+'converter')
or FileIsInPath(SrcFilename,LazDir+'designer')
then then
Result:=true; Result:=true;
end; end;

View File

@ -25,7 +25,7 @@ unit FPDocEditWindow;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
{ $define VerboseCodeHelp} {off $define VerboseCodeHelp}
interface interface

View File

@ -3425,6 +3425,13 @@ resourcestring
+'not owned be any package or project.%sPlease add the unit to a package ' +'not owned be any package or project.%sPlease add the unit to a package '
+'or project.%sUnable to create the fpdoc file.'; +'or project.%sUnable to create the fpdoc file.';
lisLDNoValidFPDocPath = 'No valid FPDoc path'; lisLDNoValidFPDocPath = 'No valid FPDoc path';
lisTheUnitIsPartOfTheFPCSourcesButTheCorrespondingFpd = 'The unit %s is part'
+' of the FPC sources, but the corresponding fpdoc xml file was not found.'
+'%sEither you have not yet added the fpcdocs directory to the search path or the '
+'unit is not yet documented.%sThe fpdoc files for the FPC sources can be'
+' downloaded from: %s%sPlease add the directory in the '
+'fpdoc editor options.%sIn order to create a new file the directory must '
+'be writable.';
lisLDDoesNotHaveAnyValidFPDocPathUnableToCreateTheFpdo = '%s does not have ' lisLDDoesNotHaveAnyValidFPDocPathUnableToCreateTheFpdo = '%s does not have '
+'any valid FPDoc path.%sUnable to create the fpdoc file for %s'; +'any valid FPDoc path.%sUnable to create the fpdoc file for %s';
lisErrorReadingXML = 'Error reading XML'; lisErrorReadingXML = 'Error reading XML';