codetools: param list insertion

git-svn-id: trunk@30650 -
This commit is contained in:
mattias 2011-05-09 22:29:52 +00:00
parent d5632feea6
commit bc90d1d06c

View File

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