From 20c335471a2ce0b761e0f947e87a82cf29a72f90 Mon Sep 17 00:00:00 2001 From: mattias Date: Thu, 5 May 2011 21:35:05 +0000 Subject: [PATCH] codetools: sort declaration changes git-svn-id: trunk@30561 - --- .../codetools/changedeclarationtool.pas | 265 ++++++++++++------ 1 file changed, 173 insertions(+), 92 deletions(-) diff --git a/components/codetools/changedeclarationtool.pas b/components/codetools/changedeclarationtool.pas index 04b7348c62..c076d0a8a7 100644 --- a/components/codetools/changedeclarationtool.pas +++ b/components/codetools/changedeclarationtool.pas @@ -40,8 +40,7 @@ type cplaInsertNewParam, // insert at Index a new parameter. Use DefaultValue in callers. cplaDeleteParam, // delete parameter at Index. In callers too. cplaMoveParam, // move parameter at OldIndex to Index - cplaMakeParamOptional, // add DefaultValue to parameter at Index. If callers use this value, remove it. - cplaMakeParamNonOptional // remove default value from parameter at Index. Use DefaultValue at callers. + cplaChangeDefaultValue // if caller use default change to old value, if caller use new value remove it ); TChangeParamListActions = set of TChangeParamListAction; @@ -55,23 +54,22 @@ type ParamModifier: string; ParamName: string; ParamType: string; - Value: string; + DefaultValue: string; constructor CreateInsertNewParam(TheIndex: integer; aModifier, aName, aType: string); constructor CreateDeleteParam(TheIndex: integer); constructor CreateMoveParam(TheOldIndex, NewIndex: integer); - constructor CreateMakeParamOptional(TheIndex: integer; aValue: string); - constructor CreateMakeParamNonOptional(TheIndex: integer; aValue: string); + constructor CreateChangeDefaultValue(TheIndex: integer; aValue: string); end; { TChangeDeclarationTool } TChangeDeclarationTool = class(TExtractProcTool) private - function ChangeProcParamListDeclaration(ProcNode: TCodeTreeNode; + function ChangeParamListDeclaration(ParentNode: TCodeTreeNode; Changes: TObjectList; // list of TChangeParamListItem SourceChanger: TSourceChangeCache): boolean; - function ChangeParamListDeclaration(CleanPos: integer; + function ChangeParamListDeclarationAtPos(CleanPos: integer; Changes: TObjectList; // list of TChangeParamListItem SourceChanger: TSourceChangeCache): boolean; public @@ -83,6 +81,117 @@ type implementation +type + + { TChangeParamTransactionInsert } + + TChangeParamTransactionInsert = class + public + Src: string; // if Src='' then use Modifier+Name+Typ + Modifier: string; + Name: string; + Typ: string; + Value: string; + MergeAllowed: boolean; + constructor Create(aSrc, aModifier, aName, aType, aValue: string; + aMergeAllowed: boolean = true); + end; + + { TChangeParamTransactionPos } + + TChangeParamTransactionPos = class + public + Node: TCodeTreeNode; // old param node + Delete: boolean; + NewDefaultValue: string; + InsertBehind: TObjectList;// list of TChangeParamTransactionInsert + constructor Create; + destructor Destroy; override; + end; + + { TChangeParamListTransactions } + + TChangeParamListTransactions = class + public + OldNodes: array of TChangeParamTransactionPos; // one for each old param node + InsertFirst: TObjectList;// list of TChangeParamTransactionInsert + Node: TCodeTreeNode; // ctnParameterList + constructor Create(ParamList: TCodeTreeNode); + destructor Destroy; override; + function MaxPos: integer; + procedure Insert(Index: integer; Insertion: TChangeParamTransactionInsert); + end; + +{ TChangeParamTransactionInsert } + +constructor TChangeParamTransactionInsert.Create(aSrc, aModifier, aName, aType, + aValue: string; aMergeAllowed: boolean); +begin + Src:=aSrc; + Modifier:=aModifier; + Name:=aName; + Typ:=aType; + Value:=aValue; + MergeAllowed:=aMergeAllowed; +end; + +constructor TChangeParamTransactionPos.Create; +begin + InsertBehind:=TObjectList.create(true); +end; + +destructor TChangeParamTransactionPos.Destroy; +begin + InsertBehind.Free; + inherited Destroy; +end; + +{ TChangeParamListInfos } + +function TChangeParamListTransactions.MaxPos: integer; +begin + Result:=length(OldNodes); +end; + +procedure TChangeParamListTransactions.Insert(Index: integer; + Insertion: TChangeParamTransactionInsert); +begin + if Index=0 then + InsertFirst.Add(Insertion) + else + OldNodes[Index-1].InsertBehind.Add(Insertion); +end; + +constructor TChangeParamListTransactions.Create(ParamList: TCodeTreeNode); +var + ParamNode: TCodeTreeNode; + i: Integer; +begin + InsertFirst:=TObjectList.create(true); + Node:=ParamList; + if Node<>nil then begin + SetLength(OldNodes,Node.ChildCount); + ParamNode:=Node.FirstChild; + i:=0; + while ParamNode<>nil do begin + OldNodes[i]:=TChangeParamTransactionPos.Create; + OldNodes[i].Node:=ParamNode; + ParamNode:=ParamNode.NextBrother; + end; + end; +end; + +destructor TChangeParamListTransactions.Destroy; +var + i: Integer; +begin + for i:=0 to length(OldNodes)-1 do + FreeAndNil(OldNodes[i]); + SetLength(OldNodes,0); + InsertFirst.Free; + inherited Destroy; +end; + { TChangeParamListItem } constructor TChangeParamListItem.CreateInsertNewParam(TheIndex: integer; @@ -108,106 +217,82 @@ begin OldIndex:=TheOldIndex; end; -constructor TChangeParamListItem.CreateMakeParamOptional(TheIndex: integer; +constructor TChangeParamListItem.CreateChangeDefaultValue(TheIndex: integer; aValue: string); begin - Action:=cplaMakeParamOptional; + Action:=cplaChangeDefaultValue; Index:=TheIndex; - Value:=aValue; -end; - -constructor TChangeParamListItem.CreateMakeParamNonOptional(TheIndex: integer; - aValue: string); -begin - Action:=cplaMakeParamNonOptional; - Index:=TheIndex; - Value:=aValue; + DefaultValue:=aValue; end; { TChangeDeclarationTool } -function TChangeDeclarationTool.ChangeProcParamListDeclaration( - ProcNode: TCodeTreeNode; Changes: TObjectList; +function TChangeDeclarationTool.ChangeParamListDeclaration( + ParentNode: TCodeTreeNode; Changes: TObjectList; SourceChanger: TSourceChangeCache): boolean; var - HeadNode: TCodeTreeNode; ParamListNode: TCodeTreeNode; i: Integer; Change: TChangeParamListItem; - NewCode: String; - InsertPos: LongInt; - ParamNode: TCodeTreeNode; - j: Integer; + Transactions: TChangeParamListTransactions; begin Result:=false; - HeadNode:=ProcNode.FirstChild; - if NodeNeedsBuildSubTree(HeadNode) then - BuildSubTreeForProcHead(HeadNode); - ParamListNode:=HeadNode.FirstChild; + + // for procs: use ctnProcedureHead as parent + if ParentNode.Desc=ctnProcedure then + ParentNode:=ParentNode.FirstChild; + if (ParentNode.Desc=ctnProcedureHead) and NodeNeedsBuildSubTree(ParentNode) then + BuildSubTreeForProcHead(ParentNode); + + ParamListNode:=ParentNode.FirstChild; if (ParamListNode<>nil) and (ParamListNode.Desc<>ctnParameterList) then ParamListNode:=nil; - for i:=0 to Changes.Count-1 do begin - Change:=TChangeParamListItem(Changes[i]); - if Change.Action=cplaInsertNewParam then begin - // add a new parameter - NewCode:=''; - if Change.ParamModifier<>'' then - NewCode:=NewCode+Change.ParamModifier+' '; - NewCode:=NewCode+Change.ParamName+':'+Change.ParamType; - if ParamListNode=nil then begin - debugln(['TChangeDeclarationTool.ChangeProcParamListDeclaration start new param list']); - if Change.Index<>0 then - raise Exception.Create('TChangeDeclarationTool.ChangeProcParamListDeclaration: add first: wrong index'); - MoveCursorBehindProcName(HeadNode); - InsertPos:=CurPos.StartPos; - NewCode:='('+NewCode+')'; - NewCode:=SourceChanger.BeautifyCodeOptions.BeautifyStatement(NewCode,0); - Result:=SourceChanger.Replace(gtNone,gtNone,InsertPos,InsertPos,NewCode); - exit; - end; - debugln(['TChangeDeclarationTool.ChangeProcParamListDeclaration extend existing param list']); - if (Change.Index<0) or (Change.Index>ParamListNode.ChildCount) then - raise Exception.Create('TChangeDeclarationTool.ChangeProcParamListDeclaration: insert: wrong index'); - if Change.Index=0 then begin - // insert as first - InsertPos:=ParamListNode.StartPos+1; - if ParamListNode.FirstChild<>nil then - NewCode:=NewCode+';'; - NewCode:=SourceChanger.BeautifyCodeOptions.BeautifyStatement(NewCode,0); - Result:=SourceChanger.Replace(gtNone,gtSpace,InsertPos,InsertPos,NewCode); - exit; - end; - ParamNode:=ParamListNode.FirstChild; - for j:=1 to Change.Index-1 do - ParamNode:=ParamNode.NextBrother; - // insert behind ParamNode - if ParamNode.NextBrother=nil then begin - // insert as last - InsertPos:=ParamNode.EndPos; - NewCode:=';'+NewCode; - NewCode:=SourceChanger.BeautifyCodeOptions.BeautifyStatement(NewCode,0); - Result:=SourceChanger.Replace(gtNone,gtNone,InsertPos,InsertPos,NewCode); - exit; - end; - // insert between two parameters - if ParamNode.FirstChild<>nil then begin - // e.g. a:t1; b:t2 - InsertPos:=ParamNode.EndPos; - NewCode:=';'+NewCode; - NewCode:=SourceChanger.BeautifyCodeOptions.BeautifyStatement(NewCode,0); - Result:=SourceChanger.Replace(gtNone,gtNone,InsertPos,InsertPos,NewCode); - exit; - end; + Transactions:=TChangeParamListTransactions.Create(ParamListNode); + try + // ToDo: parse param list - debugln(['TChangeDeclarationTool.ChangeProcParamListDeclaration ToDo: implement insert between']); - exit; + + for i:=0 to Changes.Count-1 do begin + Change:=TChangeParamListItem(Changes[i]); + if (Change.Index<0) or (Change.Index>Transactions.MaxPos) then + raise Exception.Create('TChangeDeclarationTool.ChangeProcParamListDeclaration: index out of bounds'); + case Change.Action of + cplaInsertNewParam: + Transactions.Insert(Change.Index, + TChangeParamTransactionInsert.Create('',Change.ParamModifier, + Change.ParamName,Change.ParamType,Change.DefaultValue)); + + cplaDeleteParam: + Transactions.OldNodes[Change.Index].Delete:=true; + + cplaMoveParam: + begin + if (Change.OldIndex<0) or (Change.OldIndex>Transactions.MaxPos) then + raise Exception.Create('TChangeDeclarationTool.ChangeProcParamListDeclaration: index out of bounds'); + if Change.OldIndex<>Change.Index then begin + Transactions.OldNodes[Change.OldIndex].Delete:=true; + // ToDo: check if param contains comments + // if yes: copy with comments + // if not: extract parts + raise Exception.Create('TChangeDeclarationTool.ChangeProcParamListDeclaration: ToDo: move'); + end; + end; + + cplaChangeDefaultValue: + Transactions.OldNodes[Change.OldIndex].NewDefaultValue:=Change.DefaultValue; + + end; end; - end; + // ToDo: apply transactions + + finally + Transactions.Free; + end; Result:=true; end; -function TChangeDeclarationTool.ChangeParamListDeclaration(CleanPos: integer; +function TChangeDeclarationTool.ChangeParamListDeclarationAtPos(CleanPos: integer; Changes: TObjectList; SourceChanger: TSourceChangeCache): boolean; var Node: TCodeTreeNode; @@ -221,11 +306,11 @@ begin if Node.Desc=ctnProcedure then begin // change the parameter list of a procedure ProcNode:=Node; - Result:=ChangeProcParamListDeclaration(ProcNode,Changes,SourceChanger); + Result:=ChangeParamListDeclaration(ProcNode,Changes,SourceChanger); if not Result then exit; ProcNode2:=FindCorrespondingProcNode(ProcNode); if ProcNode2<>nil then begin - Result:=ChangeProcParamListDeclaration(ProcNode2,Changes,SourceChanger); + Result:=ChangeParamListDeclaration(ProcNode2,Changes,SourceChanger); if not Result then exit; end; end else begin @@ -243,16 +328,12 @@ var begin Result:=false; if (Changes=nil) or (Changes.Count=0) then exit(true); - if Changes.Count<>1 then begin - debugln(['TChangeDeclarationTool.ChangeParamList sorry, only one change supported']); - exit; - end; BuildTree(lsrEnd); SourceChanger.MainScanner:=Scanner; if (ProcPos.Code<>nil) and (CaretToCleanPos(ProcPos,CleanPos)=0) then begin // declaration is in this unit ProcPos:=CleanCodeXYPosition; - if not ChangeParamListDeclaration(CleanPos,Changes,SourceChanger) then exit; + if not ChangeParamListDeclarationAtPos(CleanPos,Changes,SourceChanger) then exit; end; Result:=SourceChanger.Apply; end;