From d48eb4b364e83a788e2f6839f66d4aa213d6dbbb Mon Sep 17 00:00:00 2001 From: mattias Date: Wed, 8 Aug 2007 18:22:43 +0000 Subject: [PATCH] codetools: implemented function to convert simple functions to constants, h2pas: new tools to reduce IFDEFs and fucntions to constant conversion git-svn-id: trunk@11761 - --- components/codetools/codecompletiontool.pas | 252 ++++++++++-- components/codetools/codetoolmanager.pas | 52 ++- components/codetools/directivestree.pas | 1 + .../examples/scanexamples/uglyifdefs.pas | 1 + components/codetools/keywordfunclists.pas | 52 +-- components/h2pas/h2pasconvert.pas | 91 ++++- components/h2pas/h2pasdlg.lfm | 85 ++-- components/h2pas/h2pasdlg.lrs | 382 +++++++++--------- components/h2pas/h2pasdlg.pas | 16 +- ideintf/idetextconverter.pas | 1 + lcl/dbgrids.pas | 1 - lcl/include/wincontrol.inc | 2 +- 12 files changed, 644 insertions(+), 292 deletions(-) diff --git a/components/codetools/codecompletiontool.pas b/components/codetools/codecompletiontool.pas index a0b280a369..3aac283a3b 100644 --- a/components/codetools/codecompletiontool.pas +++ b/components/codetools/codecompletiontool.pas @@ -198,6 +198,8 @@ type function FixAliasDefinitions(TreeOfCodeTreeNodeExt: TAVLTree; SourceChangeCache: TSourceChangeCache): boolean; function FindConstFunctions(out TreeOfCodeTreeNodeExt: TAVLTree): boolean; + function ReplaceConstFunctions(TreeOfCodeTreeNodeExt: TAVLTree; + SourceChangeCache: TSourceChangeCache): boolean; // custom class completion function InitClassCompletion(const UpperClassName: string; @@ -1217,7 +1219,8 @@ var begin Result:=false; if SourceChangeCache=nil then exit; - if (TreeOfCodeTreeNodeExt=nil) or (TreeOfCodeTreeNodeExt.Count=0) then exit; + if (TreeOfCodeTreeNodeExt=nil) or (TreeOfCodeTreeNodeExt.Count=0) then + exit(true); SourceChangeCache.MainScanner:=Scanner; NodesToDo:=TAVLTree.Create; @@ -1313,6 +1316,7 @@ end; function TCodeCompletionCodeTool.FindAliasDefinitions(out TreeOfCodeTreeNodeExt: TAVLTree; OnlyWrongType: boolean): boolean; +// finds all public definitions of the form 'const A = B;' var NodeExt: TCodeTreeNodeExtension; AllNodes: TAVLTree; @@ -1410,12 +1414,12 @@ function TCodeCompletionCodeTool.FixAliasDefinitions( ): boolean; begin Result:=false; - + raise Exception.Create('TCodeCompletionCodeTool.FixAliasDefinitions not implemented yet'); end; function TCodeCompletionCodeTool.FindConstFunctions( out TreeOfCodeTreeNodeExt: TAVLTree): boolean; -{ find dummy functions that can be replaced with a constant +{ find public dummy functions that can be replaced with a constant For example: function MPI_CONVERSION_FN_NULL : PMPI_Datarep_conversion_function; @@ -1423,16 +1427,89 @@ function TCodeCompletionCodeTool.FindConstFunctions( MPI_CONVERSION_FN_NULL:=PMPI_Datarep_conversion_function(0); end; - Where the expression only contains unit wide defined types, constants, - variables, built-in functions and no members nor functions. + Where the expression only contains unit defined types, constants, + variables, built-in const functions and no members nor functions. + + NodeExt.Txt: description + NodeExt.Node: definition node + NodeExt.Data: function body node + NodeExt.ExtTxt1: ExtractCode(ExprStart,ExprEnd,[]); } +var + Definitions: TAVLTree; procedure CheckProcNode(ProcNode: TCodeTreeNode); + // check if node is a function (not class function) var Node: TCodeTreeNode; + FuncName: String; + ExprStart: LongInt; + NodeText: String; + NodeExt: TCodeTreeNodeExtension; + ExprEnd: LongInt; + ResultNodeExt: TCodeTreeNodeExtension; + + function CheckExprIdentifier(const Identifier: string): boolean; + var + NodeExt: TCodeTreeNodeExtension; + begin + Result:=true; + if CompareIdentifiers('Result',PChar(Identifier))=0 then exit; + if CompareIdentifiers('FuncName',PChar(Identifier))=0 then exit; + // check for const and type definitions + NodeExt:=FindCodeTreeNodeExt(Definitions,Identifier); + if (NodeExt<>nil) and (NodeExt.Node<>nil) then begin + if NodeExt.Node.Desc in [ctnConstDefinition,ctnTypeDefinition] then + exit; + end; + // check for compiler built in operators, constants and types + if IsWordBuiltInFunc.DoIt(Identifier) then exit; + if WordIsBinaryOperator.DoIt(Identifier) then exit; + if WordIsPredefinedFPCIdentifier.DoIt(Identifier) then exit; + Result:=false; + end; + begin - if not NodeIsFunction(ProcNode) then exit; - if ProcNodeHasParamList(ProcNode) then exit; + if (ProcNode=nil) or (ProcNode.Desc<>ctnProcedure) then exit; + DebugLn(['CheckProcNode START ',ExtractProcHead(ProcNode,[])]); + MoveCursorToNodeStart(ProcNode); + // read 'function' + ReadNextAtom; + if not UpAtomIs('FUNCTION') then exit; + // read name + ReadNextAtom; + FuncName:=GetAtom; + ReadNextAtom; + if CurPos.Flag=cafRoundBracketOpen then begin + // skip empty parameter list () + ReadNextAtom; + if CurPos.Flag<>cafRoundBracketClose then exit; + ReadNextAtom; + end; + // read : + if CurPos.Flag<>cafColon then exit; + // read result type + ReadNextAtom; + if not AtomIsIdentifier(false) then exit; + + // check if there is a public definition of the procedure + NodeText:=GetRedefinitionNodeText(ProcNode); + if TreeOfCodeTreeNodeExt<>nil then begin + ResultNodeExt:=FindCodeTreeNodeExt(TreeOfCodeTreeNodeExt,NodeText); + if ResultNodeExt<>nil then begin + DebugLn(['CheckProcNode function exists twice']); + exit; + end; + end; + + NodeExt:=FindCodeTreeNodeExt(Definitions,NodeText); + if (NodeExt=nil) or (NodeExt.Node=nil) or (NodeExt.Node.Desc<>ctnProcedure) + then begin + DebugLn(['CheckProcNode function is not public NodeText=',NodeText]); + exit; + end; + + // check child nodes only contain the proc head and a begin block Node:=ProcNode.FirstChild; if Node=nil then exit; if Node.Desc=ctnProcedureHead then begin @@ -1440,44 +1517,83 @@ function TCodeCompletionCodeTool.FindConstFunctions( if Node=nil then exit; end; if Node.Desc<>ctnBeginBlock then exit; + + DebugLn(['CheckProcNode has begin block']); + + // check begin block is only a single assignment MoveCursorToNodeStart(Node); - repeat + // read begin + ReadNextAtom; + // read 'Result' or 'FunctionName' + ReadNextAtom; + if (not UpAtomIs('RESULT')) and (not AtomIs(FuncName)) then exit; + // read := + ReadNextAtom; + if not UpAtomIs(':=') then exit; + // read expression + ReadNextAtom; + ExprStart:=CurPos.StartPos; + ExprEnd:=ExprStart; + while (CurPos.EndPos<=Node.EndPos) do begin + if (CurPos.Flag in [cafSemicolon,cafEnd]) then + break; + // check if all identifiers can be used in a constant expression + if AtomIsIdentifier(false) and not CheckExprIdentifier(GetAtom) then + exit; + ExprEnd:=CurPos.EndPos; ReadNextAtom; - // ToDo: check identifier - if CurPos.EndPos>Node.EndPos then break; - until false; + end; + if ExprStart=ExprEnd then exit; + + DebugLn(['CheckProcNode FOUND']); + + // save values + ResultNodeExt:=NodeExtMemManager.NewNode; + ResultNodeExt.Txt:=NodeText; + ResultNodeExt.Node:=NodeExt.Node; + ResultNodeExt.Data:=ProcNode; + ResultNodeExt.ExtTxt1:=ExtractCode(ExprStart,ExprEnd,[]); + if TreeOfCodeTreeNodeExt=nil then + TreeOfCodeTreeNodeExt:=TAVLTree.Create(@CompareCodeTreeNodeExt); + TreeOfCodeTreeNodeExt.Add(ResultNodeExt); + end; + + procedure AddDefinition(Node: TCodeTreeNode); + var + NodeExt: TCodeTreeNodeExtension; + NodeText: String; + begin + NodeText:=GetRedefinitionNodeText(Node); + NodeExt:=FindCodeTreeNodeExt(Definitions,NodeText); + if NodeExt=nil then begin + NodeExt:=NodeExtMemManager.NewNode; + NodeExt.Txt:=NodeText; + Definitions.Add(NodeExt); + end; + NodeExt.Node:=Node; end; var Node: TCodeTreeNode; - Definitions: TAVLTree; - NodeText: String; - NodeExt: TCodeTreeNodeExtension; begin Result:=false; TreeOfCodeTreeNodeExt:=nil; BuildTree(false); if not EndOfSourceFound then exit; - // first step: find all global identifiers + // first step: find all unit identifiers (excluding implementation section) Definitions:=TAVLTree.Create(@CompareCodeTreeNodeExt); try Node:=Tree.Root; while Node<>nil do begin case Node.Desc of - ctnProcedureHead, ctnProperty, ctnParameterList: + ctnProcedureHead, ctnProperty, ctnParameterList, ctnImplementation: Node:=Node.NextSkipChilds; ctnVarDefinition,ctnConstDefinition,ctnTypeDefinition,ctnEnumIdentifier: begin // add or update definition - NodeText:=ExtractDefinitionName(Node); - NodeExt:=FindCodeTreeNodeExt(Definitions,NodeText); - if NodeExt=nil then begin - NodeExt:=NodeExtMemManager.NewNode; - NodeExt.Txt:=NodeText; - end; - NodeExt.Node:=Node; - + AddDefinition(Node); + if (Node.Desc=ctnTypeDefinition) and (Node.FirstChild<>nil) and (Node.FirstChild.Desc=ctnEnumerationType) then @@ -1485,6 +1601,11 @@ begin else Node:=Node.Next; end; + ctnProcedure: + begin + AddDefinition(Node); + Node:=Node.NextSkipChilds; + end; else Node:=Node.Next; end; @@ -1500,7 +1621,7 @@ begin ctnProcedure: begin CheckProcNode(Node); - Node:=Node.Next; + Node:=Node.NextSkipChilds; end; else Node:=Node.Next; @@ -1511,6 +1632,87 @@ begin Definitions.FreeAndClear; Definitions.Free; end; + Result:=true; +end; + +function TCodeCompletionCodeTool.ReplaceConstFunctions( + TreeOfCodeTreeNodeExt: TAVLTree; SourceChangeCache: TSourceChangeCache + ): boolean; +{ replaces public dummy functions with a constant. + The function body will be removed. + See the function FindConstFunctions. +} + function IsConstSectionNeeded(Node: TCodeTreeNode): boolean; + var + AVLNode: TAVLTreeNode; + NodeExt: TCodeTreeNodeExtension; + begin + if Node.PriorBrother.Desc=ctnConstSection then exit(false); + AVLNode:=TreeOfCodeTreeNodeExt.FindLowest; + while AVLNode<>nil do begin + NodeExt:=TCodeTreeNodeExtension(AVLNode.Data); + if NodeExt.Node=Node.PriorBrother then begin + // the function in front will be replaced too + exit(false); + end; + AVLNode:=TreeOfCodeTreeNodeExt.FindSuccessor(AVLNode); + end; + Result:=true; + end; + +var + AVLNode: TAVLTreeNode; + NodeExt: TCodeTreeNodeExtension; + DefNode: TCodeTreeNode; + BodyNode: TCodeTreeNode; + Expr: String; + FromPos: LongInt; + ToPos: LongInt; + NewSrc: String; +begin + Result:=false; + if SourceChangeCache=nil then exit; + if (TreeOfCodeTreeNodeExt=nil) or (TreeOfCodeTreeNodeExt.Count=0) then + exit(true); + SourceChangeCache.MainScanner:=Scanner; + + AVLNode:=TreeOfCodeTreeNodeExt.FindLowest; + while AVLNode<>nil do begin + NodeExt:=TCodeTreeNodeExtension(AVLNode.Data); + DebugLn(['TCodeCompletionCodeTool.ReplaceConstFunctions ',NodeExt.Txt]); + DefNode:=NodeExt.Node; + BodyNode:=TCodeTreeNode(NodeExt.Data); + Expr:=NodeExt.ExtTxt1; + DebugLn(['TCodeCompletionCodeTool.ReplaceConstFunctions Expr=',Expr]); + + // remove body node + FromPos:=FindLineEndOrCodeInFrontOfPosition(BodyNode.StartPos); + ToPos:=FindLineEndOrCodeAfterPosition(BodyNode.EndPos); + if (ToPos<=SrcLen) and (Src[ToPos] in [#10,#13]) then begin + inc(ToPos); + if (ToPos<=SrcLen) and (Src[ToPos] in [#10,#13]) + and (Src[ToPos-1]<>Src[ToPos]) then + inc(ToPos); + end; + DebugLn(['TCodeCompletionCodeTool.ReplaceConstFunctions Body="',copy(Src,FromPos,ToPos-FromPos),'"']); + SourceChangeCache.Replace(gtNone,gtNone,FromPos,ToPos,''); + + // replace definition + FromPos:=DefNode.StartPos; + ToPos:=DefNode.EndPos; + if Src[ToPos]=';' then inc(ToPos);// add semicolon + NewSrc:=GetIndentStr(SourceChangeCache.BeautifyCodeOptions.Indent) + +ExtractProcName(DefNode,[])+' = '+Expr+';'; + SourceChangeCache.Replace(gtNone,gtNone,FromPos,ToPos,NewSrc); + // add 'const' keyword + if IsConstSectionNeeded(DefNode) then begin + FromPos:=FindLineEndOrCodeInFrontOfPosition(DefNode.StartPos); + SourceChangeCache.Replace(gtEmptyLine,gtNewLine,FromPos,FromPos,'const'); + end; + + AVLNode:=TreeOfCodeTreeNodeExt.FindSuccessor(AVLNode); + end; + Result:=SourceChangeCache.Apply; end; function TCodeCompletionCodeTool.InitClassCompletion( diff --git a/components/codetools/codetoolmanager.pas b/components/codetools/codetoolmanager.pas index 90c5938122..0fb797f9a2 100644 --- a/components/codetools/codetoolmanager.pas +++ b/components/codetools/codetoolmanager.pas @@ -419,7 +419,10 @@ type function FixAllAliasDefinitions(Code: TCodeBuffer): boolean; function FindConstFunctions(Code: TCodeBuffer; out TreeOfCodeTreeNodeExt: TAVLTree): boolean; - + function ReplaceConstFunctions(Code: TCodeBuffer; + TreeOfCodeTreeNodeExt: TAVLTree): boolean; + function ReplaceAllConstFunctions(Code: TCodeBuffer): boolean; + // custom class completion function InitClassCompletion(Code: TCodeBuffer; const UpperClassName: string; out CodeTool: TCodeTool): boolean; @@ -2849,6 +2852,53 @@ begin end; end; +function TCodeToolManager.ReplaceConstFunctions(Code: TCodeBuffer; + TreeOfCodeTreeNodeExt: TAVLTree): boolean; +begin + {$IFDEF CTDEBUG} + DebugLn('TCodeToolManager.ReplaceConstFunctions A ',Code.Filename); + {$ENDIF} + Result:=false; + if not InitCurCodeTool(Code) then exit; + try + Result:=FCurCodeTool.ReplaceConstFunctions(TreeOfCodeTreeNodeExt, + SourceChangeCache); + except + on e: Exception do Result:=HandleException(e); + end; +end; + +function TCodeToolManager.ReplaceAllConstFunctions(Code: TCodeBuffer): boolean; +var + TreeOfCodeTreeNodeExt: TAVLTree; +begin + {$IFDEF CTDEBUG} + DebugLn('TCodeToolManager.ReplaceAllConstFunctions A ',Code.Filename); + {$ENDIF} + Result:=false; + if not InitCurCodeTool(Code) then exit; + try + repeat + TreeOfCodeTreeNodeExt:=nil; + try + Result:=FCurCodeTool.FindConstFunctions(TreeOfCodeTreeNodeExt); + if (not Result) or (TreeOfCodeTreeNodeExt=nil) + or (TreeOfCodeTreeNodeExt.Count=0) then + break; + Result:=FCurCodeTool.ReplaceConstFunctions(TreeOfCodeTreeNodeExt, + SourceChangeCache); + finally + if TreeOfCodeTreeNodeExt<>nil then begin + TreeOfCodeTreeNodeExt.FreeAndClear; + TreeOfCodeTreeNodeExt.Free; + end; + end; + until not Result; + except + on e: Exception do Result:=HandleException(e); + end; +end; + function TCodeToolManager.InitClassCompletion(Code: TCodeBuffer; const UpperClassName: string; out CodeTool: TCodeTool): boolean; begin diff --git a/components/codetools/directivestree.pas b/components/codetools/directivestree.pas index 7d54943cfb..c2f62492ef 100644 --- a/components/codetools/directivestree.pas +++ b/components/codetools/directivestree.pas @@ -910,6 +910,7 @@ procedure TCompilerDirectivesTree.ReduceCompilerDirectives(var Changed: boolean) DisableDefineNode(MacroNode.LastDefineNode,Changed); end; + MacroNode.LastReadNode:=nil; MacroNode.LastDefineNode:=Node; end; diff --git a/components/codetools/examples/scanexamples/uglyifdefs.pas b/components/codetools/examples/scanexamples/uglyifdefs.pas index c0d8d2b535..0d18eeaf53 100644 --- a/components/codetools/examples/scanexamples/uglyifdefs.pas +++ b/components/codetools/examples/scanexamples/uglyifdefs.pas @@ -18,6 +18,7 @@ uses {$define HAVE_MPI_OFFSET} {$if !defined(MPI_BUILD_PROFILING)} +var c: char; {$ENDIF} {$define HAVE_MPI_GREQUEST} diff --git a/components/codetools/keywordfunclists.pas b/components/codetools/keywordfunclists.pas index 4fde06f9ea..e00054bf4b 100644 --- a/components/codetools/keywordfunclists.pas +++ b/components/codetools/keywordfunclists.pas @@ -924,29 +924,32 @@ begin IsWordBuiltInFunc:=TKeyWordFunctionList.Create; KeyWordLists.Add(IsWordBuiltInFunc); with IsWordBuiltInFunc do begin - Add('LOW',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('HIGH',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('LO',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('HI',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('ORD',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('PREC',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('SUCC',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('LENGTH',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('SETLENGTH',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('INC',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('DEC',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('INITIALIZE',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('FINALIZE',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('COPY',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('SIZEOF',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('WRITE',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('WRITELN',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('READ',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('READLN',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('TYPEOF',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('ASSIGNED',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('INCLUDE',{$ifdef FPC}@{$endif}AllwaysTrue); - Add('EXCLUDE',{$ifdef FPC}@{$endif}AllwaysTrue); + Add('LOW' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('HIGH' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('LO' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('HI' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('ORD' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('PREC' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('SUCC' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('LENGTH' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('SETLENGTH' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('INC' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('DEC' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('INITIALIZE' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('FINALIZE' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('COPY' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('SIZEOF' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('WRITE' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('WRITELN' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('READ' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('READLN' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('TYPEOF' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('ASSIGNED' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('INCLUDE' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('EXCLUDE' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('EXIT' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('BREAK' ,{$ifdef FPC}@{$endif}AllwaysTrue); + Add('CONTINUE' ,{$ifdef FPC}@{$endif}AllwaysTrue); end; WordIsTermOperator:=TKeyWordFunctionList.Create; @@ -1308,9 +1311,6 @@ begin Add('TRUE' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('WIDECHAR' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('WIDESTRING' ,{$ifdef FPC}@{$endif}AllwaysTrue); - Add('EXIT' ,{$ifdef FPC}@{$endif}AllwaysTrue); - Add('BREAK' ,{$ifdef FPC}@{$endif}AllwaysTrue); - Add('CONTINUE' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('LONGWORD' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('WORD' ,{$ifdef FPC}@{$endif}AllwaysTrue); Add('LONGINT' ,{$ifdef FPC}@{$endif}AllwaysTrue); diff --git a/components/h2pas/h2pasconvert.pas b/components/h2pas/h2pasconvert.pas index ddb127d34b..bb55e11af3 100644 --- a/components/h2pas/h2pasconvert.pas +++ b/components/h2pas/h2pasconvert.pas @@ -26,7 +26,7 @@ uses Classes, SysUtils, LCLProc, LResources, LazConfigStorage, XMLPropStorage, Forms, Controls, Dialogs, FileUtil, FileProcs, AvgLvlTree, // CodeTools - KeywordFuncLists, BasicCodeTools, CodeCache, CodeToolManager, + KeywordFuncLists, BasicCodeTools, CodeCache, DirectivesTree, CodeToolManager, // IDEIntf TextTools, IDEExternToolIntf, IDEDialogs, LazIDEIntf, SrcEditorIntf, IDEMsgIntf, IDETextConverter; @@ -185,9 +185,23 @@ type function Execute(aText: TIDETextConverter): TModalResult; override; end; + { TReduceCompilerDirectivesInUnit } + + TReduceCompilerDirectivesInUnit = class(TCustomTextConverterTool) + public + class function ClassDescription: string; override; + function Execute(aText: TIDETextConverter): TModalResult; override; + end; + + { TReplaceConstFunctionsInUnit } + + TReplaceConstFunctionsInUnit = class(TCustomTextConverterTool) + public + class function ClassDescription: string; override; + function Execute(aText: TIDETextConverter): TModalResult; override; + end; { Proposal: - - A tool to remove redefinitions - A tool to fix "constant A=B;" to type A=B; or functions - A tool to reorder a unit to fix forward definitions Difficulties: @@ -1368,7 +1382,7 @@ var i: Integer; begin for i:=0 to CHeaderFileCount-1 do - if CHeaderFiles[i].Enabled then exit(true); + if CHeaderFiles[i].Enabled and (not CHeaderFiles[i].Merge) then exit(true); Result:=false; end; @@ -1386,11 +1400,13 @@ begin AddNewTextConverterTool(FPostH2PasTools,TRemoveSystemTypes); AddNewTextConverterTool(FPostH2PasTools,TRemoveRedefinedPointerTypes); AddNewTextConverterTool(FPostH2PasTools,TRemoveEmptyTypeVarConstSections); + AddNewTextConverterTool(FPostH2PasTools,TReduceCompilerDirectivesInUnit); AddNewTextConverterTool(FPostH2PasTools,TReplaceImplicitTypes); AddNewTextConverterTool(FPostH2PasTools,TFixArrayOfParameterType); // the above tools fixed the syntax // now improve the declarations AddNewTextConverterTool(FPostH2PasTools,TRemoveRedefinitionsInUnit); + AddNewTextConverterTool(FPostH2PasTools,TReplaceConstFunctionsInUnit); end; function TH2PasProject.SearchIncludedCHeaderFile(aFile: TH2PasFile; @@ -2213,7 +2229,7 @@ function TRemoveRedefinedPointerTypes.Execute(aText: TIDETextConverter ): TModalResult; { search for Pname = ^name; - if PName has a redefinition, delete the first one + if PName has a redefinition, delete the second one } var Lines: TStrings; @@ -2234,12 +2250,11 @@ begin PointerName:=REVar(1); TypeName:=REVar(2); Pattern:='^\s*'+PointerName+'\s*=\s*\^\s*'+TypeName+'\s*;'; - j:=i+1; - while (ji) do begin + if REMatches(Lines[j],Pattern) then + Lines.Delete(j); dec(j); - if j