From ec45ce552b95ddbe94a352339f1ec094844cb7dd Mon Sep 17 00:00:00 2001 From: juha Date: Sat, 15 Jan 2011 23:05:59 +0000 Subject: [PATCH] Converter: add more required units and their package dependencies. git-svn-id: trunk@29045 - --- converter/convertdelphi.pas | 85 +++++++++++++++++------------- converter/convertertypes.pas | 1 + converter/missingpropertiesdlg.pas | 9 +++- converter/usedunits.pas | 40 ++++++++++---- 4 files changed, 87 insertions(+), 48 deletions(-) diff --git a/converter/convertdelphi.pas b/converter/convertdelphi.pas index fcf4d81835..69a4133606 100644 --- a/converter/convertdelphi.pas +++ b/converter/convertdelphi.pas @@ -180,6 +180,7 @@ type constructor Create(const AFilename, ADescription: string); destructor Destroy; override; function Convert: TModalResult; + function CheckPackageDependency(AUnitName: string): Boolean; public property CompOpts: TBaseCompilerOptions read GetCompOpts; property CustomDefines: TDefineTemplate read GetCustomDefines; @@ -619,33 +620,28 @@ begin end; // Take care of missing units in uses sections. fUsedUnitsTool:=Nil; + if fSettings.UnitsReplaceMode<>rlDisabled then begin + fUsedUnitsTool:=TUsedUnitsTool.Create(fCTLink, fOrigUnitFilename); + if Assigned(fOwnerConverter) then + fUsedUnitsTool.CheckPackDepEvent:=@fOwnerConverter.CheckPackageDependency; + // Find and prepare the missing units. Don't replace yet. + Result:=fUsedUnitsTool.Prepare; + if Result<>mrOk then exit; + if fUsedUnitsTool.MissingUnitCount>0 then begin + Result:=ReduceMissingUnits; + if Result<>mrOk then exit; + end; + end; + // Do the actual code conversion. + ConvTool:=TConvDelphiCodeTool.Create(fCTLink); try - if fSettings.UnitsReplaceMode<>rlDisabled then begin - fUsedUnitsTool:=TUsedUnitsTool.Create(fCTLink, fOrigUnitFilename); - // Find and prepare the missing units. Don't replace yet. - Result:=fUsedUnitsTool.Prepare; - if Result<>mrOk then exit; - if fUsedUnitsTool.MissingUnitCount>0 then begin - Result:=ReduceMissingUnits; - if Result<>mrOk then exit; - end; - end; - // Do the actual code conversion. - ConvTool:=TConvDelphiCodeTool.Create(fCTLink); - try - ConvTool.LowerCaseRes:=FileExistsUTF8(ChangeFileExt(fLazUnitFilename, '.res')); - ConvTool.HasFormFile:=DfmFilename<>''; + ConvTool.LowerCaseRes:=FileExistsUTF8(ChangeFileExt(fLazUnitFilename, '.res')); + ConvTool.HasFormFile:=DfmFilename<>''; + if Assigned(fUsedUnitsTool) then ConvTool.AddUnitEvent:=@fUsedUnitsTool.AddUnitIfNeeded; - Result:=ConvTool.Convert; - if Result<>mrOk then exit; - finally - ConvTool.Free; - end; - // Fix or comment missing units, show error messages. - if fSettings.UnitsReplaceMode<>rlDisabled then - Result:=fUsedUnitsTool.Convert; + Result:=ConvTool.Convert; finally - FreeAndNil(fUsedUnitsTool); + ConvTool.Free; end; end; @@ -661,6 +657,7 @@ begin LfmFixer:=TLFMFixer.Create(fCTLink,fLFMBuffer,@IDEMessagesWindow.AddMsg); try LfmFixer.Settings:=fSettings; + LfmFixer.UsedUnitsTool:=fUsedUnitsTool; LfmFixer.RootMustBeClassInUnit:=true; LfmFixer.RootMustBeClassInIntf:=true; LfmFixer.ObjectsMustExists:=true; @@ -675,6 +672,12 @@ begin Result:=SaveCodeBufferToFile(fLFMBuffer,fLFMBuffer.Filename); if Result<>mrOk then exit; end; + // After other changes: add, remove, fix and comment out units in uses sections. + if Assigned(fUsedUnitsTool) then begin + Result:=fUsedUnitsTool.Convert; + if Result<>mrOk then exit; + FreeAndNil(fUsedUnitsTool); + end; Result:=mrOk; end; @@ -1097,14 +1100,31 @@ begin Options.SrcPath:=CleanProjectSearchPath(Options.SrcPath); end; +function TConvertDelphiPBase.CheckPackageDependency(AUnitName: string): Boolean; +var + Pack: TPkgFile; + Dep: TPkgDependency; +begin + Result:=False; + Pack:=PackageGraph.FindUnitInAllPackages(AUnitName, True); + if Assigned(Pack) then begin + // Found from package: add package to project dependencies and open it. + AddPackageDependency(Pack.LazPackage.Name); + Dep:=FindDependencyByName(Pack.LazPackage.Name); + if Assigned(Dep) then + PackageGraph.OpenDependency(Dep,false); + Result:=True; + end else begin; + // ToDo: Install the required package automatically from a repository... + end; +end; + function TConvertDelphiPBase.DoMissingUnits(AUsedUnitsTool: TUsedUnitsTool): integer; // Locate unit names from earlier cached list or from packages. // Return the number of units still missing. procedure DoMissingSub(AUsedUnits: TUsedUnits); var - Pack: TPkgFile; - Dep: TPkgDependency; mUnit, sUnitPath, RealFileName, RealUnitName: string; i: Integer; begin @@ -1124,17 +1144,8 @@ function TConvertDelphiPBase.DoMissingUnits(AUsedUnitsTool: TUsedUnitsTool): int fUnitsToAddToProject.Add(sUnitPath+RealFileName); AUsedUnits.MissingUnits.Delete(i); // No more missing, delete from list. end - else begin - Pack:=PackageGraph.FindUnitInAllPackages(mUnit, True); - if Assigned(Pack) then begin - // Found from package: add package to project dependencies and open it. - AddPackageDependency(Pack.LazPackage.Name); - Dep:=FindDependencyByName(Pack.LazPackage.Name); - if Assigned(Dep) then - PackageGraph.OpenDependency(Dep,false); - AUsedUnits.MissingUnits.Delete(i); - end; - end; + else if CheckPackageDependency(mUnit) then + AUsedUnits.MissingUnits.Delete(i); end; end; diff --git a/converter/convertertypes.pas b/converter/convertertypes.pas index f6df82a72e..a26de5a3a0 100644 --- a/converter/convertertypes.pas +++ b/converter/convertertypes.pas @@ -10,6 +10,7 @@ uses type TAddUnitEvent = procedure(AUnitName: string) of object; + TCheckUnitEvent = function (AUnitName: string): Boolean of object; { TopOffset } diff --git a/converter/missingpropertiesdlg.pas b/converter/missingpropertiesdlg.pas index d8be9fe527..085ff91fcd 100644 --- a/converter/missingpropertiesdlg.pas +++ b/converter/missingpropertiesdlg.pas @@ -44,7 +44,7 @@ uses CustomFormEditor, LazarusIDEStrConsts, IDEProcs, OutputFilter, EditorOptions, CheckLFMDlg, IDEMsgIntf, // Converter - ConverterTypes, ConvertSettings, ReplaceNamesUnit, ConvCodeTool; + ConverterTypes, ConvertSettings, ReplaceNamesUnit, ConvCodeTool, UsedUnits; type @@ -69,6 +69,7 @@ type private fCTLink: TCodeToolLink; fSettings: TConvertSettings; + fUsedUnitsTool: TUsedUnitsTool; // List of property values which need to be adjusted. fHasMissingProperties: Boolean; // LFM file has unknown properties. fHasMissingObjectTypes: Boolean; // LFM file has unknown object types. @@ -89,6 +90,7 @@ type function Repair: TModalResult; public property Settings: TConvertSettings read fSettings write fSettings; + property UsedUnitsTool: TUsedUnitsTool read fUsedUnitsTool write fUsedUnitsTool; end; @@ -298,6 +300,11 @@ begin AddReplacement(ChgEntryRepl,StartPos,EndPos,NewIdent); IDEMessagesWindow.AddMsg(Format( 'Replaced type "%s" with "%s".',[OldIdent, NewIdent]),'',-1); + if Assigned(fUsedUnitsTool) then begin + // ToDo: This is a test and will be replaced by configurable unit names. + if NewIdent='TRichMemo' then + fUsedUnitsTool.AddUnitIfNeeded('RichMemo'); + end; Result:=mrRetry; end; end diff --git a/converter/usedunits.pas b/converter/usedunits.pas index 30a17de628..c7b35a0f4c 100644 --- a/converter/usedunits.pas +++ b/converter/usedunits.pas @@ -49,6 +49,7 @@ type TUsedUnits = class private fCTLink: TCodeToolLink; // Link to codetools. + fOwnerTool: TUsedUnitsTool; fUsesSection: TUsesSection; // Enum used by some codetools funcs. fExistingUnits: TStringList; // List of units before conversion. fUnitsToAdd: TStringList; // List of new units to add. @@ -71,7 +72,7 @@ type // Uses node in either Main or Implementation section. function UsesSectionNode: TCodeTreeNode; virtual; abstract; public - constructor Create(ACTLink: TCodeToolLink); + constructor Create(ACTLink: TCodeToolLink; aOwnerTool: TUsedUnitsTool); destructor Destroy; override; procedure CommentAutomatic(ACommentedUnits: TStringList); public @@ -94,7 +95,7 @@ type function ParentBlockNode: TCodeTreeNode; override; function UsesSectionNode: TCodeTreeNode; override; public - constructor Create(ACTLink: TCodeToolLink); + constructor Create(ACTLink: TCodeToolLink; aOwnerTool: TUsedUnitsTool); destructor Destroy; override; end; @@ -106,7 +107,7 @@ type function ParentBlockNode: TCodeTreeNode; override; function UsesSectionNode: TCodeTreeNode; override; public - constructor Create(ACTLink: TCodeToolLink); + constructor Create(ACTLink: TCodeToolLink; aOwnerTool: TUsedUnitsTool); destructor Destroy; override; end; @@ -118,6 +119,7 @@ type fFilename: string; fMainUsedUnits: TUsedUnits; fImplUsedUnits: TUsedUnits; + fCheckPackageDependencyEvent: TCheckUnitEvent; function GetMissingUnitCount: integer; public constructor Create(ACTLink: TCodeToolLink; AFilename: string); @@ -130,6 +132,8 @@ type property MainUsedUnits: TUsedUnits read fMainUsedUnits; property ImplUsedUnits: TUsedUnits read fImplUsedUnits; property MissingUnitCount: integer read GetMissingUnitCount; + property CheckPackDepEvent: TCheckUnitEvent read fCheckPackageDependencyEvent + write fCheckPackageDependencyEvent; end; @@ -151,12 +155,13 @@ end; { TUsedUnits } -constructor TUsedUnits.Create(ACTLink: TCodeToolLink); +constructor TUsedUnits.Create(ACTLink: TCodeToolLink; aOwnerTool: TUsedUnitsTool); var UsesNode: TCodeTreeNode; begin inherited Create; fCTLink:=ACTLink; + fOwnerTool:=aOwnerTool; fUnitsToAdd:=TStringList.Create; fUnitsToAddForLCL:=TStringList.Create; fUnitsToRemove:=TStringList.Create; @@ -244,11 +249,19 @@ end; procedure TUsedUnits.ToBeRenamedOrRemoved(AOldName, ANewName: string); // Replace a unit name with a new name or remove it if there is no new name. +var + UnitInFileName: string; begin if ANewName<>'' then begin fUnitsToRename[AOldName]:=ANewName; IDEMessagesWindow.AddMsg(Format(lisConvDelphiReplacedUnitInUsesSection, [AOldName, ANewName]), '', -1); + // If the unit is not found, open the package containing it. + UnitInFileName:=''; + if fCTLink.CodeTool.FindUnitCaseInsensitive(ANewName,UnitInFileName) = '' then + if Assigned(fOwnerTool.CheckPackDepEvent) then + if not fOwnerTool.CheckPackDepEvent(ANewName) then + ; end else begin fUnitsToRemove.Add(AOldName); @@ -416,9 +429,9 @@ end; { TMainUsedUnits } -constructor TMainUsedUnits.Create(ACTLink: TCodeToolLink); +constructor TMainUsedUnits.Create(ACTLink: TCodeToolLink; aOwnerTool: TUsedUnitsTool); begin - inherited Create(ACTLink); + inherited Create(ACTLink, aOwnerTool); fUsesSection:=usMain; end; @@ -439,9 +452,9 @@ end; { TImplUsedUnits } -constructor TImplUsedUnits.Create(ACTLink: TCodeToolLink); +constructor TImplUsedUnits.Create(ACTLink: TCodeToolLink; aOwnerTool: TUsedUnitsTool); begin - inherited Create(ACTLink); + inherited Create(ACTLink, aOwnerTool); fUsesSection:=usImplementation; end; @@ -469,8 +482,8 @@ begin fFilename:=AFilename; fCTLink.CodeTool.BuildTree(False); // These will read uses sections while creating. - fMainUsedUnits:=TMainUsedUnits.Create(ACTLink); - fImplUsedUnits:=TImplUsedUnits.Create(ACTLink); + fMainUsedUnits:=TMainUsedUnits.Create(ACTLink, Self); + fImplUsedUnits:=TImplUsedUnits.Create(ACTLink, Self); end; destructor TUsedUnitsTool.Destroy; @@ -612,12 +625,19 @@ end; procedure TUsedUnitsTool.AddUnitIfNeeded(AUnitName: string); var i: Integer; + UnitInFileName: String; begin if not ( fMainUsedUnits.fExistingUnits.Find(AUnitName, i) or fImplUsedUnits.fExistingUnits.Find(AUnitName, i) or fMainUsedUnits.fUnitsToAdd.Find(AUnitName, i) ) then begin fMainUsedUnits.fUnitsToAdd.Add(AUnitName); IDEMessagesWindow.AddMsg('Added unit '+AUnitName+ ' to uses section', '', -1); + // If the unit is not found, open the package containing it. + UnitInFileName:=''; + if fCTLink.CodeTool.FindUnitCaseInsensitive(AUnitName,UnitInFileName) = '' then + if Assigned(fCheckPackageDependencyEvent) then + if not fCheckPackageDependencyEvent(AUnitName) then + ; end; end;