mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-06 04:57:12 +01:00
Converter: Handle units in main and implementation uses sections separately. Includes patch from issue #17578.
git-svn-id: trunk@28062 -
This commit is contained in:
parent
6a1f9c0370
commit
c7e0f334c6
@ -58,6 +58,8 @@ type
|
|||||||
fLowerCaseRes: boolean;
|
fLowerCaseRes: boolean;
|
||||||
fDfmDirectiveStart: integer;
|
fDfmDirectiveStart: integer;
|
||||||
fDfmDirectiveEnd: integer;
|
fDfmDirectiveEnd: integer;
|
||||||
|
fExistingUsesMain: TStringList;
|
||||||
|
fExistingUsesImplementation: TStringList;
|
||||||
// List of units to remove.
|
// List of units to remove.
|
||||||
fUnitsToRemove: TStringList;
|
fUnitsToRemove: TStringList;
|
||||||
// Units to rename. Map of unit name -> real unit name.
|
// Units to rename. Map of unit name -> real unit name.
|
||||||
@ -85,12 +87,13 @@ type
|
|||||||
function FindApptypeConsole: boolean;
|
function FindApptypeConsole: boolean;
|
||||||
function RemoveUnits: boolean;
|
function RemoveUnits: boolean;
|
||||||
function RenameUnits: boolean;
|
function RenameUnits: boolean;
|
||||||
function UsesSectionsToUnitnames: TStringList;
|
|
||||||
function FixMainClassAncestor(const AClassName: string;
|
function FixMainClassAncestor(const AClassName: string;
|
||||||
AReplaceTypes: TStringToStringTree): boolean;
|
AReplaceTypes: TStringToStringTree): boolean;
|
||||||
function CheckTopOffsets(LFMBuf: TCodeBuffer; LFMTree: TLFMTree;
|
function CheckTopOffsets(LFMBuf: TCodeBuffer; LFMTree: TLFMTree;
|
||||||
VisOffsets: TVisualOffsets; ValueNodes: TObjectList): boolean;
|
VisOffsets: TVisualOffsets; ValueNodes: TObjectList): boolean;
|
||||||
public
|
public
|
||||||
|
property ExistingUsesMain: TStringList read fExistingUsesMain;
|
||||||
|
property ExistingUsesImplementation: TStringList read fExistingUsesImplementation;
|
||||||
property Ask: Boolean read fAsk write fAsk;
|
property Ask: Boolean read fAsk write fAsk;
|
||||||
property HasFormFile: boolean read fHasFormFile write fHasFormFile;
|
property HasFormFile: boolean read fHasFormFile write fHasFormFile;
|
||||||
property LowerCaseRes: boolean read fLowerCaseRes write fLowerCaseRes;
|
property LowerCaseRes: boolean read fLowerCaseRes write fLowerCaseRes;
|
||||||
@ -106,6 +109,8 @@ implementation
|
|||||||
{ TConvDelphiCodeTool }
|
{ TConvDelphiCodeTool }
|
||||||
|
|
||||||
constructor TConvDelphiCodeTool.Create(Code: TCodeBuffer);
|
constructor TConvDelphiCodeTool.Create(Code: TCodeBuffer);
|
||||||
|
var
|
||||||
|
UsesNode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
fCode:=Code;
|
fCode:=Code;
|
||||||
// Default values for vars.
|
// Default values for vars.
|
||||||
@ -114,12 +119,24 @@ begin
|
|||||||
fUnitsToRemove:=nil; // These are set from outside.
|
fUnitsToRemove:=nil; // These are set from outside.
|
||||||
fUnitsToComment:=nil;
|
fUnitsToComment:=nil;
|
||||||
fUnitsToRename:=nil;
|
fUnitsToRename:=nil;
|
||||||
|
fExistingUsesMain:=TStringList.Create;
|
||||||
|
fExistingUsesMain.CaseSensitive:=false;
|
||||||
|
fExistingUsesImplementation:=TStringList.Create;
|
||||||
|
fExistingUsesImplementation.CaseSensitive:=false;
|
||||||
// Initialize codetools. (Copied from TCodeToolManager.)
|
// Initialize codetools. (Copied from TCodeToolManager.)
|
||||||
if not CodeToolBoss.InitCurCodeTool(fCode) then exit;
|
if not CodeToolBoss.InitCurCodeTool(fCode) then exit;
|
||||||
try
|
try
|
||||||
fCodeTool:=CodeToolBoss.CurCodeTool;
|
fCodeTool:=CodeToolBoss.CurCodeTool;
|
||||||
fSrcCache:=CodeToolBoss.SourceChangeCache;
|
fSrcCache:=CodeToolBoss.SourceChangeCache;
|
||||||
fSrcCache.MainScanner:=fCodeTool.Scanner;
|
fSrcCache.MainScanner:=fCodeTool.Scanner;
|
||||||
|
// Get existing unit names from uses sections
|
||||||
|
fCodeTool.BuildTree(False);
|
||||||
|
UsesNode:=fCodeTool.FindMainUsesSection;
|
||||||
|
fExistingUsesMain:=TStringList(fCodeTool.UsesSectionToUnitnames(UsesNode));
|
||||||
|
fExistingUsesMain.Sorted:=True;
|
||||||
|
UsesNode:=fCodeTool.FindImplementationUsesSection;
|
||||||
|
fExistingUsesImplementation:=TStringList(fCodeTool.UsesSectionToUnitnames(UsesNode));
|
||||||
|
fExistingUsesImplementation.Sorted:=True;
|
||||||
except
|
except
|
||||||
on e: Exception do
|
on e: Exception do
|
||||||
CodeToolBoss.HandleException(e);
|
CodeToolBoss.HandleException(e);
|
||||||
@ -128,6 +145,8 @@ end;
|
|||||||
|
|
||||||
destructor TConvDelphiCodeTool.Destroy;
|
destructor TConvDelphiCodeTool.Destroy;
|
||||||
begin
|
begin
|
||||||
|
fExistingUsesImplementation.Free;
|
||||||
|
fExistingUsesMain.Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -209,46 +228,38 @@ end;
|
|||||||
|
|
||||||
function TConvDelphiCodeTool.AddDelphiAndLCLSections: boolean;
|
function TConvDelphiCodeTool.AddDelphiAndLCLSections: boolean;
|
||||||
// add, remove and rename units for desired target.
|
// add, remove and rename units for desired target.
|
||||||
|
|
||||||
procedure RemoveUsesUnit(AUnitName: string);
|
|
||||||
var
|
|
||||||
UsesNode: TCodeTreeNode;
|
|
||||||
begin
|
|
||||||
fCodeTool.BuildTree(true);
|
|
||||||
UsesNode:=fCodeTool.FindMainUsesSection;
|
|
||||||
fCodeTool.MoveCursorToUsesStart(UsesNode);
|
|
||||||
fCodeTool.RemoveUnitFromUsesSection(UsesNode, UpperCaseStr(AUnitName), fSrcCache);
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
var
|
||||||
DelphiOnlyUnits: TStringList; // Delphi specific units.
|
DelphiOnlyUnits: TStringList; // Delphi specific units.
|
||||||
LclOnlyUnits: TStringList; // LCL specific units.
|
LclOnlyUnits: TStringList; // LCL specific units.
|
||||||
RenameList: TStringList;
|
MainUsesNode, ImplementationUsesNode: TCodeTreeNode;
|
||||||
UsesNode: TCodeTreeNode;
|
|
||||||
s, nl: string;
|
procedure ConvUsesUnits(AUsesNode: TCodeTreeNode; AUsesUnits: TStringList);
|
||||||
InsPos, i: Integer;
|
var
|
||||||
begin
|
i, ind: Integer;
|
||||||
Result:=false;
|
InsPos: Integer;
|
||||||
DelphiOnlyUnits:=TStringList.Create;
|
nl: string;
|
||||||
LclOnlyUnits:=TStringList.Create;
|
s: string;
|
||||||
try
|
RenameList: TStringList;
|
||||||
fCodeTool.BuildTree(true);
|
begin
|
||||||
fSrcCache.MainScanner:=fCodeTool.Scanner;
|
DelphiOnlyUnits.Clear;
|
||||||
UsesNode:=fCodeTool.FindMainUsesSection;
|
LCLOnlyUnits.Clear;
|
||||||
if UsesNode<>nil then begin
|
fCodeTool.MoveCursorToUsesStart(AUsesNode);
|
||||||
fCodeTool.MoveCursorToUsesStart(UsesNode);
|
|
||||||
InsPos:=fCodeTool.CurPos.StartPos;
|
InsPos:=fCodeTool.CurPos.StartPos;
|
||||||
// Don't remove the unit names but add to Delphi block instead.
|
// Don't remove the unit names but add to Delphi block instead.
|
||||||
for i:=0 to fUnitsToRemove.Count-1 do begin
|
for i:=0 to fUnitsToRemove.Count-1 do begin
|
||||||
s:=fUnitsToRemove[i];
|
s:=fUnitsToRemove[i];
|
||||||
RemoveUsesUnit(s);
|
if AUsesUnits.Find(s, ind) then begin // if RemoveUsesUnit(AUsesNode, s) then
|
||||||
DelphiOnlyUnits.Append(s);
|
fCodeTool.RemoveUnitFromUsesSection(AUsesNode, UpperCaseStr(s), fSrcCache);
|
||||||
|
DelphiOnlyUnits.Append(s);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
// ... and don't comment the unit names either.
|
// ... and don't comment the unit names either.
|
||||||
for i:=0 to fUnitsToComment.Count-1 do begin
|
for i:=0 to fUnitsToComment.Count-1 do begin
|
||||||
s:=fUnitsToComment[i];
|
s:=fUnitsToComment[i];
|
||||||
RemoveUsesUnit(s);
|
if AUsesUnits.Find(s, ind) then begin // if RemoveUsesUnit(AUsesNode, s) then
|
||||||
DelphiOnlyUnits.Append(s);
|
fCodeTool.RemoveUnitFromUsesSection(AUsesNode, UpperCaseStr(s), fSrcCache);
|
||||||
|
DelphiOnlyUnits.Append(s);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
RenameList:=TStringList.Create;
|
RenameList:=TStringList.Create;
|
||||||
try
|
try
|
||||||
@ -256,13 +267,17 @@ begin
|
|||||||
fUnitsToRename.GetNames(RenameList);
|
fUnitsToRename.GetNames(RenameList);
|
||||||
for i:=0 to RenameList.Count-1 do begin
|
for i:=0 to RenameList.Count-1 do begin
|
||||||
s:=RenameList[i];
|
s:=RenameList[i];
|
||||||
RemoveUsesUnit(s);
|
if AUsesUnits.Find(s, ind) then begin // if RemoveUsesUnit(AUsesNode, s) then begin
|
||||||
DelphiOnlyUnits.Append(s);
|
fCodeTool.RemoveUnitFromUsesSection(AUsesNode, UpperCaseStr(s), fSrcCache);
|
||||||
LclOnlyUnits.Append(fUnitsToRename[s]);
|
DelphiOnlyUnits.Append(s);
|
||||||
|
LCLOnlyUnits.Append(fUnitsToRename[s]);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
RenameList.Free;
|
RenameList.Free;
|
||||||
end;
|
end;
|
||||||
|
{ TODO : handling of one used unit in one line is not functional yet
|
||||||
|
ex: uses consts;}
|
||||||
if (LclOnlyUnits.Count>0) or (DelphiOnlyUnits.Count>0) then begin
|
if (LclOnlyUnits.Count>0) or (DelphiOnlyUnits.Count>0) then begin
|
||||||
// Add LCL and Delphi sections for output.
|
// Add LCL and Delphi sections for output.
|
||||||
nl:=fSrcCache.BeautifyCodeOptions.LineEnd;
|
nl:=fSrcCache.BeautifyCodeOptions.LineEnd;
|
||||||
@ -277,7 +292,23 @@ begin
|
|||||||
if not fSrcCache.Replace(gtEmptyLine,gtNewLine,InsPos,InsPos,s) then exit;
|
if not fSrcCache.Replace(gtEmptyLine,gtNewLine,InsPos,InsPos,s) then exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
|
||||||
|
begin
|
||||||
|
Result:=false;
|
||||||
|
DelphiOnlyUnits:=TStringList.Create;
|
||||||
|
LclOnlyUnits:=TStringList.Create;
|
||||||
|
try
|
||||||
|
fCodeTool.BuildTree(false);
|
||||||
|
fSrcCache.MainScanner:=fCodeTool.Scanner;
|
||||||
|
// Main uses section
|
||||||
|
MainUsesNode:=fCodeTool.FindMainUsesSection;
|
||||||
|
if MainUsesNode<>nil then
|
||||||
|
ConvUsesUnits(MainUsesNode, fExistingUsesMain);
|
||||||
|
// Implementation uses section
|
||||||
|
ImplementationUsesNode:=fCodeTool.FindImplementationUsesSection;
|
||||||
|
if ImplementationUsesNode<>nil then
|
||||||
|
ConvUsesUnits(ImplementationUsesNode, fExistingUsesImplementation);
|
||||||
|
Result:=true;
|
||||||
finally
|
finally
|
||||||
LclOnlyUnits.Free;
|
LclOnlyUnits.Free;
|
||||||
DelphiOnlyUnits.Free;
|
DelphiOnlyUnits.Free;
|
||||||
@ -428,23 +459,6 @@ begin
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TConvDelphiCodeTool.UsesSectionsToUnitnames: TStringList;
|
|
||||||
// Collect all unit names from uses sections to a StringList.
|
|
||||||
var
|
|
||||||
UsesNode: TCodeTreeNode;
|
|
||||||
ImplList: TStrings;
|
|
||||||
begin
|
|
||||||
fCodeTool.BuildTree(true);
|
|
||||||
fSrcCache.MainScanner:=fCodeTool.Scanner;
|
|
||||||
UsesNode:=fCodeTool.FindMainUsesSection;
|
|
||||||
Result:=TStringList(fCodeTool.UsesSectionToUnitnames(UsesNode));
|
|
||||||
UsesNode:=fCodeTool.FindImplementationUsesSection;
|
|
||||||
ImplList:=fCodeTool.UsesSectionToUnitnames(UsesNode);
|
|
||||||
Result.AddStrings(ImplList);
|
|
||||||
ImplList.Free;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function TConvDelphiCodeTool.FixMainClassAncestor(const AClassName: string;
|
function TConvDelphiCodeTool.FixMainClassAncestor(const AClassName: string;
|
||||||
AReplaceTypes: TStringToStringTree): boolean;
|
AReplaceTypes: TStringToStringTree): boolean;
|
||||||
// Replace the ancestor type of main form with a fall-back type if needed.
|
// Replace the ancestor type of main form with a fall-back type if needed.
|
||||||
|
|||||||
@ -754,14 +754,16 @@ end;
|
|||||||
|
|
||||||
function TConvertDelphiUnit.FixMissingUnits: TModalResult;
|
function TConvertDelphiUnit.FixMissingUnits: TModalResult;
|
||||||
var
|
var
|
||||||
UnitNames: TStringList;
|
ConvTool: TConvDelphiCodeTool;
|
||||||
|
|
||||||
procedure RenameOrRemoveUnit(AOldName, ANewName: string);
|
procedure RenameOrRemoveUnit(AOldName, ANewName: string);
|
||||||
// Replace a unit name with a new name or remove it if there is no new name.
|
// Replace a unit name with a new name or remove it if there is no new name.
|
||||||
var
|
var
|
||||||
x: Integer;
|
x: Integer;
|
||||||
begin
|
begin
|
||||||
if (ANewName<>'') and not UnitNames.Find(ANewName, x) then begin
|
if (ANewName<>'')
|
||||||
|
and (not ConvTool.ExistingUsesMain.Find(ANewName, x))
|
||||||
|
and (not ConvTool.ExistingUsesImplementation.Find(ANewName, x)) then begin
|
||||||
fUnitsToRename[AOldName]:=ANewName;
|
fUnitsToRename[AOldName]:=ANewName;
|
||||||
IDEMessagesWindow.AddMsg(Format(
|
IDEMessagesWindow.AddMsg(Format(
|
||||||
'Replaced unit "%s" with "%s" in uses section.',[AOldName, ANewName]),'',-1);
|
'Replaced unit "%s" with "%s" in uses section.',[AOldName, ANewName]),'',-1);
|
||||||
@ -802,7 +804,6 @@ var
|
|||||||
MapToEdit: TStringToStringTree;
|
MapToEdit: TStringToStringTree;
|
||||||
Node: TAVLTreeNode;
|
Node: TAVLTreeNode;
|
||||||
Item: PStringToStringTreeItem;
|
Item: PStringToStringTreeItem;
|
||||||
ConvTool: TConvDelphiCodeTool;
|
|
||||||
i: Integer;
|
i: Integer;
|
||||||
UnitN, s: string;
|
UnitN, s: string;
|
||||||
begin
|
begin
|
||||||
@ -811,15 +812,11 @@ begin
|
|||||||
ConvTool:=TConvDelphiCodeTool.Create(fPascalBuffer);
|
ConvTool:=TConvDelphiCodeTool.Create(fPascalBuffer);
|
||||||
if fSettings.UnitsReplaceMode=rlInteractive then
|
if fSettings.UnitsReplaceMode=rlInteractive then
|
||||||
MapToEdit:=TStringToStringTree.Create(false);
|
MapToEdit:=TStringToStringTree.Create(false);
|
||||||
UnitNames:=nil; // Will be created in ConvTool.UsesSectionsToUnitnames.
|
|
||||||
fMissingUnits:=nil; // Will be created in CodeToolBoss.FindMissingUnits.
|
fMissingUnits:=nil; // Will be created in CodeToolBoss.FindMissingUnits.
|
||||||
try
|
try
|
||||||
Result:=GetMissingUnits;
|
Result:=GetMissingUnits;
|
||||||
if (Result<>mrOK) or (fMissingUnits=nil) or (fMissingUnits.Count=0) then exit;
|
if (Result<>mrOK) or (fMissingUnits=nil) or (fMissingUnits.Count=0) then exit;
|
||||||
|
|
||||||
// Collect all unit names from uses sections.
|
|
||||||
UnitNames:=ConvTool.UsesSectionsToUnitnames;
|
|
||||||
UnitNames.Sorted:=true;
|
|
||||||
// Find replacements for missing units from settings.
|
// Find replacements for missing units from settings.
|
||||||
for i:=fMissingUnits.Count-1 downto 0 do begin
|
for i:=fMissingUnits.Count-1 downto 0 do begin
|
||||||
UnitN:=fMissingUnits[i];
|
UnitN:=fMissingUnits[i];
|
||||||
@ -874,7 +871,6 @@ begin
|
|||||||
if fSettings.UnitsReplaceMode=rlInteractive then
|
if fSettings.UnitsReplaceMode=rlInteractive then
|
||||||
MapToEdit.Free;
|
MapToEdit.Free;
|
||||||
fMissingUnits.Free;
|
fMissingUnits.Free;
|
||||||
UnitNames.Free;
|
|
||||||
ConvTool.Free;
|
ConvTool.Free;
|
||||||
UnitUpdater.Free;
|
UnitUpdater.Free;
|
||||||
end;
|
end;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user