codetools: sort declaration changes

git-svn-id: trunk@30561 -
This commit is contained in:
mattias 2011-05-05 21:35:05 +00:00
parent f429d822c0
commit 20c335471a

View File

@ -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;