Updated gir2pascal to add the parameter error: PPGError to functions if throws=1 is set as a property name

https://bugzilla.gnome.org/show_bug.cgi?id=721588
Added support for the new parameter type "instance-parameter" which is similiar to the hidden "self" param of pascal


git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2876 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
drewski207
2014-01-06 02:31:04 +00:00
parent 64a3fb1dc4
commit ba51e1b8d9
5 changed files with 105 additions and 19 deletions

View File

@ -1,4 +1,4 @@
<?xml version="1.0"?> <?xml version="1.0" encoding="UTF-8"?>
<CONFIG> <CONFIG>
<ProjectOptions> <ProjectOptions>
<Version Value="9"/> <Version Value="9"/>

View File

@ -34,6 +34,7 @@ type
geUnhandledNode = 'Unhandled node [%s] "%s"'; geUnhandledNode = 'Unhandled node [%s] "%s"';
geUnexpectedNodeType = 'Unexpected node [%s] type: found "%s" expected "%s"'; geUnexpectedNodeType = 'Unexpected node [%s] type: found "%s" expected "%s"';
geMissingNode = '[%s] Could not find child node "%s" while looking in node "%s"'; geMissingNode = '[%s] Could not find child node "%s" while looking in node "%s"';
geAddingErrorNode = '%s %s throws an error but is not included as a param. Adding...';
var var
girErrorName: array[TGirError] of String =( girErrorName: array[TGirError] of String =(

View File

@ -106,14 +106,17 @@ type
TgirTypeParam = class(TGirBaseType) TgirTypeParam = class(TGirBaseType)
private private
FIsInstanceParam: Boolean;
FVarType: TGirBaseType; FVarType: TGirBaseType;
FPointerLevel: Integer; FPointerLevel: Integer;
function GetPointerLevel: Integer; function GetPointerLevel: Integer;
function GetType: TGirBaseType; function GetType: TGirBaseType;
public public
constructor Create(AOwner: TObject; ANode: TDomNode); override; constructor Create(AOwner: TObject; ANode: TDomNode); override;
constructor Create(AOwner: TObject; ANode: TDomNode; AIsInstanceParam: Boolean); virtual;
property VarType: TGirBaseType read GetType; property VarType: TGirBaseType read GetType;
property PointerLevel: Integer read GetPointerLevel; property PointerLevel: Integer read GetPointerLevel;
property IsInstanceParam: Boolean read FIsInstanceParam;
end; end;
{ TgirProperty } { TgirProperty }
@ -199,6 +202,7 @@ type
TGirFunctionParam = class(TgirTypeParam) TGirFunctionParam = class(TgirTypeParam)
public public
constructor Create(AOwner: TObject; ANode: TDomNode); override; constructor Create(AOwner: TObject; ANode: TDomNode); override;
constructor Create(AOwner: TObject; ANode: TDomNode; AIsInstanceParam: Boolean); override;
end; end;
{ TgirFunctionReturn } { TgirFunctionReturn }
@ -226,6 +230,7 @@ type
FDeprecatedVersion: String; FDeprecatedVersion: String;
FParams: TgirParamList; FParams: TgirParamList;
FReturns: TgirFunctionReturn; FReturns: TgirFunctionReturn;
FThrowsGError: Boolean;
publiC publiC
constructor Create(AOwner: TObject; ANode: TDomNode); override; constructor Create(AOwner: TObject; ANode: TDomNode); override;
destructor Destroy; override; destructor Destroy; override;
@ -235,6 +240,7 @@ type
property Deprecated: Boolean read FDeprecated; property Deprecated: Boolean read FDeprecated;
property DeprecatedMsg: String read FDeprecatedMsg; property DeprecatedMsg: String read FDeprecatedMsg;
property DeprecatedVersion: String read FDeprecatedVersion; property DeprecatedVersion: String read FDeprecatedVersion;
property ThrowsGError: Boolean read FThrowsGError write FThrowsGError;
end; end;
{ TgirMethod } { TgirMethod }
@ -374,7 +380,7 @@ type
implementation implementation
uses girNameSpaces, girErrors; uses girNameSpaces, girErrors, XMLRead;
{ TgirClassStruct } { TgirClassStruct }
@ -773,6 +779,12 @@ begin
FObjectType:=otFunctionParam; FObjectType:=otFunctionParam;
end; end;
constructor TGirFunctionParam.Create(AOwner: TObject; ANode: TDomNode;
AIsInstanceParam: Boolean);
begin
inherited Create(AOwner, ANode, AIsInstanceParam);
end;
{ TgirTypeParam } { TgirTypeParam }
function TgirTypeParam.GetType: TGirBaseType; function TgirTypeParam.GetType: TGirBaseType;
@ -891,6 +903,13 @@ begin
FObjectType:=otTypeParam; FObjectType:=otTypeParam;
end; end;
constructor TgirTypeParam.Create(AOwner: TObject; ANode: TDomNode;
AIsInstanceParam: Boolean);
begin
FIsInstanceParam:=AIsInstanceParam;
Create(AOwner, ANode);
end;
{ TgirFunction } { TgirFunction }
constructor TgirFunction.Create(AOwner: TObject; ANode: TDomNode); constructor TgirFunction.Create(AOwner: TObject; ANode: TDomNode);
@ -898,6 +917,46 @@ var
Node: TDOMNode; Node: TDOMNode;
NodeToken: TGirToken; NodeToken: TGirToken;
procedure CheckAddErrorParam(ParentNode: TDomNode);
//const
// ErrorXML = '<parameter name="error"> <type name="Error" c:type="GError**"/> </parameter>';
var
Param: TGirFunctionParam;
AddParam: Boolean;
ErrorNode: TDOMElement;
TypeNode: TDOMElement;
begin
// some functions have throws=1 as a property of the node. This indicates that
// the last parameter is GError **error. The introspection file does not include
// this as a parameter so we have to add it ourselves
AddParam:=False;
if FParams.Count > 0 then
begin
Param := FParams.Param[FParams.Count-1];
//WriteLn(Param.CType);
if Param.CType <> 'GError**' then
begin
AddParam:=True;
end;
end
else
AddParam:=True;
if AddParam then
begin
girError(geInfo, Format(geAddingErrorNode,[ClassName, CIdentifier]));
ErrorNode := ParentNode.OwnerDocument.CreateElement('parameter');
ErrorNode.SetAttribute('name','error');
TypeNode := ParentNode.OwnerDocument.CreateElement('type');
ErrorNode.AppendChild(TypeNode);
TypeNode.SetAttribute('name','Error');
TypeNode.SetAttribute('c:type','GError**');
ParentNode.AppendChild(ErrorNode);
end;
end;
procedure CreateParameters(ANode: TDomNode); procedure CreateParameters(ANode: TDomNode);
var var
PNode: TDomNode; PNode: TDomNode;
@ -913,9 +972,16 @@ var
Param := TGirFunctionParam.Create(AOwner, PNode); Param := TGirFunctionParam.Create(AOwner, PNode);
FParams.Add(Param); FParams.Add(Param);
end; end;
gtInstanceParameter:
begin
Param := TGirFunctionParam.Create(AOwner, PNode, True);
FParams.Add(Param);
end;
else else
girError(geError, Format(geUnexpectedNodeType,[ClassName, PNode.NodeName, GirTokenName[gtParameter]])); girError(geError, Format(geUnexpectedNodeType,[ClassName, PNode.NodeName, GirTokenName[gtParameter]]));
end; end;
if FThrowsGError and (PNode.NextSibling = nil) then
CheckAddErrorParam(ANode); // may add a NextSibling
PNode := PNode.NextSibling; PNode := PNode.NextSibling;
end; end;
end; end;
@ -924,6 +990,7 @@ begin
inherited Create(AOwner, ANode); inherited Create(AOwner, ANode);
FParams := TgirParamList.Create; FParams := TgirParamList.Create;
FCIdentifier:=TDOMElement(ANode).GetAttribute('c:identifier'); FCIdentifier:=TDOMElement(ANode).GetAttribute('c:identifier');
ThrowsGError:=TDOMElement(ANode).GetAttribute('throws') = '1';
if FName = '' then FName:=FCIdentifier; if FName = '' then FName:=FCIdentifier;
if FName = '' then FName:=StringReplace(FCType, '*', '', [rfReplaceAll]); if FName = '' then FName:=StringReplace(FCType, '*', '', [rfReplaceAll]);

View File

@ -213,7 +213,7 @@ type
procedure WriteWrapperForObject(ARoutineType, AObjectName, AObjectFunctionName: String; AParams:TgirParamList; AFunctionReturns: String; AFlatFunctionName: String; AWantSelf: Boolean); procedure WriteWrapperForObject(ARoutineType, AObjectName, AObjectFunctionName: String; AParams:TgirParamList; AFunctionReturns: String; AFlatFunctionName: String; AWantSelf: Boolean);
function WriteCallBack(AItem: TgirFunction; IsInObject: Boolean; AExistingUsedNames: TStringList = nil): String; function WriteCallBack(AItem: TgirFunction; IsInObject: Boolean; AExistingUsedNames: TStringList = nil): String;
procedure WriteFunctionTypeAndReturnType(AItem: TgirFunction; out AFunctionType, AFunctionReturnType: String); procedure WriteFunctionTypeAndReturnType(AItem: TgirFunction; out AFunctionType, AFunctionReturnType: String);
function WriteFunctionParams(AParams: TgirParamList; AArgs: PString = nil): String; function WriteFunctionParams(AParams: TgirParamList; AArgs: PString = nil; AIncludeInstanceParam: Boolean = False): String;
function WriteFunction(AFunction: TgirFunction; AItem: TGirBaseType; AIsMethod: Boolean; AWantWrapperForObject: Boolean; AFunctionList: TStrings; AExistingUsedNames: TStringList = nil): String; function WriteFunction(AFunction: TgirFunction; AItem: TGirBaseType; AIsMethod: Boolean; AWantWrapperForObject: Boolean; AFunctionList: TStrings; AExistingUsedNames: TStringList = nil): String;
function WriteParamAsString(AParam: TgirTypeParam; AIndex: Integer; out ABitSizeSpecified: Boolean; AFirstParam: PString = nil; AExistingUsedNames: TStringList = nil): String; function WriteParamAsString(AParam: TgirTypeParam; AIndex: Integer; out ABitSizeSpecified: Boolean; AFirstParam: PString = nil; AExistingUsedNames: TStringList = nil): String;
function WriteRecord(ARecord: TgirRecord; ABaseIndent: Integer = 0; AIsUnion: Boolean = False): String; function WriteRecord(ARecord: TgirRecord; ABaseIndent: Integer = 0; AIsUnion: Boolean = False): String;
@ -1144,10 +1144,14 @@ var
Postfix: String; Postfix: String;
Entry: String; Entry: String;
InLineS: String = ''; InLineS: String = '';
Deprecated: String = ''; DeprecatedS: String = '';
ProperUnit: TPascalUnit; ProperUnit: TPascalUnit;
OptionsIndicateWrapperMethod: Boolean; OptionsIndicateWrapperMethod: Boolean;
begin begin
{ I apologize to anyone who tries to figure all this out. In short this function
writes procedure lines for an object and it's implementation. As well as the
plain function the object method calls.
}
Result := ''; Result := '';
OptionsIndicateWrapperMethod:= FUnitType = PascalUnitTypeAll; OptionsIndicateWrapperMethod:= FUnitType = PascalUnitTypeAll;
// we skip deprecated functions // we skip deprecated functions
@ -1164,7 +1168,7 @@ begin
if AWantWrapperForObject then if AWantWrapperForObject then
InLineS:=' inline;'; InLineS:=' inline;';
if AFunction.Deprecated then Deprecated :=' deprecated ''Since ' + NameSpace.NameSpace + ' ' + AFunction.DeprecatedVersion+' '+StringReplace(AFunction.DeprecatedMsg,'''','`', [rfReplaceAll])+''';'; if AFunction.Deprecated then DeprecatedS :=' deprecated ''Since ' + NameSpace.NameSpace + ' ' + AFunction.DeprecatedVersion+' '+StringReplace(AFunction.DeprecatedMsg,'''','`', [rfReplaceAll])+''';';
// this fills in the values for procedure/function and the return type // this fills in the values for procedure/function and the return type
WriteFunctionTypeAndReturnType(AFunction, RoutineType, Returns); WriteFunctionTypeAndReturnType(AFunction, RoutineType, Returns);
@ -1172,13 +1176,13 @@ begin
if AFunction.InheritsFrom(TgirConstructor) then if AFunction.InheritsFrom(TgirConstructor) then
Returns := ': '+MakePascalTypeFromCType(AItem.TranslatedName ,1)+'; cdecl;'; Returns := ': '+MakePascalTypeFromCType(AItem.TranslatedName ,1)+'; cdecl;';
Params := WriteFunctionParams(AFunction.Params); Params := WriteFunctionParams(AFunction.Params, nil, False);
if Pos('array of const', Params) + Pos('va_list', Params) > 0 then if Pos('array of const', Params) + Pos('va_list', Params) > 0 then
Prefix:='//'; Prefix:='//';
if not (goLinkDynamic in FOptions) then if not (goLinkDynamic in FOptions) then
Postfix := ' external;'+ Deprecated// '+UnitName+'_library;'; Postfix := ' external;'+ DeprecatedS// '+UnitName+'_library;';
else else
PostFix := ''+Deprecated; PostFix := ''+DeprecatedS;
// first wrapper proc // first wrapper proc
Entry := Prefix + RoutineType +' '+ SanitizeName(AFunction.Name, AExistingUsedNames)+ParenParams(Params)+Returns+InLineS; Entry := Prefix + RoutineType +' '+ SanitizeName(AFunction.Name, AExistingUsedNames)+ParenParams(Params)+Returns+InLineS;
@ -1190,18 +1194,24 @@ begin
// This is the line that will be used by in the TObject declaration. <---- // This is the line that will be used by in the TObject declaration. <----
// result will be written in the object declaration. // result will be written in the object declaration.
if OptionsIndicateWrapperMethod and not(goNoWrappers in FOptions) then if OptionsIndicateWrapperMethod and not(goNoWrappers in FOptions) then
Result := Entry + Deprecated Result := Entry + DeprecatedS
else else
Result := ''; Result := '';
// now make sure the flat proc has all the params it needs // now make sure the flat proc has all the params it needs
if AIsMethod then if AIsMethod then
begin begin
// methods do not include the first param for it's type so we have to add it // with older introspection versions methods do not include the first param for it's type so we have to add it
if Params <> '' then if (AFunction.Params.Count = 0) // <--only true if older
Params := SanitizeName('A'+AItem.Name) +': '+TypeAsString(AItem, 1)+'; ' + Params or ((AFunction.Params.Count > 0) and not(AFunction.Params.Param[0].IsInstanceParam)) then // <-- true if older
begin
if Params <> '' then
Params := SanitizeName('A'+AItem.Name) +': '+TypeAsString(AItem, 1)+'; ' + Params
else
Params := SanitizeName('A'+AItem.Name) +': '+TypeAsString(AItem, 1);
end
else else
Params := SanitizeName('A'+AItem.Name) +': '+TypeAsString(AItem, 1); Params := WriteFunctionParams(AFunction.Params, nil, True);
end; end;
ProperUnit := FGroup.GetUnitForType(utFunctions); ProperUnit := FGroup.GetUnitForType(utFunctions);
@ -1625,7 +1635,7 @@ var
begin begin
if AWantSelf then if AWantSelf then
begin begin
if AParams.Count = 0 then if (AParams.Count = 0) or ((AParams.Count = 1) and AParams.Param[0].IsInstanceParam) then
CallParams:='@self' CallParams:='@self'
else else
CallParams:='@self, '; CallParams:='@self, ';
@ -1634,11 +1644,12 @@ begin
CallParams:=''; CallParams:='';
if (ARoutineType = 'function') or (ARoutineType='constructor') then if (ARoutineType = 'function') or (ARoutineType='constructor') then
ResultStr := 'Result := '; ResultStr := 'Result := ';
Params:=WriteFunctionParams(AParams, @Args); Params:=WriteFunctionParams(AParams, @Args, not AWantSelf);
CallParams:=CallParams+Args; CallParams:=CallParams+Args;
Code := TPCodeText.Create; Code := TPCodeText.Create;
Code.Content := Format(Decl, [ARoutineType, AObjectName, AObjectFunctionName, ParenParams(Params), AFunctionReturns])+ Code.Content := Format(Decl, [ARoutineType, AObjectName, AObjectFunctionName, ParenParams(Params), AFunctionReturns])+
Format(Body, [ResultStr, FGroup.UnitForType[utFunctions].UnitFileName+'.'+AFlatFunctionName, CallParams]); Format(Body, [ResultStr, FGroup.UnitForType[utFunctions].UnitFileName+'.'+AFlatFunctionName,
CallParams]);
ImplementationSection.Declarations.Add(Code); ImplementationSection.Declarations.Add(Code);
@ -1690,7 +1701,7 @@ begin
end; end;
end; end;
function TPascalUnit.WriteFunctionParams(AParams: TgirParamList; AArgs: PString = nil): String; function TPascalUnit.WriteFunctionParams(AParams: TgirParamList; AArgs: PString = nil; AIncludeInstanceParam: Boolean = false): String;
var var
i: Integer; i: Integer;
ArgName: String; ArgName: String;
@ -1701,7 +1712,13 @@ begin
AArgs^ := ''; AArgs^ := '';
for i := 0 to AParams.Count-1 do for i := 0 to AParams.Count-1 do
begin begin
Result := Result+WriteParamAsString(AParams.Param[i], i, Dummy, @ArgName); // IsInstanceParam is only the ever the first param so this is safe if it's the
// only Param and AArgs is not updated. AArgs := @Self[, ;] is set in WriteFunction
if AIncludeInstanceParam or (not AIncludeInstanceParam and not AParams.Param[i].IsInstanceParam) then
Result := Result+WriteParamAsString(AParams.Param[i], i, Dummy, @ArgName)
else
Continue;
if i < AParams.Count-1 then if i < AParams.Count-1 then
begin begin
Result := Result +'; '; Result := Result +'; ';

View File

@ -28,7 +28,7 @@ uses
type type
TGirToken = (gtInvalid, gtAlias, gtConstant, gtRecord, gtBitField, gtEnumeration, TGirToken = (gtInvalid, gtAlias, gtConstant, gtRecord, gtBitField, gtEnumeration,
gtCallback, gtUnion, gtFunction, gtReturnValue, gtType, gtCallback, gtUnion, gtFunction, gtReturnValue, gtType,
gtParameters, gtParameter, gtMember, gtField, gtMethod, gtArray, gtParameters, gtParameter, gtInstanceParameter, gtMember, gtField, gtMethod, gtArray,
gtDoc, gtConstructor, gtRepository, gtInclude, gtNameSpace, gtPackage, gtDoc, gtConstructor, gtRepository, gtInclude, gtNameSpace, gtPackage,
gtCInclude, gtClass, gtProperty, gtVirtualMethod, gtInterface, gtCInclude, gtClass, gtProperty, gtVirtualMethod, gtInterface,
gtGlibSignal, gtImplements, gtPrerequisite,gtVarArgs, gtObject, gtClassStruct, gtGType); gtGlibSignal, gtImplements, gtPrerequisite,gtVarArgs, gtObject, gtClassStruct, gtGType);
@ -50,6 +50,7 @@ var
'type', 'type',
'parameters', 'parameters',
'parameter', 'parameter',
'instance-parameter',
'member', 'member',
'field', 'field',
'method', 'method',