Converter: add more required units and their package dependencies.

git-svn-id: trunk@29045 -
This commit is contained in:
juha 2011-01-15 23:05:59 +00:00
parent eaaabadb9b
commit ec45ce552b
4 changed files with 87 additions and 48 deletions

View File

@ -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;

View File

@ -10,6 +10,7 @@ uses
type
TAddUnitEvent = procedure(AUnitName: string) of object;
TCheckUnitEvent = function (AUnitName: string): Boolean of object;
{ TopOffset }

View File

@ -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

View File

@ -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;