clean up delphi unit conversion

git-svn-id: trunk@8962 -
This commit is contained in:
mattias 2006-03-18 21:47:56 +00:00
parent decac5e3ee
commit 2fd40eed9d
3 changed files with 138 additions and 62 deletions

View File

@ -45,7 +45,7 @@ unit DelphiProject2Laz;
interface interface
uses uses
Classes, SysUtils, LCLProc, Forms, Controls, Dialogs, FileUtil, Classes, SysUtils, LCLProc, Forms, Controls, Dialogs, FileProcs, FileUtil,
ExprEval, DefineTemplates, CodeCache, CodeToolManager, ExprEval, DefineTemplates, CodeCache, CodeToolManager,
SrcEditorIntf, MsgIntf, MainIntf, LazIDEIntf, ProjectIntf, SrcEditorIntf, MsgIntf, MainIntf, LazIDEIntf, ProjectIntf,
IDEProcs, DelphiUnit2Laz, Project, DialogProcs, CheckLFMDlg, IDEProcs, DelphiUnit2Laz, Project, DialogProcs, CheckLFMDlg,
@ -54,8 +54,20 @@ uses
function ConvertDelphiToLazarusProject(const ProjectFilename: string function ConvertDelphiToLazarusProject(const ProjectFilename: string
): TModalResult; ): TModalResult;
function FindAllDelphiProjectUnits(AProject: TProject): TModalResult;
type
TConvertDelphiToLazarusUnitFlag = (
cdtlufRenameLowercase, // rename the unit lowercase
cdtlufIsSubProc, // this is part of a big conversion -> add Abort button to all questions
cdtlufCheckLFM // check and fix LFM
);
TConvertDelphiToLazarusUnitFlags = set of TConvertDelphiToLazarusUnitFlag;
function ConvertAllDelphiProjectUnits(AProject: TProject;
Flags: TConvertDelphiToLazarusUnitFlags): TModalResult;
function ConvertDelphiToLazarusUnit(const DelphiFilename: string; function ConvertDelphiToLazarusUnit(const DelphiFilename: string;
RenameLowercase, IsSubProc: boolean): TModalResult; Flags: TConvertDelphiToLazarusUnitFlags): TModalResult;
function CreateDelphiToLazarusProject(const LPIFilename: string): TModalResult; function CreateDelphiToLazarusProject(const LPIFilename: string): TModalResult;
function CreateDelphiToLazarusMainSourceFile(AProject: TProject; function CreateDelphiToLazarusMainSourceFile(AProject: TProject;
@ -63,6 +75,8 @@ function CreateDelphiToLazarusMainSourceFile(AProject: TProject;
out LPRCode: TCodeBuffer): TModalResult; out LPRCode: TCodeBuffer): TModalResult;
function FindDPRFilename(const StartFilename: string): string; function FindDPRFilename(const StartFilename: string): string;
function ReadDelphiProjectConfigFiles(AProject: TProject): TModalResult; function ReadDelphiProjectConfigFiles(AProject: TProject): TModalResult;
procedure CleanUpProjectSearchPaths(AProject: TProject);
implementation implementation
@ -75,18 +89,11 @@ function ConvertDelphiToLazarusProject(const ProjectFilename: string
It can be aborted and called again. It can be aborted and called again.
} }
var var
FoundInUnits, MissingInUnits, NormalUnits: TStrings;
NotFoundUnits: String;
LPRCode: TCodeBuffer; LPRCode: TCodeBuffer;
i: Integer;
CurUnitInfo: TUnitInfo;
LPIFilename: String; LPIFilename: String;
DPRFilename: String; DPRFilename: String;
MainSourceFilename: String; MainSourceFilename: String;
RenameLowercase: Boolean; ConvertUnitFlags: TConvertDelphiToLazarusUnitFlags;
NewUnitPath: String;
CurFilename: string;
p: LongInt;
begin begin
debugln('ConvertDelphiToLazarusProject ProjectFilename="',ProjectFilename,'"'); debugln('ConvertDelphiToLazarusProject ProjectFilename="',ProjectFilename,'"');
IDEMessagesWindow.Clear; IDEMessagesWindow.Clear;
@ -116,22 +123,7 @@ begin
// clean up project // clean up project
Project1.RemoveNonExistingFiles(false); Project1.RemoveNonExistingFiles(false);
// TODO: remove doubles in search paths -> this should be done on loading the .lpi CleanUpProjectSearchPaths(Project1);
Project1.CompilerOptions.OtherUnitFiles:=
RemoveNonExistingPaths(Project1.CompilerOptions.OtherUnitFiles,
Project1.ProjectDirectory);
Project1.CompilerOptions.IncludeFiles:=
RemoveNonExistingPaths(Project1.CompilerOptions.IncludeFiles,
Project1.ProjectDirectory);
Project1.CompilerOptions.Libraries:=
RemoveNonExistingPaths(Project1.CompilerOptions.Libraries,
Project1.ProjectDirectory);
Project1.CompilerOptions.ObjectPath:=
RemoveNonExistingPaths(Project1.CompilerOptions.ObjectPath,
Project1.ProjectDirectory);
Project1.CompilerOptions.SrcPath:=
RemoveNonExistingPaths(Project1.CompilerOptions.SrcPath,
Project1.ProjectDirectory);
// load required packages // load required packages
Project1.AddPackageDependency('LCL');// Nearly all Delphi projects require it Project1.AddPackageDependency('LCL');// Nearly all Delphi projects require it
@ -148,18 +140,43 @@ begin
end; end;
// fix .lpr // fix .lpr
RenameLowercase:=false; ConvertUnitFlags:=[cdtlufIsSubProc];
Result:=ConvertDelphiToLazarusUnit(LPRCode.Filename,RenameLowercase,true); Result:=ConvertDelphiToLazarusUnit(LPRCode.Filename,ConvertUnitFlags);
if Result=mrAbort then begin if Result=mrAbort then begin
DebugLn('ConvertDelphiToLazarusProject failed converting unit ',LPRCode.Filename); DebugLn('ConvertDelphiToLazarusProject failed converting unit ',LPRCode.Filename);
exit; exit;
end; end;
// TODO: get all compiler options from .lpr // get all options from .lpr (the former .dpr)
Result:=ExtractOptionsFromDPR(LPRCode,Project1); Result:=ExtractOptionsFromDPR(LPRCode,Project1);
if Result<>mrOk then exit; if Result<>mrOk then exit;
// find all project files // find and convert all project files
Result:=FindAllDelphiProjectUnits(Project1);
if Result<>mrOk then exit;
// convert all project files
Result:=ConvertAllDelphiProjectUnits(Project1,[cdtlufIsSubProc]);
if Result<>mrOk then exit;
debugln('ConvertDelphiToLazarusProject Done');
Result:=mrOk;
end;
function FindAllDelphiProjectUnits(AProject: TProject): TModalResult;
var
FoundInUnits, MissingInUnits, NormalUnits: TStrings;
LPRCode: TCodeBuffer;
NotFoundUnits: String;
i: Integer;
CurUnitInfo: TUnitInfo;
NewUnitPath: String;
CurFilename: string;
p: LongInt;
OffendingUnit: TUnitInfo;
begin
LPRCode:=AProject.MainUnitInfo.Source;
FoundInUnits:=nil; FoundInUnits:=nil;
MissingInUnits:=nil; MissingInUnits:=nil;
NormalUnits:=nil; NormalUnits:=nil;
@ -183,9 +200,10 @@ begin
+NotFoundUnits,mtWarning,[mrIgnore,mrAbort],0); +NotFoundUnits,mtWarning,[mrIgnore,mrAbort],0);
if Result<>mrIgnore then exit; if Result<>mrIgnore then exit;
end; end;
// add all units to the project // add all units to the project
debugln('ConvertDelphiToLazarusProject adding all project units to project ...'); debugln('ConvertDelphiToLazarusProject adding all project units to project ...');
for i:=0 to FoundInUnits.Count-1 do begin for i:=0 to FoundInUnits.Count-1 do begin
CurFilename:=FoundInUnits[i]; CurFilename:=FoundInUnits[i];
p:=System.Pos(' in ',CurFilename); p:=System.Pos(' in ',CurFilename);
@ -194,6 +212,7 @@ begin
if CurFilename='' then continue; if CurFilename='' then continue;
if not FilenameIsAbsolute(CurFilename) then if not FilenameIsAbsolute(CurFilename) then
CurFilename:=AppendPathDelim(Project1.ProjectDirectory)+CurFilename; CurFilename:=AppendPathDelim(Project1.ProjectDirectory)+CurFilename;
CurFilename:=TrimFilename(CurFilename);
if not FileExists(CurFilename) then begin if not FileExists(CurFilename) then begin
DebugLn('ConvertDelphiToLazarusProject file not found: "',CurFilename,'"'); DebugLn('ConvertDelphiToLazarusProject file not found: "',CurFilename,'"');
continue; continue;
@ -202,6 +221,29 @@ begin
if CurUnitInfo<>nil then begin if CurUnitInfo<>nil then begin
CurUnitInfo.IsPartOfProject:=true; CurUnitInfo.IsPartOfProject:=true;
end else begin end else begin
if FilenameIsPascalUnit(CurFilename) then begin
// check unitname
OffendingUnit:=Project1.UnitWithUnitname(
ExtractFileNameOnly(CurFilename));
if OffendingUnit<>nil then begin
Result:=QuestionDlg('Unitname exists twice',
'There are two units with the same unitname:'#13
+OffendingUnit.Filename+#13
+CurFilename+#13,
mtWarning,[mrYes,'Remove first',mrNo,'Remove second',
mrIgnore,'Keep both',mrAbort],0);
case Result of
mrYes: OffendingUnit.IsPartOfProject:=false;
mrNo: continue;
mrIgnore: ;
else
Result:=mrAbort;
exit;
end;
end;
end;
// add new unit to project
CurUnitInfo:=TUnitInfo.Create(nil); CurUnitInfo:=TUnitInfo.Create(nil);
CurUnitInfo.Filename:=CurFilename; CurUnitInfo.Filename:=CurFilename;
CurUnitInfo.IsPartOfProject:=true; CurUnitInfo.IsPartOfProject:=true;
@ -214,7 +256,8 @@ begin
NewUnitPath:=RemoveSearchPaths(NewUnitPath, NewUnitPath:=RemoveSearchPaths(NewUnitPath,
'.;'+VirtualDirectory+';'+VirtualTempDir '.;'+VirtualDirectory+';'+VirtualTempDir
+';'+Project1.ProjectDirectory); +';'+Project1.ProjectDirectory);
Project1.CompilerOptions.OtherUnitFiles:=NewUnitPath; Project1.CompilerOptions.OtherUnitFiles:=MinimizeSearchPath(
RemoveNonExistingPaths(NewUnitPath,Project1.ProjectDirectory));
DebugLn('ConvertDelphiToLazarusProject UnitPath="',Project1.CompilerOptions.OtherUnitFiles,'"'); DebugLn('ConvertDelphiToLazarusProject UnitPath="',Project1.CompilerOptions.OtherUnitFiles,'"');
// save project // save project
@ -224,29 +267,6 @@ begin
DebugLn('ConvertDelphiToLazarusProject failed saving project'); DebugLn('ConvertDelphiToLazarusProject failed saving project');
exit; exit;
end; end;
// convert all units
i:=0;
while i<Project1.UnitCount do begin
CurUnitInfo:=Project1.Units[i];
if CurUnitInfo.IsPartOfProject and not (CurUnitInfo.IsMainUnit) then begin
Result:=ConvertDelphiToLazarusUnit(CurUnitInfo.Filename,
RenameLowercase,true);
if Result=mrAbort then exit;
if Result=mrCancel then begin
Result:=QuestionDlg('Failed converting unit',
'Failed to convert unit'+#13
+CurUnitInfo.Filename+#13,
mtWarning,[mrIgnore,'Ignore and continue',mrAbort],0);
if Result=mrAbort then exit;
end;
if LazarusIDE.DoCloseEditorFile(CurUnitInfo.Filename,[cfSaveFirst])
=mrAbort
then
exit;
end;
inc(i);
end;
finally finally
FoundInUnits.Free; FoundInUnits.Free;
@ -254,12 +274,43 @@ begin
NormalUnits.Free; NormalUnits.Free;
end; end;
debugln('ConvertDelphiToLazarusProject Done'); Result:=mrOk;
end;
function ConvertAllDelphiProjectUnits(AProject: TProject;
Flags: TConvertDelphiToLazarusUnitFlags): TModalResult;
var
i: Integer;
CurUnitInfo: TUnitInfo;
begin
// convert all units
i:=0;
while i<Project1.UnitCount do begin
CurUnitInfo:=Project1.Units[i];
if CurUnitInfo.IsPartOfProject and not (CurUnitInfo.IsMainUnit) then begin
Result:=ConvertDelphiToLazarusUnit(CurUnitInfo.Filename,
Flags+[cdtlufIsSubProc]);
if Result=mrAbort then exit;
if Result=mrCancel then begin
Result:=QuestionDlg('Failed converting unit',
'Failed to convert unit'+#13
+CurUnitInfo.Filename+#13,
mtWarning,[mrIgnore,'Ignore and continue',mrAbort],0);
if Result=mrAbort then exit;
end;
if LazarusIDE.DoCloseEditorFile(CurUnitInfo.Filename,[cfSaveFirst])
=mrAbort
then
exit;
end;
inc(i);
end;
Result:=mrOk; Result:=mrOk;
end; end;
function ConvertDelphiToLazarusUnit(const DelphiFilename: string; function ConvertDelphiToLazarusUnit(const DelphiFilename: string;
RenameLowercase, IsSubProc: boolean): TModalResult; Flags: TConvertDelphiToLazarusUnitFlags): TModalResult;
var var
DFMFilename: String; DFMFilename: String;
LazarusUnitFilename: String; LazarusUnitFilename: String;
@ -290,7 +341,8 @@ begin
DebugLn('ConvertDelphiToLazarusUnit Rename files'); DebugLn('ConvertDelphiToLazarusUnit Rename files');
LazarusUnitFilename:=''; LazarusUnitFilename:='';
LFMFilename:=''; LFMFilename:='';
Result:=RenameDelphiUnitToLazarusUnit(DelphiFilename,true,RenameLowercase, Result:=RenameDelphiUnitToLazarusUnit(DelphiFilename,true,
cdtlufRenameLowercase in Flags,
LazarusUnitFilename,LFMFilename); LazarusUnitFilename,LFMFilename);
if Result<>mrOk then exit; if Result<>mrOk then exit;
if LFMFilename='' then LFMFilename:=ChangeFileExt(LazarusUnitFilename,'.lfm'); if LFMFilename='' then LFMFilename:=ChangeFileExt(LazarusUnitFilename,'.lfm');
@ -324,10 +376,10 @@ begin
// fix or comment missing units // fix or comment missing units
DebugLn('ConvertDelphiToLazarusUnit FixMissingUnits'); DebugLn('ConvertDelphiToLazarusUnit FixMissingUnits');
Result:=FixMissingUnits(LazarusUnitFilename,IsSubProc); Result:=FixMissingUnits(LazarusUnitFilename,cdtlufIsSubProc in Flags);
if Result=mrAbort then exit; if Result=mrAbort then exit;
if (Result<>mrOk) then begin if (Result<>mrOk) then begin
Result:=JumpToCodetoolErrorAndAskToAbort(IsSubProc); Result:=JumpToCodetoolErrorAndAskToAbort(cdtlufIsSubProc in Flags);
exit; exit;
end; end;
@ -339,9 +391,11 @@ begin
// TODO: fix delphi ambiguousities like incomplete proc implementation headers // TODO: fix delphi ambiguousities like incomplete proc implementation headers
Result:=ConvertDelphiSourceToLazarusSource(LazarusUnitFilename, Result:=ConvertDelphiSourceToLazarusSource(LazarusUnitFilename,
LRSFilename<>''); LRSFilename<>'');
if not IfNotOkJumpToCodetoolErrorAndAskToAbort(Result=mrOk,IsSubProc,Result) if not IfNotOkJumpToCodetoolErrorAndAskToAbort(Result=mrOk,
cdtlufIsSubProc in Flags,Result)
then exit; then exit;
// check the LFM file and the pascal unit // check the LFM file and the pascal unit
DebugLn('ConvertDelphiToLazarusUnit Check new .lfm and .pas file'); DebugLn('ConvertDelphiToLazarusUnit Check new .lfm and .pas file');
Result:=LoadUnitAndLFMFile(LazarusUnitFilename,UnitCode,LFMCode,HasDFMFile); Result:=LoadUnitAndLFMFile(LazarusUnitFilename,UnitCode,LFMCode,HasDFMFile);
@ -460,5 +514,26 @@ begin
end; end;
end; end;
procedure CleanUpProjectSearchPaths(AProject: TProject);
function CleanProjectSearchPath(const SearchPath: string): string;
begin
Result:=RemoveNonExistingPaths(SearchPath,Project1.ProjectDirectory);
Result:=MinimizeSearchPath(Result);
end;
begin
AProject.CompilerOptions.OtherUnitFiles:=
CleanProjectSearchPath(AProject.CompilerOptions.OtherUnitFiles);
AProject.CompilerOptions.IncludeFiles:=
CleanProjectSearchPath(AProject.CompilerOptions.IncludeFiles);
AProject.CompilerOptions.Libraries:=
CleanProjectSearchPath(AProject.CompilerOptions.Libraries);
AProject.CompilerOptions.ObjectPath:=
CleanProjectSearchPath(AProject.CompilerOptions.ObjectPath);
AProject.CompilerOptions.SrcPath:=
CleanProjectSearchPath(AProject.CompilerOptions.SrcPath);
end;
end. end.

View File

@ -205,6 +205,7 @@ begin
end; end;
end; end;
if not FileExists(LFMFilename) then begin if not FileExists(LFMFilename) then begin
// TODO: update project
Result:=RenameFileWithErrorDialogs(DFMFilename,LFMFilename,[mbAbort]); Result:=RenameFileWithErrorDialogs(DFMFilename,LFMFilename,[mbAbort]);
if Result<>mrOK then exit; if Result<>mrOK then exit;
end; end;

View File

@ -8129,7 +8129,7 @@ function TMainIDE.DoConvertDelphiUnit(const DelphiFilename: string
): TModalResult; ): TModalResult;
begin begin
InputHistories.LastConvertDelphiUnit:=DelphiFilename; InputHistories.LastConvertDelphiUnit:=DelphiFilename;
Result:=DelphiProject2Laz.ConvertDelphiToLazarusUnit(DelphiFilename,false,false); Result:=DelphiProject2Laz.ConvertDelphiToLazarusUnit(DelphiFilename,[]);
end; end;
function TMainIDE.DoConvertDelphiProject(const DelphiFilename: string function TMainIDE.DoConvertDelphiProject(const DelphiFilename: string