mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-24 02:39:27 +02:00
codetools: param list insertion
git-svn-id: trunk@30650 -
This commit is contained in:
parent
d5632feea6
commit
bc90d1d06c
@ -94,7 +94,7 @@ type
|
||||
Modifier: string;
|
||||
Name: string;
|
||||
Typ: string;
|
||||
Value: string;
|
||||
DefaultValue: string;
|
||||
CopyFromParamIndex: integer;
|
||||
constructor Create(aSrc, aModifier, aName, aType, aValue: string;
|
||||
aCopyFrom: integer);
|
||||
@ -119,6 +119,7 @@ type
|
||||
LastInGroup: integer;
|
||||
|
||||
Delete: boolean;
|
||||
ChangeDefaultValue: boolean;
|
||||
NewDefaultValue: string;
|
||||
InsertBehind: TObjectList;// list of TChangeParamTransactionInsert
|
||||
constructor Create;
|
||||
@ -152,7 +153,7 @@ begin
|
||||
Modifier:=aModifier;
|
||||
Name:=aName;
|
||||
Typ:=aType;
|
||||
Value:=aValue;
|
||||
DefaultValue:=aValue;
|
||||
CopyFromParamIndex:=aCopyFrom;
|
||||
end;
|
||||
|
||||
@ -310,7 +311,7 @@ begin
|
||||
else if ParentNode.Desc=ctnProperty then
|
||||
MoveCursorBehindPropName(ParentNode)
|
||||
else
|
||||
raise Exception.Create('TChangeDeclarationTool.ChangeParamListDeclaration kind not supported: '+ParentNode.DescAsString);
|
||||
raise EInvalidOperation.Create('TChangeDeclarationTool.ChangeParamListDeclaration kind not supported: '+ParentNode.DescAsString);
|
||||
t.BehindNamePos:=LastAtoms.GetValueAt(0).EndPos;
|
||||
// read bracket
|
||||
if CurPos.Flag=cafRoundBracketOpen then
|
||||
@ -441,8 +442,9 @@ function TChangeDeclarationTool.ApplyParamListTransactions(
|
||||
var
|
||||
t: TChangeParamListTransactions;
|
||||
InsertCode: String;
|
||||
i: Integer;
|
||||
InsertParam: TChangeParamTransactionInsert;
|
||||
InsertPos: Integer;
|
||||
ReplaceStartPos: Integer;
|
||||
ReplaceEndPos: Integer;
|
||||
|
||||
function WholeParamListWillBeDeleted: boolean;
|
||||
var
|
||||
@ -459,6 +461,87 @@ var
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
procedure InsertParam(Insertion: TChangeParamTransactionInsert;
|
||||
FrontParam: TChangeParamTransactionPos);
|
||||
var
|
||||
SrcParam: TChangeParamTransactionPos;
|
||||
begin
|
||||
if ReplaceStartPos=0 then begin
|
||||
ReplaceStartPos:=InsertPos;
|
||||
ReplaceEndPos:=ReplaceStartPos;
|
||||
end;
|
||||
if (InsertCode<>'') and (not (InsertCode[length(InsertCode)] in [';','(','[']))
|
||||
then
|
||||
InsertCode:=InsertCode+';';
|
||||
if Insertion.Src<>'' then
|
||||
InsertCode:=InsertCode+Insertion.Src
|
||||
else if Insertion.CopyFromParamIndex>=0 then begin
|
||||
// copy source including comments
|
||||
SrcParam:=t.OldNodes[Insertion.CopyFromParamIndex];
|
||||
// ToDo: remove separator
|
||||
// ToDo: a,//
|
||||
// ToDo: a;//
|
||||
InsertCode:=ExtractCode(SrcParam.GetFirstPos,SrcParam.GetLastPos(true),[]);
|
||||
end else begin
|
||||
if Insertion.Modifier<>'' then
|
||||
InsertCode:=InsertCode+Insertion.Modifier+' ';
|
||||
InsertCode:=InsertCode+Insertion.Name;
|
||||
if Insertion.Typ<>'' then
|
||||
InsertCode:=InsertCode+':'+Insertion.Typ;
|
||||
if Insertion.DefaultValue<>'' then
|
||||
InsertCode:=InsertCode+'='+Insertion.DefaultValue;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ChangeParam(aParam: TChangeParamTransactionPos);
|
||||
var
|
||||
i: Integer;
|
||||
Code: String;
|
||||
p: LongInt;
|
||||
begin
|
||||
if aParam.Delete then begin
|
||||
if ReplaceStartPos<1 then begin
|
||||
ReplaceStartPos:=aParam.GetFirstPos;
|
||||
ReplaceEndPos:=aParam.GetLastPos(true);
|
||||
// ToDo: delete the last parameter => delete separator from previous parameter
|
||||
// ToDo: delete space
|
||||
end;
|
||||
end else begin
|
||||
// keep this parameter at this place
|
||||
if ReplaceStartPos>0 then begin
|
||||
// insert the changes in front
|
||||
ReplaceEndPos:=aParam.GetFirstPos;
|
||||
if not SourceChanger.Replace(gtNone,gtNone,
|
||||
ReplaceStartPos,ReplaceEndPos,InsertCode)
|
||||
then exit;
|
||||
ReplaceStartPos:=0;
|
||||
ReplaceEndPos:=0;
|
||||
InsertCode:='';
|
||||
end;
|
||||
if aParam.ChangeDefaultValue then begin
|
||||
// ToDo: keep modifier, name and type and change default value
|
||||
if aParam.DefaultValue.StartPos>0 then begin
|
||||
// replace the default value
|
||||
Code:=aParam.NewDefaultValue;
|
||||
if Code<>'' then Code:='='+Code;
|
||||
if not SourceChanger.Replace(gtNone,gtNone,
|
||||
aParam.DefaultValue.StartPos,aParam.DefaultValue.EndPos,Code)
|
||||
then exit;
|
||||
end else if aParam.NewDefaultValue<>'' then begin
|
||||
// insert a default value
|
||||
Code:=':'+aParam.NewDefaultValue;
|
||||
p:=aParam.Typ.EndPos;
|
||||
if not SourceChanger.Replace(gtNone,gtNone,p,p,Code)
|
||||
then exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
for i:=0 to aParam.InsertBehind.Count-1 do
|
||||
InsertParam(TChangeParamTransactionInsert(aParam.InsertBehind[i]),aParam);
|
||||
end;
|
||||
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result:=false;
|
||||
t:=Transactions as TChangeParamListTransactions;
|
||||
@ -474,41 +557,109 @@ begin
|
||||
end;
|
||||
|
||||
InsertCode:='';
|
||||
InsertPos:=0;
|
||||
ReplaceStartPos:=0;
|
||||
ReplaceEndPos:=0;
|
||||
if t.BracketOpenPos<1 then begin
|
||||
// start a new param list
|
||||
if t.Node.Desc=ctnProperty then
|
||||
InsertCode:='['
|
||||
else
|
||||
InsertCode:='(';
|
||||
InsertPos:=t.BehindNamePos;
|
||||
ReplaceStartPos:=InsertPos;
|
||||
ReplaceEndPos:=ReplaceStartPos;
|
||||
end else begin
|
||||
// keep brackets
|
||||
InsertPos:=t.BracketOpenPos+1;
|
||||
end;
|
||||
|
||||
for i:=0 to t.InsertFirst.Count-1 do begin
|
||||
InsertParam:=TChangeParamTransactionInsert(t.InsertFirst[i]);
|
||||
if (InsertCode<>'') and (not (InsertCode[length(InsertCode)] in [';','(','[']))
|
||||
then
|
||||
InsertCode:=InsertCode+';';
|
||||
if InsertParam.Src<>'' then
|
||||
InsertCode:=InsertCode+InsertParam.Src
|
||||
else begin
|
||||
if InsertParam.Modifier<>'' then
|
||||
InsertCode:=InsertCode+InsertParam.Modifier+' ';
|
||||
InsertCode:=InsertCode+InsertParam.Name;
|
||||
if InsertParam.Typ<>'' then
|
||||
InsertCode:=InsertCode+':'+InsertParam.Typ;
|
||||
if InsertParam.Value<>'' then
|
||||
InsertCode:=InsertCode+'='+InsertParam.Value;
|
||||
end;
|
||||
for i:=0 to t.InsertFirst.Count-1 do
|
||||
InsertParam(TChangeParamTransactionInsert(t.InsertFirst[i]),nil);
|
||||
for i:=0 to t.MaxPos-1 do
|
||||
ChangeParam(t.OldNodes[i]);
|
||||
|
||||
if t.BracketOpenPos<1 then begin
|
||||
// end a new param list
|
||||
if t.Node.Desc=ctnProperty then
|
||||
InsertCode:=InsertCode+']'
|
||||
else
|
||||
InsertCode:=InsertCode+')';
|
||||
end;
|
||||
|
||||
if ReplaceStartPos>0 then
|
||||
if not SourceChanger.Replace(gtNone,gtNone,ReplaceStartPos,ReplaceEndPos,InsertCode)
|
||||
then
|
||||
exit;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TChangeDeclarationTool.ChangeParamListDeclaration(
|
||||
ParentNode: TCodeTreeNode; Changes: TObjectList;
|
||||
SourceChanger: TSourceChangeCache): boolean;
|
||||
var
|
||||
FoundVarArgs: Boolean;
|
||||
FoundDefaultValue: boolean;
|
||||
Transactions: TChangeParamListTransactions;
|
||||
|
||||
procedure CheckInsert(Insertion: TChangeParamTransactionInsert);
|
||||
var
|
||||
SrcParam: TChangeParamTransactionPos;
|
||||
HasDefaultValue: Boolean;
|
||||
begin
|
||||
// check that '...' (MacPas vararg) is last
|
||||
// check that after a parameter with default value all have default values
|
||||
if FoundVarArgs then
|
||||
raise EInvalidOperation.Create('TChangeDeclarationTool.ChangeParamListDeclaration: ... parameter must be the last');
|
||||
if Insertion.CopyFromParamIndex>=0 then begin
|
||||
SrcParam:=Transactions.OldNodes[Insertion.CopyFromParamIndex];
|
||||
if GetAtom(SrcParam.Name)='...' then
|
||||
FoundVarArgs:=true;
|
||||
if SrcParam.ChangeDefaultValue then
|
||||
HasDefaultValue:=SrcParam.NewDefaultValue<>''
|
||||
else
|
||||
HasDefaultValue:=SrcParam.DefaultValue.StartPos>0;
|
||||
end else begin
|
||||
if (Insertion.Name='...') then
|
||||
FoundVarArgs:=true;
|
||||
HasDefaultValue:=Insertion.DefaultValue<>'';
|
||||
end;
|
||||
if HasDefaultValue then
|
||||
FoundDefaultValue:=true
|
||||
else if FoundDefaultValue then
|
||||
raise EInvalidOperation.Create('TChangeDeclarationTool.ChangeParamListDeclaration: after a parameter with default value all parameters must have default values');
|
||||
end;
|
||||
|
||||
procedure CheckParam(aParam: TChangeParamTransactionPos);
|
||||
var
|
||||
i: Integer;
|
||||
HasDefaultValue: Boolean;
|
||||
begin
|
||||
if not aParam.Delete then begin
|
||||
// check that '...' (MacPas vararg) is last
|
||||
if FoundVarArgs then
|
||||
raise EInvalidOperation.Create('TChangeDeclarationTool.ChangeParamListDeclaration: ... parameter must be the last');
|
||||
if GetAtom(aParam.Name)='...' then
|
||||
FoundVarArgs:=true;
|
||||
if not aParam.Delete then begin
|
||||
if aParam.ChangeDefaultValue then
|
||||
HasDefaultValue:=aParam.NewDefaultValue<>''
|
||||
else
|
||||
HasDefaultValue:=aParam.DefaultValue.StartPos>0;
|
||||
if HasDefaultValue then
|
||||
FoundDefaultValue:=true
|
||||
else if FoundDefaultValue then
|
||||
raise EInvalidOperation.Create('TChangeDeclarationTool.ChangeParamListDeclaration: after a parameter with default value all parameters must have default values');
|
||||
end;
|
||||
end;
|
||||
for i:=0 to aParam.InsertBehind.Count-1 do
|
||||
CheckInsert(TChangeParamTransactionInsert(aParam.InsertBehind[i]));
|
||||
end;
|
||||
|
||||
var
|
||||
ParamListNode: TCodeTreeNode;
|
||||
i: Integer;
|
||||
Change: TChangeParamListItem;
|
||||
Transactions: TChangeParamListTransactions;
|
||||
Transaction: TChangeParamTransactionPos;
|
||||
begin
|
||||
Result:=false;
|
||||
@ -529,7 +680,7 @@ begin
|
||||
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.ChangeParamListDeclaration: index out of bounds');
|
||||
raise EInvalidOperation.Create('TChangeDeclarationTool.ChangeParamListDeclaration: index '+dbgs(Change.Index)+' out of bounds');
|
||||
case Change.Action of
|
||||
cplaInsertNewParam:
|
||||
Transactions.Insert(Change.Index,
|
||||
@ -540,18 +691,18 @@ begin
|
||||
begin
|
||||
Transaction:=Transactions.OldNodes[Change.Index];
|
||||
if Transaction.Delete then
|
||||
raise Exception.Create('TChangeDeclarationTool.ChangeParamListDeclaration: index already deleted');
|
||||
raise EInvalidOperation.Create('TChangeDeclarationTool.ChangeParamListDeclaration: index '+dbgs(Change.Index)+' already deleted');
|
||||
Transaction.Delete:=true;
|
||||
end;
|
||||
|
||||
cplaMoveParam:
|
||||
begin
|
||||
if (Change.OldIndex<0) or (Change.OldIndex>Transactions.MaxPos) then
|
||||
raise Exception.Create('TChangeDeclarationTool.ChangeParamListDeclaration: index out of bounds');
|
||||
raise EInvalidOperation.Create('TChangeDeclarationTool.ChangeParamListDeclaration: index out of bounds');
|
||||
if Change.OldIndex<>Change.Index then begin
|
||||
Transaction:=Transactions.OldNodes[Change.OldIndex];
|
||||
if Transaction.Delete then
|
||||
raise Exception.Create('TChangeDeclarationTool.ChangeParamListDeclaration: index already deleted');
|
||||
raise EInvalidOperation.Create('TChangeDeclarationTool.ChangeParamListDeclaration: index '+dbgs(Change.OldIndex)+' already deleted');
|
||||
Transaction.Delete:=true;
|
||||
Transactions.Insert(Change.Index,
|
||||
TChangeParamTransactionInsert.Create('','','','','',Change.OldIndex));
|
||||
@ -559,13 +710,28 @@ begin
|
||||
end;
|
||||
|
||||
cplaChangeDefaultValue:
|
||||
Transactions.OldNodes[Change.OldIndex].NewDefaultValue:=Change.DefaultValue;
|
||||
begin
|
||||
Transaction:=Transactions.OldNodes[Change.Index];
|
||||
if Transaction.Typ.StartPos<1 then
|
||||
raise EInvalidOperation.Create('TChangeDeclarationTool.ChangeParamListDeclaration: can not change the default value, because index '+dbgs(Change.Index)+' has no type');
|
||||
if Transaction.Delete then
|
||||
raise EInvalidOperation.Create('TChangeDeclarationTool.ChangeParamListDeclaration: index '+dbgs(Change.Index)+' already deleted');
|
||||
if Transaction.ChangeDefaultValue then
|
||||
raise EInvalidOperation.Create('TChangeDeclarationTool.ChangeParamListDeclaration: index '+dbgs(Change.Index)+' default value already changed');
|
||||
|
||||
Transaction.ChangeDefaultValue:=true;
|
||||
Transaction.NewDefaultValue:=Change.DefaultValue;
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
// ToDo: check default values
|
||||
// ToDo: check '...' is last
|
||||
FoundVarArgs:=false;
|
||||
FoundDefaultValue:=false;
|
||||
for i:=0 to Transactions.InsertFirst.Count-1 do
|
||||
CheckInsert(TChangeParamTransactionInsert(Transactions.InsertFirst[i]));
|
||||
for i:=0 to Transactions.MaxPos-1 do
|
||||
CheckParam(Transactions.OldNodes[i]);
|
||||
|
||||
// apply
|
||||
Result:=ApplyParamListTransactions(Transactions,SourceChanger);
|
||||
|
Loading…
Reference in New Issue
Block a user