mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-30 00:30:25 +02:00
codetools: sort declaration changes
git-svn-id: trunk@30561 -
This commit is contained in:
parent
f429d822c0
commit
20c335471a
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user