From 1b5076f959a50d23fe3f45da7ea2a5e099616555 Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Tue, 28 Jun 2016 09:39:51 +0200 Subject: [PATCH] add main option for #77 + mostly drafted the feature --- src/ce_libman.pas | 141 +++++++++++++++++++++++++--------------- src/ce_libmaneditor.pas | 12 +++- src/ce_main.pas | 14 ++-- 3 files changed, 109 insertions(+), 58 deletions(-) diff --git a/src/ce_libman.pas b/src/ce_libman.pas index e23aed01..21ff71ac 100644 --- a/src/ce_libman.pas +++ b/src/ce_libman.pas @@ -10,6 +10,8 @@ uses type + // TODO-clibman: improve import analysis, caching, hashmap, backup, update. + (** * Information for a module in a library manager entry *) @@ -17,16 +19,12 @@ type private fName: string; fImports: TStringList; - fDeps: TstringList; procedure setImports(value: TStringList); - procedure setDependencies(value: TStringList); published // the.module.name property name: string read fName write fname; // all the imports in this module property imports: TStringList read fImports write setImports; - // the aliases to the libraries used by this module. - property dependencies: TStringList read fDeps write setDependencies; public constructor Create(ACollection: TCollection); override; destructor Destroy; override; @@ -44,8 +42,10 @@ type fLibFile: string; fProjFile: string; fEnabled: boolean; - fModules: TOwnedCollection; - procedure setModules(value: TOwnedCollection); + fDependencies: TStringList; + fModules: TCollection; + procedure setDependencies(value: TStringList); + procedure setModules(value: TCollection); function getModuleInfo(ix: integer): TModuleInfo; published property libAlias: string read fAlias write fAlias; @@ -53,14 +53,16 @@ type property libFile: string read fLibFile write fLibFile; property projectFile: string read fProjFile write fProjFile; property enabled: boolean read fEnabled write fEnabled default true; - // TODO-creminder: dont forget that this prop is not written - property modules: TOwnedCollection read fModules write setModules stored false; + // TODO-clibman: dont forget that these props are not written + property dependencies: TStringList read fDependencies write setDependencies stored false; + property modules: TCollection read fModules write setModules stored false; public constructor Create(ACollection: TCollection); override; + destructor Destroy; override; procedure updateModulesInfo; - procedure updateModulesDependencies; function addModuleInfo: TModuleInfo; function hasModule(const value: string): boolean; + property moduleInfos[ix: integer]: TModuleInfo read getModuleInfo; end; (** @@ -69,32 +71,34 @@ type TLibraryManager = class(TWritableLfmTextComponent) private fCol: TCollection; - function getLibrary(index: integer): TLibraryItem; + function getItems(index: integer): TLibraryItem; procedure setCol(value: TCollection); published property libraries: TCollection read fCol write setCol; public constructor create(aOwner: TComponent); override; destructor destroy; override; - // (** - * the caller gets all the *.lib/*.a files in aList if someAliases is nil - * otherwise the static libs selected by the aliases in someAliases. + * The caller gets all the static library files in list if aliases is nil + * otherwise the static library files selected by the aliases. *) - procedure getLibFiles(someAliases, aList: TStrings); + procedure getLibFiles(aliases, list: TStrings); (** - * the caller gets all the paths were are located the lib sources in aList if someAliases is nil - * otherwise the paths where are located the lib sources selected by the aliases in someAliases. + * The caller gets all the paths were are located the library sources in list + * if aliases is nil otherwise the paths where are located the sources of the + * livraries selected by aliases. *) - procedure getLibSources(someAliases, aList: TStrings); + procedure getLibSources(aliases, list: TStrings); (** - * The caller gets all the static library files and their source root + * The caller gets all the static library files and the source path * that are required by the specified source code. *) procedure getLibsForSource(source, libs, paths: TStrings); // procedure updateDCD; - property lib[index: integer]: TLibraryItem read getLibrary; default; + // find the aliases of the libraries used by this library. + procedure updateCrossDependencies; + property items[index: integer]: TLibraryItem read getItems; default; end; const @@ -109,13 +113,11 @@ constructor TModuleInfo.Create(ACollection: TCollection); begin inherited create(ACollection); fImports := TStringList.Create; - fDeps := TstringList.Create; end; destructor TModuleInfo.Destroy; begin fImports.free; - fDeps.Free; inherited; end; @@ -124,18 +126,21 @@ begin fImports.Assign(value); end; -procedure TModuleInfo.setDependencies(value: TStringList); -begin - fDeps.Assign(value); -end; - constructor TLibraryItem.Create(ACollection: TCollection); begin inherited create(ACollection); - fModules := TOwnedCollection.Create(self, TModuleInfo); + fModules := TCollection.Create(TModuleInfo); + fDependencies := TStringList.Create; fEnabled:=true; end; +destructor TLibraryItem.Destroy; +begin + fDependencies.Free; + fModules.Free; + inherited; +end; + function TLibraryItem.getModuleInfo(ix: integer): TModuleInfo; begin exit(TModuleInfo(fModules.Items[ix])); @@ -156,11 +161,16 @@ begin exit(false); end; -procedure TLibraryItem.setModules(value: TOwnedCollection); +procedure TLibraryItem.setModules(value: TCollection); begin fModules.Assign(value); end; +procedure TLibraryItem.setDependencies(value: TStringList); +begin + fDependencies.Assign(value); +end; + procedure TLibraryItem.updateModulesInfo; var prj: ICECommonProject; @@ -223,11 +233,6 @@ begin end; end; -procedure TLibraryItem.updateModulesDependencies; -begin - -end; - constructor TLibraryManager.create(aOwner: TComponent); var fName: string; @@ -275,7 +280,7 @@ begin libSourcePath := '/usr/include/dmd/phobos'; end; end; - // add druntime (no lib - only for DCD) + // add druntime (no items - only for DCD) if '/usr/include/dmd/druntime/import'.dirExists then begin with TLibraryItem(fCol.Add) do begin @@ -314,10 +319,12 @@ begin end; updateDCD; // - for i := 2 to fCol.Count-1 do + for i := 0 to fCol.Count-1 do begin - TLibraryItem(fCol.Items[i]).updateModulesInfo; + if (items[i].libAlias <> 'phobos') and (items[i].libAlias <> 'druntime') then + items[i].updateModulesInfo; end; + updateCrossDependencies; end; destructor TLibraryManager.destroy; @@ -333,7 +340,7 @@ begin fCol.assign(value); end; -function TLibraryManager.getLibrary(index: integer): TLibraryItem; +function TLibraryManager.getItems(index: integer): TLibraryItem; begin exit(TLibraryItem(fCol.Items[index])); end; @@ -360,7 +367,7 @@ begin end; end; -procedure TLibraryManager.getLibFiles(someAliases, aList: TStrings); +procedure TLibraryManager.getLibFiles(aliases, list: TStrings); var itm: TLibraryItem; lst: TStringList; @@ -371,16 +378,16 @@ begin begin itm := TLibraryItem(fCol.Items[i]); if (not itm.enabled) or - (someAliases.isNotNil and (someAliases.IndexOf(itm.libAlias) = -1)) then + (aliases.isNotNil and (aliases.IndexOf(itm.libAlias) = -1)) then continue; - // single lib files + // single items files if fileExists(itm.libFile) then begin - if aList.IndexOf(itm.libFile) <> -1 then + if list.IndexOf(itm.libFile) <> -1 then continue; - aList.Add(itm.libFile); + list.Add(itm.libFile); end - // folder of lib file + // folder of items file else if itm.libFile.dirExists then begin lst := TStringList.Create; @@ -392,8 +399,8 @@ begin for j:= 0 to lst.Count-1 do begin if lst[j].extractFileExt = libExt then - if aList.IndexOf(lst[j]) = -1 then - aList.Add(lst[j]); + if list.IndexOf(lst[j]) = -1 then + list.Add(lst[j]); end; finally lst.Free; @@ -402,8 +409,7 @@ begin end; end; - -procedure TLibraryManager.getLibSources(someAliases, aList: TStrings); +procedure TLibraryManager.getLibSources(aliases, list: TStrings); var itm: TLibraryItem; i: Integer; @@ -412,14 +418,14 @@ begin begin itm := TLibraryItem(fCol.Items[i]); if (not itm.enabled) or - (someAliases.isNotNil and (someAliases.IndexOf(itm.libAlias) = -1)) then + (aliases.isNotNil and (aliases.IndexOf(itm.libAlias) = -1)) then continue; // - if aList.IndexOf(itm.libSourcePath) <> -1 then + if list.IndexOf(itm.libSourcePath) <> -1 then continue; if not itm.libSourcePath.dirExists then continue; - aList.Add('-I' + itm.libSourcePath); + list.Add('-I' + itm.libSourcePath); end; end; @@ -437,7 +443,7 @@ begin getImports(tks, imp); for i := 0 to fCol.Count-1 do begin - itm := lib[i]; + itm := items[i]; for j := imp.Count-1 downto 0 do if itm.hasModule(imp[j]) then begin imp.Delete(j); @@ -445,6 +451,11 @@ begin continue; libs.Add(itm.libFile); paths.Add('-I'+itm.libSourcePath); + if itm.dependencies.Count > 0 then + begin + getLibFiles(itm.dependencies, libs); + getLibSources(itm.dependencies, paths); + end; end; end; finally @@ -453,6 +464,34 @@ begin end; end; +procedure TLibraryManager.updateCrossDependencies; +var + i, j, k, m: integer; +begin + for i := 0 to fCol.Count-1 do + begin + if (items[i].libAlias = 'phobos') or (items[i].libAlias = 'druntime') then + continue; + items[i].dependencies.Clear; + for j := 0 to items[i].modules.Count-1 do + for m := 0 to items[i].moduleInfos[j].imports.Count-1 do + begin + for k := 0 to fCol.Count-1 do + begin + if k = i then + continue; + if (items[k].libAlias = 'phobos') or (items[k].libAlias = 'druntime') then + continue; + if items[k].hasModule(items[i].moduleInfos[j].imports[m]) then + begin + items[i].dependencies.Add(items[k].libAlias); + break; + end; + end; + end; + end; +end; + initialization registerClasses([TLibraryManager, TLibraryItem]); LibMan := TLibraryManager.create(nil); diff --git a/src/ce_libmaneditor.pas b/src/ce_libmaneditor.pas index eaa579dc..c0a62047 100644 --- a/src/ce_libmaneditor.pas +++ b/src/ce_libmaneditor.pas @@ -486,9 +486,15 @@ begin if List.Selected.isNil then exit; al := List.Selected.Caption; - if inputQuery('library alias', '', al) then + if (al = 'phobos') or (al = 'druntime') then + begin + dlgOkInfo('phobos and druntime cannot be renamed'); + end else + begin + if inputQuery('library alias', '', al) then List.Selected.Caption := al; - RowToLibrary(List.Selected); + RowToLibrary(List.Selected); + end; end; procedure TCELibManEditorWidget.btnEnabledClick(Sender: TObject); @@ -732,8 +738,10 @@ begin itm.libSourcePath := row.SubItems[1]; itm.projectFile := row.SubItems[2]; itm.enabled := row.SubItems[3] = enableStr[true]; + itm.updateModulesInfo; LibMan.updateDCD; + LibMan.updateCrossDependencies; end; function sourceRoot(project: ICECommonProject): string; diff --git a/src/ce_main.pas b/src/ce_main.pas index 94e0b73b..ef505c61 100644 --- a/src/ce_main.pas +++ b/src/ce_main.pas @@ -466,6 +466,7 @@ type fAutoSaveProjectFiles: boolean; fFlatLook: boolean; fDetectMain: boolean; + fDetectRunnableImports: boolean; function getAdditionalPATH: string; procedure setAdditionalPATH(const value: string); function getDubCompiler: TCECompiler; @@ -492,6 +493,7 @@ type property autoSaveProjectFiles: boolean read fAutoSaveProjectFiles write fAutoSaveProjectFiles default false; property flatLook: boolean read fFlatLook write setFlatLook; property detectMain: boolean read fDetectMain write fDetectMain; + property detectRunnableImports: boolean read fDetectRunnableImports write fDetectRunnableImports; // published for ICEEditableOptions but stored by DCD wrapper since it reloads before CEMainForm property dcdPort: word read fDcdPort write fDcdPort stored false; @@ -2265,11 +2267,13 @@ begin end else dmdproc.Parameters.Add('-version=runnable_module'); - LibMan.getLibFiles(nil, dmdproc.Parameters); - LibMan.getLibSources(nil, dmdproc.Parameters); - - //LibMan.getLibsForSource(fDoc.Lines, dmdproc.Parameters, dmdproc.Parameters); - + if fAppliOpts.detectRunnableImports then + LibMan.getLibsForSource(fDoc.Lines, dmdproc.Parameters, dmdproc.Parameters) + else + begin + LibMan.getLibFiles(nil, dmdproc.Parameters); + LibMan.getLibSources(nil, dmdproc.Parameters); + end; deleteDups(dmdproc.Parameters); dmdproc.Execute;