From e1a6a2e960795bab9b51251ab5026f7487f140be Mon Sep 17 00:00:00 2001 From: juha Date: Fri, 5 Nov 2010 16:38:12 +0000 Subject: [PATCH] Converter: Treat main and implementation uses sections separately. Patch from Stephano, issue #0017578. git-svn-id: trunk@28099 - --- converter/convcodetool.pas | 121 ++++++++++++++++++++++++++++--------- 1 file changed, 93 insertions(+), 28 deletions(-) diff --git a/converter/convcodetool.pas b/converter/convcodetool.pas index ccd477c04d..086c877682 100644 --- a/converter/convcodetool.pas +++ b/converter/convcodetool.pas @@ -46,6 +46,8 @@ uses type + TUsesSection=(usMain, usImplementation); + { TConvDelphiCodeTool } TConvDelphiCodeTool = class @@ -74,6 +76,8 @@ type function AddDelphiAndLCLSections: boolean; function AddModeDelphiDirective: boolean; + procedure ConvAddDelphiAndLCLUnitsToUsesSection(AUsesSection: TUsesSection; + DelphiOnlyUnits, LCLOnlyUnits: TStringList); function RenameResourceDirectives: boolean; function CommentOutUnits: boolean; function ReplaceFuncsInSource: boolean; @@ -229,6 +233,81 @@ begin end; end; +procedure TConvDelphiCodeTool.ConvAddDelphiAndLCLUnitsToUsesSection( + AUsesSection: TUsesSection; DelphiOnlyUnits, LCLOnlyUnits: TStringList); +var + AUsesNode: TCodeTreeNode; + i: Integer; + InsPos: Integer; + nl: string; + s: string; + DelphiOnlyUnitsStr, LclOnlyUnitsStr: string; +begin + if (LclOnlyUnits.Count=0) and (DelphiOnlyUnits.Count=0) then + exit; + DelphiOnlyUnitsStr:=''; + for i:=0 to DelphiOnlyUnits.Count-1 do begin + if inil then begin + //uses section exists + s:='{$IFNDEF FPC}'+nl; + if DelphiOnlyUnits.Count>=1 then + s:=s+' '+DelphiOnlyUnitsStr+','+nl; + s:=s+'{$ELSE}'+nl; + if LclOnlyUnits.Count>=1 then + s:=s+' '+LclOnlyUnitsStr+','+nl; + s:=s+'{$ENDIF}'+nl; + s:=s+' '; + //TODO: check for special units + fCodeTool.MoveCursorToUsesStart(AUsesNode); + InsPos:=fCodeTool.CurPos.StartPos; + end + else begin + //uses section does not exist + s:=nl; + s:=s+'{$IFNDEF FPC}'+nl; + if DelphiOnlyUnits.Count>=1 then begin + s:=s+'uses'+nl; + s:=s+' '+DelphiOnlyUnitsStr+';'+nl; + end; + s:=s+'{$ELSE}'+nl; + if LclOnlyUnits.Count>=1 then begin + s:=s+'uses'+nl; + s:=s+' '+LclOnlyUnitsStr+';'+nl; + end; + s:=s+'{$ENDIF}'; + case AUsesSection Of + usMain: AUsesNode:=fCodeTool.FindInterfaceNode; + usImplementation: AUsesNode:=fCodeTool.FindImplementationNode; + end; + // set insert position behind interface or implementation keyword + // TODO: what about program? + fCodeTool.MoveCursorToNodeStart(AUsesNode); + fCodeTool.ReadNextAtom; + InsPos:=fCodeTool.FindLineEndOrCodeAfterPosition(fCodeTool.CurPos.EndPos,false); + end; + // Now add the generated lines. + if not fSrcCache.Replace(gtNewLine,gtNone,InsPos,InsPos,s) 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. @@ -237,18 +316,23 @@ var LclOnlyUnits: TStringList; // LCL specific units. MainUsesNode, ImplementationUsesNode: TCodeTreeNode; - procedure ConvUsesUnits(AUsesNode: TCodeTreeNode; AUsesUnits: TStringList); + procedure ConvUsesUnits(AUsesSection: TUsesSection; AUsesUnits: TStringList); var i, ind: Integer; - InsPos: Integer; - nl: string; s: string; RenameList: TStringList; + AUsesNode: TCodeTreeNode; begin DelphiOnlyUnits.Clear; LCLOnlyUnits.Clear; - fCodeTool.MoveCursorToUsesStart(AUsesNode); - InsPos:=fCodeTool.CurPos.StartPos; + 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; // Don't remove the unit names but add to Delphi block instead. for i:=0 to fUnitsToRemove.Count-1 do begin s:=fUnitsToRemove[i]; @@ -280,21 +364,8 @@ var finally RenameList.Free; 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 - // Add LCL and Delphi sections for output. - nl:=fSrcCache.BeautifyCodeOptions.LineEnd; - s:='{$IFNDEF FPC}'+nl+' '; - for i:=0 to DelphiOnlyUnits.Count-1 do - s:=s+DelphiOnlyUnits[i]+', '; - s:=s+nl+'{$ELSE}'+nl+' '; - for i:=0 to LclOnlyUnits.Count-1 do - s:=s+LclOnlyUnits[i]+', '; - s:=s+nl+'{$ENDIF}'; - // Now add the generated lines. - if not fSrcCache.Replace(gtEmptyLine,gtNewLine,InsPos,InsPos,s) then exit; - end; + // Add LCL and Delphi sections for output. + ConvAddDelphiAndLCLUnitsToUsesSection(AUsesSection, DelphiOnlyUnits, LclOnlyUnits); end; begin @@ -302,16 +373,10 @@ begin 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); + ConvUsesUnits(usMain, fExistingUsesMain); // Implementation uses section - ImplementationUsesNode:=fCodeTool.FindImplementationUsesSection; - if ImplementationUsesNode<>nil then - ConvUsesUnits(ImplementationUsesNode, fExistingUsesImplementation); + ConvUsesUnits(usImplementation, fExistingUsesImplementation); Result:=true; finally LclOnlyUnits.Free;