Converter: a patch from Stephano. Temporarily broken but applied to help co-operation and easier fixes.

git-svn-id: trunk@28438 -
This commit is contained in:
juha 2010-11-23 23:02:21 +00:00
parent c4d4d4f6c3
commit 15785bf24f
2 changed files with 429 additions and 129 deletions

View File

@ -46,7 +46,8 @@ uses
type
TUsesSection=(usMain, usImplementation);
//defined in StdCodeTools
//TUsesSection=(usMain, usImplementation);
{ TConvDelphiCodeTool }
@ -62,19 +63,33 @@ type
fDfmDirectiveEnd: integer;
fExistingUsesMain: TStringList;
fExistingUsesImplementation: TStringList;
// List of Delphi only units
fDelphiOnlyMainUnits: TStringList;
fDelphiOnlyImplementationUnits: TStringList;
// List of LCL only units
fLCLOnlyMainUnits: TStringList;
fLCLOnlyImplementationUnits: TStringList;
// List of common units
fCommonMainUnits: TStringList;
fCommonImplementationUnits: TStringList;
// List of units to remove.
fUnitsToRemove: TStringList;
//fUnitsToRemove: TStringList;
fMainUnitsToRemove: TStringList;
fImplementationUnitsToRemove: TStringList;
// Units to rename. Map of unit name -> real unit name.
fUnitsToRename: TStringToStringTree;
//fUnitsToRename: TStringToStringTree;
fMainUnitsToRename: TStringToStringTree;
fImplementationUnitsToRename: TStringToStringTree;
// List of units to be commented.
fUnitsToComment: TStringList;
//fUnitsToComment: TStringList;
fMainUnitsToComment: TStringList;
fImplementationUnitsToComment: TStringList;
// Delphi Function names to replace with FCL/LCL functions.
fDefinedProcNames: TStringList;
// List of TFuncReplacement.
fFuncsToReplace: TObjectList;
fSettings: TConvertSettings; // Conversion settings.
function AddDelphiAndLCLSections: boolean;
function AddModeDelphiDirective: boolean;
procedure ConvAddDelphiAndLCLUnitsToUsesSection(AUsesSection: TUsesSection;
DelphiOnlyUnits, LCLOnlyUnits: TStringList);
@ -89,21 +104,37 @@ type
destructor Destroy; override;
function Convert(aIsConsoleApp: boolean): TModalResult;
function FindApptypeConsole: boolean;
function RemoveUnits: boolean;
function RenameUnits: boolean;
function AddUnits(AMainUnitsToAdd, AImplementationUnitsToAdd: TStrings): boolean;
function RemoveUnits(AUnitsToRemove: TStrings): boolean;
function RenameUnits(AUnitsToRename: TStringToStringTree): boolean;
function FixMainClassAncestor(const AClassName: string;
AReplaceTypes: TStringToStringTree): boolean;
function CheckTopOffsets(LFMBuf: TCodeBuffer; LFMTree: TLFMTree;
VisOffsets: TVisualOffsets; ValueNodes: TObjectList): boolean;
function AddDelphiAndLCLSections: boolean;//should be private
procedure CommentUsesSection(AUsesSection: TUsesSection);//should be private
procedure UnCommentUsesSection(AUsesSection: TUsesSection);//should be private
function AddLCLUnitsToUsesSections(LCLMainUnits,
LCLImplementationUnits: TStringList): boolean;//should be private
public
property ExistingUsesMain: TStringList read fExistingUsesMain;
property ExistingUsesImplementation: TStringList read fExistingUsesImplementation;
property Ask: Boolean read fAsk write fAsk;
property HasFormFile: boolean read fHasFormFile write fHasFormFile;
property LowerCaseRes: boolean read fLowerCaseRes write fLowerCaseRes;
property UnitsToRemove: TStringList read fUnitsToRemove write fUnitsToRemove;
property UnitsToRename: TStringToStringTree read fUnitsToRename write fUnitsToRename;
property UnitsToComment: TStringList read fUnitsToComment write fUnitsToComment;
property DelphiOnlyMainUnits: TStringList read fDelphiOnlyMainUnits write fDelphiOnlyMainUnits;
property DelphiOnlyImplementationUnits: TStringList read fDelphiOnlyImplementationUnits write fDelphiOnlyImplementationUnits;
property LCLOnlyMainUnits: TStringList read fLCLOnlyMainUnits write fLCLOnlyMainUnits;
property LCLOnlyImplementationUnits: TStringList read fLCLOnlyImplementationUnits write fLCLOnlyImplementationUnits;
property CommonMainUnits: TStringList read fCommonMainUnits write fCommonMainUnits;
property CommonImplementationUnits: TStringList read fCommonImplementationUnits write fCommonImplementationUnits;
property MainUnitsToRemove: TStringList read fMainUnitsToRemove write fMainUnitsToRemove;
property ImplementationUnitsToRemove: TStringList read fImplementationUnitsToRemove write fImplementationUnitsToRemove;
property MainUnitsToRename: TStringToStringTree read fMainUnitsToRename write fMainUnitsToRename;
property ImplementationUnitsToRename: TStringToStringTree read fImplementationUnitsToRename write fImplementationUnitsToRename;
property MainUnitsToComment: TStringList read fMainUnitsToComment write fMainUnitsToComment;
property ImplementationUnitsToComment: TStringList read fImplementationUnitsToComment write fImplementationUnitsToComment;
property Settings: TConvertSettings read fSettings write fSettings;
end;
@ -120,9 +151,12 @@ begin
// Default values for vars.
fAsk:=true;
fLowerCaseRes:=false;
fUnitsToRemove:=nil; // These are set from outside.
fUnitsToComment:=nil;
fUnitsToRename:=nil;
fMainUnitsToRemove:=nil; // These are set from outside.
fImplementationUnitsToRemove:=nil;
fMainUnitsToComment:=nil;
fImplementationUnitsToComment:=nil;
fMainUnitsToRename:=nil;
fImplementationUnitsToRename:=nil;
fExistingUsesMain:=TStringList.Create;
fExistingUsesMain.CaseSensitive:=false;
fExistingUsesImplementation:=TStringList.Create;
@ -197,8 +231,10 @@ begin
end;
if fSettings.Target=ctLazarus then begin
// One way conversion -> remove and rename units.
if not RemoveUnits then exit;
if not RenameUnits then exit;
if not RemoveUnits(fMainUnitsToRemove) then exit;
if not RemoveUnits(fImplementationUnitsToRemove) then exit;
if not RenameUnits(fMainUnitsToRename) then exit;
if not RenameUnits(fImplementationUnitsToRename) then exit;
end;
if fSettings.Target in [ctLazarusDelphi, ctLazarusDelphiSameDfm] then begin
// Support Delphi. Add IFDEF blocks for units.
@ -233,6 +269,56 @@ begin
end;
end;
procedure TConvDelphiCodeTool.CommentUsesSection(AUsesSection: TUsesSection);
var
AUsesNode: TCodeTreeNode;
InsPos1, InsPos2: Integer;
begin
fSrcCache.MainScanner:=fCodeTool.Scanner;
fCodeTool.BuildTree(AUsesSection=usMain);
case AUsesSection Of
usMain: AUsesNode:=fCodeTool.FindMainUsesSection;
usImplementation: AUsesNode:=fCodeTool.FindImplementationUsesSection;
end;
if AUsesNode=nil then
exit;
InsPos1:=AUsesNode.StartPos;
fCodeTool.MoveCursorToUsesEnd(AUsesNode);
InsPos2:=fCodeTool.CurPos.EndPos;
//fSrcCache.ReplaceEx();
fCodeTool.CommentCode(InsPos1, InsPos2, fSrcCache, true);
end;
procedure TConvDelphiCodeTool.UnCommentUsesSection(AUsesSection: TUsesSection);
var
AUsesNode: TCodeTreeNode;
InsPos1, InsPos2: Integer;
begin
fSrcCache.MainScanner:=fCodeTool.Scanner;
fCodeTool.BuildTree(AUsesSection=usMain);
case AUsesSection Of
usMain: AUsesNode:=fCodeTool.FindInterfaceNode;
usImplementation: AUsesNode:=fCodeTool.FindImplementationNode;
end;
if AUsesNode=nil then
exit;
case AUsesSection Of
usMain: fCodeTool.AddUnitToMainUsesSection('windows', '', fSrcCache, false);
usImplementation: ;//fCodeTool.AddUnitToImplementationUsesSection('consts', '', fSrcCache, false);
end;
fSrcCache.Apply;
fCodeTool.MoveCursorToNodeStart(AUsesNode);
//while not fCodeTool.AtomIs('end') do begin
// fCodeTool.ReadNextAtom;
//end;
//
//InsPos1:=AUsesNode.StartPos;
//fCodeTool.MoveCursorToUsesEnd(AUsesNode);
//InsPos2:=fCodeTool.CurPos.EndPos;
//fCodeTool.CommentCode(InsPos1, InsPos2, fSrcCache, true);
end;
procedure TConvDelphiCodeTool.ConvAddDelphiAndLCLUnitsToUsesSection(
AUsesSection: TUsesSection; DelphiOnlyUnits, LCLOnlyUnits: TStringList);
var
@ -255,9 +341,9 @@ begin
LclOnlyUnitsStr:='';
for i:=0 to LclOnlyUnits.Count-1 do begin
if i<LclOnlyUnits.Count-1 then
LclOnlyUnitsStr:=LclOnlyUnitsStr+DelphiOnlyUnits[i]+', '
LclOnlyUnitsStr:=LclOnlyUnitsStr+LCLOnlyUnits[i]+', '
else
LclOnlyUnitsStr:=LclOnlyUnitsStr+DelphiOnlyUnits[i];
LclOnlyUnitsStr:=LclOnlyUnitsStr+LCLOnlyUnits[i];
end;
fSrcCache.MainScanner:=fCodeTool.Scanner;
fCodeTool.BuildTree(AUsesSection=usMain);
@ -308,6 +394,49 @@ begin
if not fSrcCache.Replace(gtNewLine,gtNone,InsPos,InsPos,s) then exit;
end;
function TConvDelphiCodeTool.AddLCLUnitsToUsesSections(LCLMainUnits, LCLImplementationUnits: TStringList): boolean;
var
AUsesNode: TCodeTreeNode;
s: string;
InsPos, i: integer;
begin
Result:=true;
if Assigned(LCLMainUnits) and (LCLMainUnits.Count>=1) then begin
s:='uses '+LCLMainUnits[0];
for i:=1 to LCLMainUnits.Count-1 do
s:=s+', '+LCLMainUnits[i];
s:=s+';';
fSrcCache.MainScanner:=fCodeTool.Scanner;
fCodeTool.BuildTree(true);
AUsesNode:=fCodeTool.FindInterfaceNode;
if Assigned(AUsesNode) then begin
InsPos:=AUsesNode.EndPos;
Result:=fSrcCache.Replace(gtNone,gtNone,InsPos,InsPos,s);
end
else
ShowMessage('Debug AddLCLUnitsToUsesSections: No InterfaceNode in this file! (will be fixed soon)');
end;
if not Result then
exit;
if Assigned(LCLImplementationUnits) and (LCLImplementationUnits.Count>=1) then begin
s:='uses '+LCLImplementationUnits[0];
for i:=1 to LCLImplementationUnits.Count-1 do
s:=s+', '+LCLImplementationUnits[i];
s:=s+';';
fSrcCache.MainScanner:=fCodeTool.Scanner;
fCodeTool.BuildTree(false);
AUsesNode:=fCodeTool.FindImplementationNode;
if Assigned(AUsesNode) then begin
InsPos:=AUsesNode.EndPos;
Result:=fSrcCache.Replace(gtNone,gtNone,InsPos,InsPos,s);
end
else
ShowMessage('Debug AddLCLUnitsToUsesSections: No ImplementationNode in this file!');
end;
if not Result then
exit;
end;
function TConvDelphiCodeTool.AddDelphiAndLCLSections: boolean;
// Add unit names into conditional blocks for Delphi and Lazarus targets. If the name
// would otherwise be deleted or commented out, now it is added to Delphi block.
@ -315,7 +444,7 @@ var
DelphiOnlyUnits: TStringList; // Delphi specific units.
LclOnlyUnits: TStringList; // LCL specific units.
procedure ConvUsesUnits(AUsesSection: TUsesSection; AUsesUnits: TStringList);
procedure ConvUsesUnits(AUsesSection: TUsesSection; AUsesUnits, AUnitsToRemove, AUnitsToComment: TStringList; AUnitsToRename: TStringToStringTree);
var
i, ind: Integer;
s: string;
@ -333,16 +462,16 @@ var
if AUsesNode=nil then
exit;
// Don't remove the unit names but add to Delphi block instead.
for i:=0 to fUnitsToRemove.Count-1 do begin
s:=fUnitsToRemove[i];
for i:=0 to AUnitsToRemove.Count-1 do begin
s:=AUnitsToRemove[i];
if AUsesUnits.Find(s, ind) then begin // if RemoveUsesUnit(AUsesNode, s) then
fCodeTool.RemoveUnitFromUsesSection(AUsesNode, UpperCaseStr(s), fSrcCache);
DelphiOnlyUnits.Append(s);
end;
end;
// ... and don't comment the unit names either.
for i:=0 to fUnitsToComment.Count-1 do begin
s:=fUnitsToComment[i];
for i:=0 to AUnitsToComment.Count-1 do begin
s:=AUnitsToComment[i];
if AUsesUnits.Find(s, ind) then begin // if RemoveUsesUnit(AUsesNode, s) then
fCodeTool.RemoveUnitFromUsesSection(AUsesNode, UpperCaseStr(s), fSrcCache);
DelphiOnlyUnits.Append(s);
@ -351,13 +480,13 @@ var
RenameList:=TStringList.Create;
try
// Add replacement units to LCL block.
fUnitsToRename.GetNames(RenameList);
AUnitsToRename.GetNames(RenameList);
for i:=0 to RenameList.Count-1 do begin
s:=RenameList[i];
if AUsesUnits.Find(s, ind) then begin // if RemoveUsesUnit(AUsesNode, s) then begin
fCodeTool.RemoveUnitFromUsesSection(AUsesNode, UpperCaseStr(s), fSrcCache);
DelphiOnlyUnits.Append(s);
LCLOnlyUnits.Append(fUnitsToRename[s]);
LCLOnlyUnits.Append(AUnitsToRename[s]);
end;
end;
finally
@ -373,9 +502,9 @@ begin
LclOnlyUnits:=TStringList.Create;
try
// Main uses section
ConvUsesUnits(usMain, fExistingUsesMain);
ConvUsesUnits(usMain, fExistingUsesMain, fMainUnitsToRemove, fMainUnitsToComment, fMainUnitsToRename);
// Implementation uses section
ConvUsesUnits(usImplementation, fExistingUsesImplementation);
ConvUsesUnits(usImplementation, fExistingUsesImplementation, fImplementationUnitsToRemove, fImplementationUnitsToComment, fImplementationUnitsToRename);
Result:=true;
finally
LclOnlyUnits.Free;
@ -486,34 +615,46 @@ begin
Result:=true;
end;
function TConvDelphiCodeTool.RemoveUnits: boolean;
function TConvDelphiCodeTool.AddUnits(AMainUnitsToAdd, AImplementationUnitsToAdd: TStrings): boolean;
var
i: Integer;
begin
if AMainUnitsToAdd<>nil then;
for i:=0 to AMainUnitsToAdd.Count-1 do
fCodeTool.AddUnitToSpecificUsesSection(usMain, AMainUnitsToAdd[i], '', fSrcCache);
if AImplementationUnitsToAdd<>nil then;
for i:=0 to AImplementationUnitsToAdd.Count-1 do
fCodeTool.AddUnitToSpecificUsesSection(usImplementation, AImplementationUnitsToAdd[i], '', fSrcCache);
end;
function TConvDelphiCodeTool.RemoveUnits(AUnitsToRemove: TStrings): boolean;
// Remove units
var
i: Integer;
begin
Result:=false;
if Assigned(fUnitsToRemove) then begin
for i:=0 to fUnitsToRemove.Count-1 do begin
if Assigned(AUnitsToRemove) then begin
for i:=0 to AUnitsToRemove.Count-1 do begin
fSrcCache:=CodeToolBoss.SourceChangeCache;
fSrcCache.MainScanner:=fCodeTool.Scanner;
if not fCodeTool.RemoveUnitFromAllUsesSections(UpperCaseStr(fUnitsToRemove[i]),
if not fCodeTool.RemoveUnitFromAllUsesSections(UpperCaseStr(AUnitsToRemove[i]),
fSrcCache) then
exit;
if not fSrcCache.Apply then exit;
end;
end;
fUnitsToRemove.Clear;
//AUnitsToRemove.Clear;
Result:=true;
end;
function TConvDelphiCodeTool.RenameUnits: boolean;
function TConvDelphiCodeTool.RenameUnits(AUnitsToRename: TStringToStringTree): boolean;
// Rename units
begin
Result:=false;
if Assigned(fUnitsToRename) then
if not fCodeTool.ReplaceUsedUnits(fUnitsToRename, fSrcCache) then
if Assigned(AUnitsToRename) then
if not fCodeTool.ReplaceUsedUnits(AUnitsToRename, fSrcCache) then
exit;
fUnitsToRename.Clear;
AUnitsToRename.Clear;
Result:=true;
end;
@ -521,8 +662,11 @@ function TConvDelphiCodeTool.CommentOutUnits: boolean;
// Comment out missing units
begin
Result:=false;
if Assigned(fUnitsToComment) and (fUnitsToComment.Count>0) then
if not fCodeTool.CommentUnitsInUsesSections(fUnitsToComment, fSrcCache) then
if Assigned(fMainUnitsToComment) and (fMainUnitsToComment.Count>0) then
if not fCodeTool.CommentUnitsInUsesSections(fMainUnitsToComment, fSrcCache) then
exit;
if Assigned(fImplementationUnitsToComment) and (fImplementationUnitsToComment.Count>0) then
if not fCodeTool.CommentUnitsInUsesSections(fImplementationUnitsToComment, fSrcCache) then
exit;
Result:=true;
end;

View File

@ -91,13 +91,13 @@ type
fLFMBuffer: TCodeBuffer;
fFlags: TConvertUnitFlags;
// Units not found in project dir or packages.
fMissingUnits: TStrings;
fMissingMainUnits, fMissingImplementationUnits: TStringList;
// List of units to remove (or keep in IFDEF when Delphi is supported).
fUnitsToRemove: TStringList;
fMainUnitsToRemove, fImplementationUnitsToRemove: TStringList;
// Units to rename. Map of unit name -> real unit name.
fUnitsToRename: TStringToStringTree;
fMainUnitsToRename, fImplementationUnitsToRename: TStringToStringTree;
// Units to be commented later.
fUnitsToComment: TStringList;
fMainUnitsToComment, fImplementationUnitsToComment: TStringList;
fSettings: TConvertSettings;
function GetDfmFileName: string;
@ -105,8 +105,8 @@ type
function ConvertUnitFile: TModalResult;
function ConvertFormFile: TModalResult;
function MissingUnitToMsg(MissingUnit: string): string;
function CommentAutomatically: integer;
function AskUnitPathFromUser: TModalResult;
function CommentAutomatically(AMissingUnits: TStrings; AUnitsToComment: TStringList): integer;
function AskUnitPathFromUser(AMissingUnits: TStrings; AUnitsToComment: TStringList; AUnitsToRename: TStringToStringTree): TModalResult;
function FixIncludeFiles: TModalResult;
function FixMissingUnits: TModalResult;
protected
@ -557,9 +557,12 @@ var
ConvTool: TConvDelphiCodeTool;
begin
Result:=mrOK;
fUnitsToRemove:=TStringList.Create;
fUnitsToRename:=TStringToStringTree.Create(false);
fUnitsToComment:=TStringList.Create;
fMainUnitsToRemove:=TStringList.Create;
fImplementationUnitsToRemove:=TStringList.Create;
fMainUnitsToRename:=TStringToStringTree.Create(false);
fImplementationUnitsToRename:=TStringToStringTree.Create(false);
fMainUnitsToComment:=TStringList.Create;
fImplementationUnitsToComment:=TStringList.Create;
try
IDEMessagesWindow.AddMsg(Format(lisConvDelphiConvertingUnitFile, [
fOrigUnitFilename]), '', -1);
@ -624,17 +627,23 @@ begin
ConvTool.LowerCaseRes:=FileExistsUTF8(ChangeFileExt(fLazUnitFilename, '.res'));
ConvTool.HasFormFile:=DfmFilename<>'';
ConvTool.Settings:=fSettings;
ConvTool.UnitsToRemove:=fUnitsToRemove;
ConvTool.UnitsToRename:=fUnitsToRename;
ConvTool.UnitsToComment:=fUnitsToComment;
ConvTool.MainUnitsToRemove:=fMainUnitsToRemove;
ConvTool.ImplementationUnitsToRemove:=fImplementationUnitsToRemove;
ConvTool.MainUnitsToRename:=fMainUnitsToRename;
ConvTool.ImplementationUnitsToRename:=fImplementationUnitsToRename;
ConvTool.MainUnitsToComment:=fMainUnitsToComment;
ConvTool.ImplementationUnitsToComment:=fImplementationUnitsToComment;
Result:=ConvTool.Convert(ConsApp);
finally
ConvTool.Free;
end;
finally
fUnitsToComment.Free;
fUnitsToRename.Free;
fUnitsToRemove.Free;
fMainUnitsToComment.Free;
fImplementationUnitsToComment.Free;
fMainUnitsToRename.Free;
fImplementationUnitsToRename.Free;
fMainUnitsToRemove.Free;
fImplementationUnitsToRemove.Free;
end;
end;
@ -690,24 +699,24 @@ begin
, IntToStr(Col), MissingUnit]);
end;
function TConvertDelphiUnit.CommentAutomatically: integer;
function TConvertDelphiUnit.CommentAutomatically(AMissingUnits: TStrings; AUnitsToComment: TStringList): integer;
// Comment automatically unit names that were commented in other files.
// Return the number of missing units still left.
var
i, x: Integer;
s: string;
begin
for i:=fMissingUnits.Count-1 downto 0 do begin
s:=fMissingUnits[i];
for i:=AMissingUnits.Count-1 downto 0 do begin
s:=AMissingUnits[i];
if fOwnerConverter.fAllMissingUnits.Find(s, x) then begin
fUnitsToComment.Append(s);
fMissingUnits.Delete(i);
AUnitsToComment.Append(s);
AMissingUnits.Delete(i);
end;
end;
Result:=fMissingUnits.Count;
Result:=AMissingUnits.Count;
end;
function TConvertDelphiUnit.AskUnitPathFromUser: TModalResult;
function TConvertDelphiUnit.AskUnitPathFromUser(AMissingUnits: TStrings; AUnitsToComment: TStringList; AUnitsToRename: TStringToStringTree): TModalResult;
var
TryAgain: Boolean;
UnitDirDialog: TSelectDirectoryDialog;
@ -715,15 +724,15 @@ begin
// ask user what to do
repeat
TryAgain:=False;
Result:=AskMissingUnits(fMissingUnits, ExtractFileName(fLazUnitFilename),
Result:=AskMissingUnits(AMissingUnits, ExtractFileName(fLazUnitFilename),
fSettings.Target in [ctLazarusDelphi, ctLazarusDelphiSameDfm]);
case Result of
// mrOK means: comment out.
mrOK: begin
// These units will be commented automatically in this project/package.
if Assigned(fOwnerConverter) then
fOwnerConverter.fAllMissingUnits.AddStrings(fMissingUnits);
fUnitsToComment.AddStrings(fMissingUnits);
fOwnerConverter.fAllMissingUnits.AddStrings(AMissingUnits);
AUnitsToComment.AddStrings(AMissingUnits);
end;
// mrYes means: Search for unit path.
mrYes: begin
@ -737,7 +746,7 @@ begin
fOwnerConverter.fPrevSelectedPath:=ExtractFilePath(UnitDirDialog.Filename);
// Add the new path to project if missing units are found.
fOwnerConverter.CacheUnitsInPath(UnitDirDialog.Filename);
TryAgain:=fOwnerConverter.DoMissingUnits(fMissingUnits, fUnitsToRename)>0;
TryAgain:=fOwnerConverter.DoMissingUnits(AMissingUnits, AUnitsToRename)>0;
end;
end
else
@ -791,22 +800,21 @@ end;
function TConvertDelphiUnit.FixMissingUnits: TModalResult;
var
ConvTool: TConvDelphiCodeTool;
MapToEdit: TStringToStringTree;
UnitUpdater: TStringMapUpdater;
AUsedMainUnits, AUsedImplementationUnits: TStrings;
procedure RenameOrRemoveUnit(AOldName, ANewName: string);
procedure RenameOrRemoveUnit(AOldName, ANewName: string; AUnitsToRename: TStringToStringTree; AUnitsToRemove: TStringList);
// Replace a unit name with a new name or remove it if there is no new name.
var
x: Integer;
begin
if (ANewName<>'')
and (not ConvTool.ExistingUsesMain.Find(ANewName, x))
and (not ConvTool.ExistingUsesImplementation.Find(ANewName, x)) then begin
fUnitsToRename[AOldName]:=ANewName;
if ANewName<>'' then begin
AUnitsToRename[AOldName]:=ANewName;
IDEMessagesWindow.AddMsg(Format(
lisConvDelphiReplacedUnitSWithSInUsesSection, [AOldName, ANewName]), ''
, -1);
end
else begin
fUnitsToRemove.Append(AOldName);
AUnitsToRemove.Append(AOldName);
IDEMessagesWindow.AddMsg(Format(
lisConvDelphiRemovedUsedUnitSInUsesSection, [AOldName]), '', -1);
end;
@ -818,46 +826,48 @@ var
CTResult: Boolean;
i: Integer;
s: String;
AAllMissingUnits: TStrings;
begin
Result:=mrOk;
CTResult:=CodeToolBoss.FindMissingUnits(fPascalBuffer,fMissingUnits,true);
fMissingMainUnits.Clear;
fMissingImplementationUnits.Clear;
AAllMissingUnits:=nil;// AAllMissingUnits will be created by CodeToolBoss.FindMissingUnits
try
CTResult:=CodeToolBoss.FindMissingUnits(fPascalBuffer,AAllMissingUnits,true);
if not CTResult then begin
IDEMessagesWindow.AddMsg(Format(lisConvDelphiError, [CodeToolBoss.
ErrorMessage]), '', -1);
IDEMessagesWindow.AddMsg('Error="'+CodeToolBoss.ErrorMessage+'"','',-1);
Result:=mrCancel;
exit;
end;
// Remove Windows specific units from the list if target is "Windows only".
if (fSettings.Target=ctLazarusWin) and Assigned(fMissingUnits) then begin
for i:=fMissingUnits.Count-1 downto 0 do begin
s:=LowerCase(fMissingUnits[i]);
if (fSettings.Target=ctLazarusWin) and Assigned(AAllMissingUnits) then begin
for i:=AAllMissingUnits.Count-1 downto 0 do begin
s:=LowerCase(AAllMissingUnits[i]);
if (s='windows') or (s='variants') or (s='shellapi') then
fMissingUnits.Delete(i);
AAllMissingUnits.Delete(i);
end;
end;
// Split AAllMissingUnits into Main and Implementation
if Assigned(AAllMissingUnits) then begin
for i:=0 to AAllMissingUnits.Count-1 do begin
if AUsedMainUnits.IndexOf(AAllMissingUnits[i])<>-1 then
fMissingMainUnits.Add(AAllMissingUnits[i]);
if AUsedImplementationUnits.IndexOf(AAllMissingUnits[i])<>-1 then
fMissingImplementationUnits.Add(AAllMissingUnits[i]);
end;
end;
finally
AAllMissingUnits.Free;
end;
end;
procedure FindReplacementForMissingUnits(AMissingUnits: TStrings; AUnitsToRename: TStringToStringTree; AUnitsToRemove: TStringList);
var
UnitUpdater: TStringMapUpdater;
MapToEdit: TStringToStringTree;
Node: TAVLTreeNode;
Item: PStringToStringTreeItem;
i: Integer;
i: integer;
UnitN, s: string;
begin
Result:=mrOk;
UnitUpdater:=TStringMapUpdater.Create(fSettings.ReplaceUnits);
ConvTool:=TConvDelphiCodeTool.Create(fPascalBuffer);
if fSettings.UnitsReplaceMode=rlInteractive then
MapToEdit:=TStringToStringTree.Create(false);
fMissingUnits:=nil; // Will be created in CodeToolBoss.FindMissingUnits.
try
Result:=GetMissingUnits;
if (Result<>mrOK) or (fMissingUnits=nil) or (fMissingUnits.Count=0) then exit;
// Find replacements for missing units from settings.
for i:=fMissingUnits.Count-1 downto 0 do begin
UnitN:=fMissingUnits[i];
for i:=AMissingUnits.Count-1 downto 0 do begin
UnitN:=AMissingUnits[i];
if UnitUpdater.FindReplacement(UnitN, s) then begin
// Don't replace Windows unit with LCL units in a console application.
if (LowerCase(UnitN)='windows') and
@ -866,9 +876,45 @@ begin
if fSettings.UnitsReplaceMode=rlInteractive then
MapToEdit[UnitN]:=s // Add for interactive editing.
else
RenameOrRemoveUnit(UnitN, s); // Automatic rename / remove.
if fSettings.Target in [ctLazarusDelphi, ctLazarusDelphiSameDfm] then
AUnitsToRename.Add(UnitN,s)
else
RenameOrRemoveUnit(UnitN, s, AUnitsToRename, AUnitsToRemove); // Automatic rename / remove.
end
else
AUnitsToRemove.Add(UnitN);
end;
end;
var
Node: TAVLTreeNode;
Item: PStringToStringTreeItem;
i: Integer;
UnitN, s: string;
LCLOnlyMainUnits, LCLOnlyImplementationUnits: TStringList;
RenameList: TStringList;
begin
Result:=mrOk;
UnitUpdater:=TStringMapUpdater.Create(fSettings.ReplaceUnits);
ConvTool:=TConvDelphiCodeTool.Create(fPascalBuffer);
if fSettings.UnitsReplaceMode=rlInteractive then
MapToEdit:=TStringToStringTree.Create(false);
AUsedMainUnits:=nil;// AAllMissingUnits will be created by CodeToolBoss.FindMissingUnits
AUsedImplementationUnits:=nil;// AAllMissingUnits will be created by CodeToolBoss.FindMissingUnits
fMissingMainUnits:=TStringList.Create;
fMissingImplementationUnits:=TStringList.Create;
try
if not CodeToolBoss.FindUsedUnitNames(fPascalBuffer, AUsedMainUnits, AUsedImplementationUnits) then begin
IDEMessagesWindow.AddMsg('Error="'+CodeToolBoss.ErrorMessage+'"','',-1);
Result:=mrCancel;
exit;
end;
Result:=GetMissingUnits;
if (Result<>mrOK) or ((fMissingMainUnits=nil) or ((fMissingMainUnits.Count=0)) and ((fMissingImplementationUnits=nil) or (fMissingImplementationUnits.Count=0))) then exit;
// Find replacements for missing units from settings.
FindReplacementForMissingUnits(fMissingMainUnits, fMainUnitsToRename, fMainUnitsToRemove);
FindReplacementForMissingUnits(fMissingImplementationUnits, fImplementationUnitsToRename, fImplementationUnitsToRemove);
if (fSettings.UnitsReplaceMode=rlInteractive) and (MapToEdit.Tree.Count>0) then begin
// Edit, then remove or replace units.
Result:=EditMap(MapToEdit, Format(lisConvDelphiUnitsToReplaceIn, [
@ -878,38 +924,148 @@ begin
Node:=MapToEdit.Tree.FindLowest;
while Node<>nil do begin
Item:=PStringToStringTreeItem(Node.Data);
RenameOrRemoveUnit(Item^.Name, Item^.Value);
UnitN:=Item^.Name;
s:=Item^.Value;
if fSettings.Target in [ctLazarusDelphi, ctLazarusDelphiSameDfm] then begin
if AUsedMainUnits.IndexOf(UnitN)<>-1 then
fMainUnitsToRename.Add(UnitN,s);
if AUsedImplementationUnits.IndexOf(UnitN)<>-1 then
fImplementationUnitsToRename.Add(UnitN,s);
end else
if AUsedMainUnits.IndexOf(UnitN)<>-1 then
RenameOrRemoveUnit(UnitN,s, fMainUnitsToRename, fMainUnitsToRemove);
if AUsedImplementationUnits.IndexOf(UnitN)<>-1 then
RenameOrRemoveUnit(UnitN,s, fImplementationUnitsToRename, fImplementationUnitsToRemove);
Node:=MapToEdit.Tree.FindSuccessor(Node);
end;
end;
// Remove and rename missing units. More of them may be added later.
ConvTool.UnitsToRename:=fUnitsToRename;
ConvTool.RenameUnits;
ConvTool.UnitsToRemove:=fUnitsToRemove;
ConvTool.RemoveUnits;
// Find missing units again. Some replacements may not be valid.
fMissingUnits.Clear;
Result:=GetMissingUnits;
if (Result<>mrOK) or (fMissingUnits.Count=0) then exit;
// delete all uses sections
ConvTool.RemoveUnits(AUsedMainUnits);
ConvTool.RemoveUnits(AUsedImplementationUnits);
//// comment out all uses clauses
//ConvTool.CommentUsesSection(usMain);
//ConvTool.CommentUsesSection(usImplementation);
// Add FPC uses clauses only for further investigation
LCLOnlyMainUnits:=TStringList.Create;
LCLOnlyImplementationUnits:=TStringList.Create;
RenameList:=TStringList.Create;
try
LCLOnlyMainUnits.Assign(AUsedMainUnits);
for i:=0 to fMainUnitsToRemove.Count-1 do
if LCLOnlyMainUnits.IndexOf(fMainUnitsToRemove[i])<>-1 then
LCLOnlyMainUnits.Delete(LCLOnlyMainUnits.IndexOf(fMainUnitsToRemove[i]));
for i:=0 to fMainUnitsToComment.Count-1 do
if LCLOnlyMainUnits.IndexOf(fMainUnitsToComment[i])<>-1 then
LCLOnlyMainUnits.Delete(LCLOnlyMainUnits.IndexOf(fMainUnitsToComment[i]));
fMainUnitsToRename.GetNames(RenameList);
for i:=0 to RenameList.Count-1 do begin
if LCLOnlyMainUnits.IndexOf(RenameList[i])<>-1 then
LCLOnlyMainUnits.Delete(LCLOnlyMainUnits.IndexOf(RenameList[i]));
end;
for i:=0 to RenameList.Count-1 do begin
if LCLOnlyMainUnits.IndexOf(fMainUnitsToRename[RenameList[i]])<>-1 then
LCLOnlyMainUnits.Add(fMainUnitsToRename[RenameList[i]]);
end;
LCLOnlyImplementationUnits.Assign(AUsedImplementationUnits);
for i:=0 to fImplementationUnitsToRemove.Count-1 do
if LCLOnlyImplementationUnits.IndexOf(fImplementationUnitsToRemove[i])<>-1 then
LCLOnlyImplementationUnits.Delete(LCLOnlyImplementationUnits.IndexOf(fImplementationUnitsToRemove[i]));
for i:=0 to fImplementationUnitsToComment.Count-1 do
if LCLOnlyImplementationUnits.IndexOf(fImplementationUnitsToComment[i])<>-1 then
LCLOnlyImplementationUnits.Delete(LCLOnlyImplementationUnits.IndexOf(fImplementationUnitsToComment[i]));
fImplementationUnitsToRename.GetNames(RenameList);
for i:=0 to RenameList.Count-1 do begin
if LCLOnlyImplementationUnits.IndexOf(RenameList[i])<>-1 then
LCLOnlyImplementationUnits.Delete(LCLOnlyImplementationUnits.IndexOf(RenameList[i]));
end;
for i:=0 to RenameList.Count-1 do begin
if LCLOnlyImplementationUnits.IndexOf(fImplementationUnitsToRename[RenameList[i]])<>-1 then
LCLOnlyImplementationUnits.Add(fImplementationUnitsToRename[RenameList[i]]);
end;
ConvTool.AddLCLUnitsToUsesSections(LCLOnlyMainUnits, LCLOnlyImplementationUnits);
// Remove and rename missing units. More of them may be added later.
//ConvTool.RenameUnits;
//ConvTool.DeleteUsesSection;
//ConvTool.RemoveUnits;
//ConvTool.CommonMainUnits.Assign(AUsedMainUnits);
//ConvTool.DelphiOnlyMainUnits.Clear;
//ConvTool.LCLOnlyMainUnits.Clear;
//for i:=0 to fMainUnitsToRemove.Count-1 do begin
// ConvTool.DelphiOnlyMainUnits.Add(fMainUnitsToRemove[i]);
// if ConvTool.CommonMainUnits.IndexOf(fMainUnitsToRemove[i])<>-1 then
// ConvTool.CommonMainUnits.Delete(AUsedMainUnits.IndexOf(fMainUnitsToRemove[i]));
//end;
//for i:=0 to fMainUnitsToComment.Count-1 do begin
// ConvTool.DelphiOnlyMainUnits.Add(fMainUnitsToComment[i]);
// if AUsedMainUnits.IndexOf(fMainUnitsToComment[i])<>-1 then
// AUsedMainUnits.Delete(AUsedMainUnits.IndexOf(fMainUnitsToComment[i]));
//end;
//for i:=0 to fMainUnitsToRename.Count-1 do begin
// ConvTool.DelphiOnlyMainUnits.Add(fMainUnitsToRename[i]);
// if AUsedMainUnits.IndexOf(fMainUnitsToRename[i])<>-1 then
// AUsedMainUnits.Delete(AUsedMainUnits.IndexOf(fMainUnitsToRename[i]));
//end;
//ConvTool.CommonMainUnits;
//ConvTool.DelphiOnlyMainUnits
// Find missing units again. Some replacements may not be valid.
fMissingMainUnits.Clear;
fMissingImplementationUnits.Clear;
Result:=GetMissingUnits;
if (Result=mrOK) and ((fMissingMainUnits.Count<>0) or (fMissingImplementationUnits.Count<>0)) then begin
if Assigned(fOwnerConverter) then begin
// Try to find from subdirectories scanned earlier.
if fOwnerConverter.DoMissingUnits(fMissingUnits, fUnitsToRename)=0 then exit;
if fOwnerConverter.DoMissingUnits(fMissingMainUnits, fMainUnitsToRename)=0 then exit;
if fOwnerConverter.DoMissingUnits(fMissingImplementationUnits, fImplementationUnitsToRename)=0 then exit;
// Comment out automatically units that were commented in other files.
if CommentAutomatically=0 then exit;
if CommentAutomatically(fMissingMainUnits, fMainUnitsToComment)=0 then exit;
if CommentAutomatically(fMissingImplementationUnits, fImplementationUnitsToComment)=0 then exit;
end;
// Interactive dialog for searching unit.
Result:=AskUnitPathFromUser;
Result:=AskUnitPathFromUser(fMissingMainUnits, fMainUnitsToComment, fMainUnitsToRename);
if Result<>mrOK then exit;
Result:=AskUnitPathFromUser(fMissingImplementationUnits, fImplementationUnitsToComment, fImplementationUnitsToRename);
if Result<>mrOK then exit;
end;
// remove all uses section
ConvTool.RemoveUnits(LCLOnlyMainUnits);
ConvTool.RemoveUnits(LCLOnlyImplementationUnits);
//// uncomment old uses sections
//ConvTool.UnCommentUsesSection(usMain);
//ConvTool.UnCommentUsesSection(usImplementation);
//Add back original uses sections
ConvTool.AddUnits(AUsedMainUnits, AUsedImplementationUnits);
ConvTool.MainUnitsToRename:=fMainUnitsToRename;
ConvTool.ImplementationUnitsToRename:=fImplementationUnitsToRename;
ConvTool.MainUnitsToRemove:=fMainUnitsToRemove;
ConvTool.ImplementationUnitsToRemove:=fImplementationUnitsToRemove;
ConvTool.MainUnitsToComment:=fMainUnitsToComment;
ConvTool.ImplementationUnitsToComment:=fImplementationUnitsToComment;
ConvTool.AddDelphiAndLCLSections;
finally
LCLOnlyMainUnits.Free;
LCLOnlyImplementationUnits.Free;
RenameList.Free;
end;
// add error messages, so the user can click on them
for i:=0 to fMissingUnits.Count-1 do
IDEMessagesWindow.AddMsg(MissingUnitToMsg(fMissingUnits[i]),'',-1);
for i:=0 to fMissingMainUnits.Count-1 do
IDEMessagesWindow.AddMsg(MissingUnitToMsg(fMissingMainUnits[i]),'',-1);
for i:=0 to fMissingImplementationUnits.Count-1 do
IDEMessagesWindow.AddMsg(MissingUnitToMsg(fMissingImplementationUnits[i]),'',-1);
Application.ProcessMessages;
finally
if fSettings.UnitsReplaceMode=rlInteractive then
MapToEdit.Free;
fMissingUnits.Free;
AUsedMainUnits.Free;
AUsedImplementationUnits.Free;
fMissingMainUnits.Free;
fMissingImplementationUnits.Free;
ConvTool.Free;
UnitUpdater.Free;
end;