* Merging revisions r44346 from trunk:

------------------------------------------------------------------------
    r44346 | michael | 2020-03-23 14:53:24 +0100 (Mon, 23 Mar 2020) | 1 line
    
    * Add constructor (part of webidl 2 spec)
    ------------------------------------------------------------------------

git-svn-id: branches/fixes_3_2@46568 -
This commit is contained in:
michael 2020-08-23 09:07:41 +00:00
parent 61ae4eea1f
commit 2b75bf162b
5 changed files with 93 additions and 38 deletions

View File

@ -118,7 +118,7 @@ Type
end; end;
{ TIDLConstDefinition } { TIDLConstDefinition }
TConstType = (ctFloat,ctInteger,ctBoolean,ctInfinity,ctNegInfinity,ctNan,ctNull,ctString,ctEmptyArray); TConstType = (ctFloat,ctInteger,ctBoolean,ctInfinity,ctNegInfinity,ctNan,ctNull,ctString,ctEmptyArray,ctEmptyObject);
TIDLConstDefinition = Class(TIDLDefinition) TIDLConstDefinition = Class(TIDLDefinition)
private private
FConstType: TConstType; FConstType: TConstType;
@ -207,6 +207,7 @@ Type
private private
FDefaultValue: String; FDefaultValue: String;
FHasDefaultValue: Boolean; FHasDefaultValue: Boolean;
FHasEllipsis: Boolean;
FIsOptional: Boolean; FIsOptional: Boolean;
FType: TIDLTypeDefDefinition; FType: TIDLTypeDefDefinition;
procedure SetType(AValue: TIDLTypeDefDefinition); procedure SetType(AValue: TIDLTypeDefDefinition);
@ -218,11 +219,12 @@ Type
Property ArgumentType : TIDLTypeDefDefinition Read FType Write SetType; Property ArgumentType : TIDLTypeDefDefinition Read FType Write SetType;
Property IsOptional : Boolean Read FIsOptional Write FIsOptional; Property IsOptional : Boolean Read FIsOptional Write FIsOptional;
Property HasDefaultValue : Boolean Read FHasDefaultValue Write FHasDefaultValue; Property HasDefaultValue : Boolean Read FHasDefaultValue Write FHasDefaultValue;
Property HasEllipsis : Boolean Read FHasEllipsis Write FHasEllipsis;
Property DefaultValue : String Read FDefaultValue Write FDefaultValue; Property DefaultValue : String Read FDefaultValue Write FDefaultValue;
end; end;
{ TIDLFunctionDefinition } { TIDLFunctionDefinition }
TFunctionOption = (foCallBack,foStatic,foStringifier,foGetter, foSetter, foDeleter, foLegacyCaller); TFunctionOption = (foCallBack,foStatic,foStringifier,foGetter, foSetter, foDeleter, foLegacyCaller, foConstructor);
TFunctionOptions = Set of TFunctionOption; TFunctionOptions = Set of TFunctionOption;
TIDLFunctionDefinition = Class(TIDLDefinition) TIDLFunctionDefinition = Class(TIDLDefinition)

View File

@ -129,7 +129,7 @@ implementation
Resourcestring Resourcestring
SErrInvalidToken = 'Invalid token: expected "%s", got: "%s"'; SErrInvalidToken = 'Invalid token: expected "%s", got: "%s"';
SErrInvalidTokenList = 'Invalid token: expected one of "%s", got: "%s"'; SErrInvalidTokenList = 'Invalid token: expected one of "%s", got: "%s"';
SExpectedOther = 'Unexpected token in attribute list: "%s".'; // SExpectedOther = 'Unexpected token in attribute list: "%s".';
SErrUnExpectedToken = 'Unexpected token : "%s"'; SErrUnExpectedToken = 'Unexpected token : "%s"';
SErrTypeNotAllowed = 'Type "%s" not allowed in "%s" type.'; SErrTypeNotAllowed = 'Type "%s" not allowed in "%s" type.';
SErrDictionaryNotFound = 'Dictionary %s not found'; SErrDictionaryNotFound = 'Dictionary %s not found';
@ -349,6 +349,11 @@ begin
GetToken; GetToken;
end; end;
Result.ArgumentType:=ParseType(Result,False); Result.ArgumentType:=ParseType(Result,False);
if CurrentToken=tkEllipsis then
begin
Result.HasEllipsis:=True;
GetToken;
end;
CheckCurrentToken(tkIdentifier); CheckCurrentToken(tkIdentifier);
Result.Name:=CurrentTokenString; Result.Name:=CurrentTokenString;
except except
@ -428,7 +433,7 @@ function TWebIDLParser.ParseOperation(aParent: TIDLBaseObject): TIDLFunctionDefi
on exit, we're on the final ) } on exit, we're on the final ) }
Const Const
Specials = [tkGetter, tkSetter, tkDeleter, tkLegacyCaller]; Specials = [tkGetter, tkSetter, tkDeleter, tkLegacyCaller, tkConstructor];
Var Var
Opts : TFunctionOptions; Opts : TFunctionOptions;
@ -443,16 +448,22 @@ begin
tkSetter : FO:=foSetter; tkSetter : FO:=foSetter;
tkDeleter : FO:=foDeleter; tkDeleter : FO:=foDeleter;
tkLegacyCaller : FO:=foLegacyCaller; tkLegacyCaller : FO:=foLegacyCaller;
tkConstructor : fo:=foConstructor;
end; end;
Include(Opts,FO); Include(Opts,FO);
GetToken; GetToken;
end; end;
Result:=TIDLFunctionDefinition(Context.Add(aParent,TIDLFunctionDefinition,'')); Result:=TIDLFunctionDefinition(Context.Add(aParent,TIDLFunctionDefinition,''));
try try
Result.ReturnType:=ParseType(Result,False,True); if (foConstructor in Opts) then
CheckCurrentToken(tkIdentifier); Result.Name:='New'
Result.Name:=CurrentTokenString; else
GetToken; begin
Result.ReturnType:=ParseType(Result,False,True);
CheckCurrentToken(tkIdentifier);
Result.Name:=CurrentTokenString;
GetToken;
end;
ParseArguments(Result.Arguments); ParseArguments(Result.Arguments);
Result.Options:=Result.Options+Opts; Result.Options:=Result.Options+Opts;
except except
@ -605,7 +616,7 @@ function TWebIDLParser.ParseConstValue(out aValue: UTF8String;
Const Const
ValueTokens = [tkTrue,tkFalse,tkNumberFloat,tkNumberInteger,tkNull,tkInfinity,tkNegInfinity,tkNan]; ValueTokens = [tkTrue,tkFalse,tkNumberFloat,tkNumberInteger,tkNull,tkInfinity,tkNegInfinity,tkNan];
ExtendedTokens = [tkSquaredBraceOpen,tkString]; ExtendedTokens = [tkSquaredBraceOpen,tkString, tkCurlyBraceOpen];
ExtendedValueTokens = ExtendedTokens + ValueTokens; ExtendedValueTokens = ExtendedTokens + ValueTokens;
AllowedTokens : Array[Boolean] of TIDLTokens = (ValueTokens,ExtendedValueTokens); AllowedTokens : Array[Boolean] of TIDLTokens = (ValueTokens,ExtendedValueTokens);
@ -634,6 +645,15 @@ begin
end end
else else
Error(SErrUnExpectedToken,[CurrentTokenString]); Error(SErrUnExpectedToken,[CurrentTokenString]);
tkCurlyBraceOpen :
If aExtended then
begin
ExpectToken(tkCurlyBraceClose);
aValue:=AValue+CurrentTokenString;
Result:=ctEmptyObject
end
else
Error(SErrUnExpectedToken,[CurrentTokenString]);
end; end;
end; end;
@ -903,11 +923,14 @@ Var
aName : UTF8String; aName : UTF8String;
begin begin
aName:=CurrentTokenString;
if version=v1 then if version=v1 then
Result:=ParseImplements('',aParent) begin
ExpectToken(tkImplements);
Result:=ParseImplements(aName,aParent)
end
else else
begin begin
aName:=CurrentTokenString;
ExpectTokens([tkImplements,tkIncludes]); ExpectTokens([tkImplements,tkIncludes]);
case CurrentToken of case CurrentToken of
tkIncludes: Result:=ParseIncludes(aName,aParent); tkIncludes: Result:=ParseIncludes(aName,aParent);
@ -945,25 +968,28 @@ function TWebIDLParser.ParseDictionaryMember(aParent : TIDLBaseObject): TIDLDict
Var Var
Attrs : TAttributeList; Attrs : TAttributeList;
tk : TIDLToken; tk : TIDLToken;
isRequired : Boolean; isReq : Boolean;
S : UTF8String; S : UTF8String;
begin begin
Attrs:=Nil; Attrs:=Nil;
tk:=CurrentToken; tk:=CurrentToken;
isRequired:=(tk=tkRequired); isReq:=(tk=tkRequired);
if IsRequired then if IsReq then
tk:=GetToken; tk:=GetToken;
if tk=tkSquaredBraceOpen then if tk=tkSquaredBraceOpen then
begin begin
Attrs:=ParseAttributes; Attrs:=ParseAttributes;
tk:=GetToken; tk:=GetToken;
isReq:=(tk=tkRequired);
if IsReq then
tk:=GetToken;
end; end;
Result:=TIDLDictionaryMemberDefinition(Context.Add(aParent,TIDLDictionaryMemberDefinition,'')); Result:=TIDLDictionaryMemberDefinition(Context.Add(aParent,TIDLDictionaryMemberDefinition,''));
try try
Result.Attributes:=Attrs; Result.Attributes:=Attrs;
Result.IsRequired:=isRequired; Result.IsRequired:=isReq;
Result.MemberType:=ParseType(Result,Assigned(Attrs),True); Result.MemberType:=ParseType(Result,False,True);
CheckCurrentToken(tkIdentifier); CheckCurrentToken(tkIdentifier);
Result.Name:=CurrentTokenString; Result.Name:=CurrentTokenString;
tk:=GetToken; tk:=GetToken;
@ -1181,8 +1207,7 @@ Var
begin begin
if Version=V1 then if Version=V1 then
begin begin
N:=CurrentTokenString; N:=aName
ExpectToken(tkImplements);
end end
else else
N:=aName; N:=aName;

View File

@ -103,14 +103,15 @@ type
tkMapLike, tkMapLike,
tkRecord, tkRecord,
tkSetLike, tkSetLike,
tkOther tkOther,
tkConstructor
); );
TIDLTokens = Set of TIDLToken; TIDLTokens = Set of TIDLToken;
EWebIDLScanner = class(EParserError); EWebIDLScanner = class(EParserError);
Const Const
V2Tokens = [tkMixin,tkIncludes,tkMapLike,tkRecord,tkSetLike,tkFrozenArray]; V2Tokens = [tkMixin,tkIncludes,tkMapLike,tkRecord,tkSetLike,tkFrozenArray,tkConstructor];
V1Tokens = []; V1Tokens = [tkImplements];
VersionNonTokens : Array[TWebIDLVersion] of TIDLTokens = (V2Tokens,V1Tokens); VersionNonTokens : Array[TWebIDLVersion] of TIDLTokens = (V2Tokens,V1Tokens);
Type Type
@ -234,7 +235,8 @@ const
'maplike', 'maplike',
'record', 'record',
'setlike', 'setlike',
'other' 'other',
'constructor'
); );
Function GetTokenName(aToken : TIDLToken) : String; Function GetTokenName(aToken : TIDLToken) : String;
@ -666,6 +668,7 @@ begin
inc(TokenStr); inc(TokenStr);
if TokenStr[0]<>'.' then if TokenStr[0]<>'.' then
Error(SErrInvalidEllipsis); Error(SErrInvalidEllipsis);
inc(TokenStr);
FCurTokenString:='...'; FCurTokenString:='...';
Result:=tkEllipsis; Result:=tkEllipsis;
end; end;

View File

@ -252,7 +252,7 @@ function TWebIDLToPas.WriteConst(aConst: TIDLConstDefinition): Boolean;
Const Const
ConstTypes : Array[TConstType] of String = ConstTypes : Array[TConstType] of String =
('Double','NativeInt','Boolean','JSValue','JSValue','JSValue','JSValue','String','JSValue'); ('Double','NativeInt','Boolean','JSValue','JSValue','JSValue','JSValue','String','JSValue','JSValue');
Var Var
S : String; S : String;
@ -452,7 +452,6 @@ Var
var var
I : integer; I : integer;
P : TPasData;
NOrig,N,N2 : String; NOrig,N,N2 : String;
isDup : Boolean; isDup : Boolean;
D2 : TIDLDefinition; D2 : TIDLDefinition;
@ -672,6 +671,7 @@ begin
'long long': TN:=UsePascalType('NativeInt'); 'long long': TN:=UsePascalType('NativeInt');
'unsigned short': TN:=UsePascalType('Cardinal'); 'unsigned short': TN:=UsePascalType('Cardinal');
'unrestricted float': TN:=UsePascalType('Double'); 'unrestricted float': TN:=UsePascalType('Double');
'unrestricted double': TN:=UsePascalType('Double');
'unsigned long': TN:=UsePascalType('NativeInt'); 'unsigned long': TN:=UsePascalType('NativeInt');
'unsigned long long': TN:=UsePascalType('NativeInt'); 'unsigned long long': TN:=UsePascalType('NativeInt');
'octet': TN:=UsePascalType('Byte'); 'octet': TN:=UsePascalType('Byte');
@ -1131,21 +1131,34 @@ Var
begin begin
Result:=True; Result:=True;
FN:=GetName(aDef); if not (foConstructor in aDef.Options) then
if FN<>aDef.Name then begin
Suff:=Format('; external name ''%s''',[aDef.Name]); FN:=GetName(aDef);
RT:=GetTypeName(aDef.ReturnType,False); if FN<>aDef.Name then
if (RT='void') then Suff:=Format('; external name ''%s''',[aDef.Name]);
RT:=''; RT:=GetTypeName(aDef.ReturnType,False);
if (RT='void') then
RT:='';
end
else
FN:='New';
Overloads:=GetOverloads(ADef); Overloads:=GetOverloads(ADef);
try try
for I:=0 to aDef.Arguments.Count-1 do
if aDef.Argument[i].HasEllipsis then
Suff:='; varargs';
if Overloads.Count>1 then if Overloads.Count>1 then
Suff:=Suff+'; overload'; Suff:=Suff+'; overload';
For I:=0 to Overloads.Count-1 do For I:=0 to Overloads.Count-1 do
begin begin
Args:=GetArguments(TIDLDefinitionList(Overloads[i]),False); Args:=GetArguments(TIDLDefinitionList(Overloads[i]),False);
if (RT='') then if (RT='') then
AddLn('Procedure %s%s%s;',[FN,Args,Suff]) begin
if not (foConstructor in aDef.Options) then
AddLn('Procedure %s%s%s;',[FN,Args,Suff])
else
AddLn('constructor %s%s%s;',[FN,Args,Suff]);
end
else else
AddLn('function %s%s: %s%s;',[FN,Args,RT,Suff]) AddLn('function %s%s: %s%s;',[FN,Args,RT,Suff])
end; end;
@ -1181,8 +1194,9 @@ begin
EnsureSection(csType); EnsureSection(csType);
for D in aList do for D in aList do
if D is TIDLDictionaryDefinition then if D is TIDLDictionaryDefinition then
if WriteDictionaryDef(DD) then if not TIDLDictionaryDefinition(D).IsPartial then
Inc(Result); if WriteDictionaryDef(DD) then
Inc(Result);
end; end;
function TWebIDLToPas.WriteInterfaceDefs(aList: TIDLDefinitionList): Integer; function TWebIDLToPas.WriteInterfaceDefs(aList: TIDLDefinitionList): Integer;
@ -1196,8 +1210,9 @@ begin
EnsureSection(csType); EnsureSection(csType);
for D in aList do for D in aList do
if D is TIDLInterfaceDefinition then if D is TIDLInterfaceDefinition then
if WriteInterfaceDef(ID) then if not TIDLInterfaceDefinition(D).IsPartial then
Inc(Result); if WriteInterfaceDef(ID) then
Inc(Result);
end; end;
procedure TWebIDLToPas.Getoptions(L : TStrings); procedure TWebIDLToPas.Getoptions(L : TStrings);
@ -1363,7 +1378,6 @@ procedure TWebIDLToPas.ProcessDefinitions;
begin begin
FContext.AppendPartials; FContext.AppendPartials;
FContext.AppendIncludes; FContext.AppendIncludes;
AllocatePasNames(FContext.Definitions); AllocatePasNames(FContext.Definitions);
end; end;

View File

@ -245,6 +245,7 @@ Type
Procedure ParseSingleSimpleElement; Procedure ParseSingleSimpleElement;
Procedure ParseSingleSimpleElementInheritance; Procedure ParseSingleSimpleElementInheritance;
Procedure ParseSingleSimpleElementAttributes; Procedure ParseSingleSimpleElementAttributes;
Procedure ParseSingleSimpleElementAttributes2;
Procedure ParseSingleSimpleElementRequired; Procedure ParseSingleSimpleElementRequired;
Procedure ParseSingleSimpleElementDefaultString; Procedure ParseSingleSimpleElementDefaultString;
Procedure ParseSingleSimpleElementRequiredDefaultString; Procedure ParseSingleSimpleElementRequiredDefaultString;
@ -699,6 +700,7 @@ Var
begin begin
Src:=AName+' implements '+aImplements+';'+sLineBreak; Src:=AName+' implements '+aImplements+';'+sLineBreak;
InitSource(Src); InitSource(Src);
Parser.Version:=V1;
Parser.Parse; Parser.Parse;
AssertEquals('Correct class',TIDLImplementsDefinition,Definitions[0].ClassType); AssertEquals('Correct class',TIDLImplementsDefinition,Definitions[0].ClassType);
Result:=Definitions[0] as TIDLImplementsDefinition; Result:=Definitions[0] as TIDLImplementsDefinition;
@ -895,7 +897,16 @@ end;
procedure TTestDictionaryParser.ParseSingleSimpleElementAttributes; procedure TTestDictionaryParser.ParseSingleSimpleElementAttributes;
begin begin
ParseDictionary('A','',['[Replaceable] required string B']); ParseDictionary('A','',['[Replaceable] required string B']);
AssertMember(0,'B','string','',ctNull,False); AssertMember(0,'B','string','',ctNull,True);
AssertTrue('Has attributes',Dict[0].HasAttributes);
AssertEquals('Attribute count',1,Dict[0].Attributes.Count);
AssertEquals('Has attributes','Replaceable',Dict[0].Attributes[0]);
end;
procedure TTestDictionaryParser.ParseSingleSimpleElementAttributes2;
begin
ParseDictionary('A','',['[Replaceable] octet B']);
AssertMember(0,'B','octet','',ctNull,False);
AssertTrue('Has attributes',Dict[0].HasAttributes); AssertTrue('Has attributes',Dict[0].HasAttributes);
AssertEquals('Attribute count',1,Dict[0].Attributes.Count); AssertEquals('Attribute count',1,Dict[0].Attributes.Count);
AssertEquals('Has attributes','Replaceable',Dict[0].Attributes[0]); AssertEquals('Has attributes','Replaceable',Dict[0].Attributes[0]);
@ -1175,7 +1186,7 @@ Var
begin begin
Version:=v2; Version:=v2;
D:=TestTypeDef(aDef ,'A','record'}); D:=TestTypeDef(aDef ,'A','record');
AssertEquals('Correct class',TIDLRecordDefinition,D.ClassType); AssertEquals('Correct class',TIDLRecordDefinition,D.ClassType);
R:=TIDLRecordDefinition(D); R:=TIDLRecordDefinition(D);
AssertNotNull('Have key type',R.KeyType); AssertNotNull('Have key type',R.KeyType);