Browse Source

* Better callback and type handling

Michaël Van Canneyt 1 year ago
parent
commit
51ffa2220e

+ 57 - 4
packages/webidl/src/webidldefs.pp

@@ -264,9 +264,19 @@ type
     Property Options : TAttributeOptions Read FOptions Write FOptions;
   end;
 
+
+  { TIDLTypeDefinition }
+  // Everything that defines a named type descends from this:
+  // function, typedef, enum, interface, dictionary, namespace, callback
+  TIDLTypeDefinition = class(TIDLDefinition)
+  Public
+    // Type name in Javascript
+    Function GetJSTypeName : String; virtual; abstract;
+  end;
+
   { TIDLStructuredDefinition }
 
-  TIDLStructuredDefinition = Class(TIDLDefinition)
+  TIDLStructuredDefinition = Class(TIDLTypeDefinition)
   Private
     FIsCallBack: Boolean;
     FPartials,
@@ -278,6 +288,7 @@ type
     function GetPartial(Aindex : Integer): TIDLStructuredDefinition;
     function GetPartials: TIDLDefinitionList;
   Public
+    Function GetJSTypeName : String; override;
     Destructor Destroy; override;
     Function IsExtension : Boolean; override;
     Function GetFullMemberList(aList : TIDLDefinitionList) : Integer;
@@ -371,6 +382,18 @@ type
     Property Options : TFunctionOptions Read FOptions Write FOptions;
   end;
 
+  { TIDLCallBackDefinition }
+
+  TIDLCallBackDefinition = Class(TIDLTypeDefinition)
+  private
+    FFunctionDef: TIDLFunctionDefinition;
+  Public
+    Destructor Destroy; override;
+    Function GetJSTypeName: String; override;
+    Property FunctionDef : TIDLFunctionDefinition Read FFunctionDef Write FFunctionDef;
+  end;
+
+
   TSerializerKind = (skObject,skArray,skSingle,skFunction);
 
   { TIDLSerializerDefinition }
@@ -422,24 +445,26 @@ type
 
   { TIDLEnumDefinition }
 
-  TIDLEnumDefinition = Class(TIDLDefinition)
+  TIDLEnumDefinition = Class(TIDLTypeDefinition)
   private
     FValues: TStrings;
   Public
     Constructor Create(aParent : TIDLDefinition;Const aName : UTF8String; const aFile: string; aLine, aCol: integer); override;
     Destructor Destroy; override;
+    Function GetJSTypeName : String; override;
     Procedure AddValue(Const aValue : String);
     Property Values : TStrings Read FValues;
   end;
 
   { TIDLTypeDefDefinition }
 
-  TIDLTypeDefDefinition = Class(TIDLDefinition)
+  TIDLTypeDefDefinition = Class(TIDLTypeDefinition)
   private
     FNull: Boolean;
     FTypeName: String;
   Public
     Function Clone (aParent : TIDLDefinition) : TIDLTypeDefDefinition; virtual;
+    Function GetJSTypeName : String; override;
     Function AsString(Full: Boolean): UTF8String; override;
     Property TypeName : String Read FTypeName Write FTypeName;
     Property AllowNull : Boolean Read FNull Write FNull;
@@ -509,7 +534,7 @@ type
 
   { TIDLSetlikeDefinition }
 
-  TIDLSetlikeDefinition = Class(TIDLDefinition)
+  TIDLSetlikeDefinition = Class(TIDLTypeDefinition)
   private
     FElementType: TIDLTypeDefDefinition;
     FIsReadonly: Boolean;
@@ -763,6 +788,11 @@ begin
   Result.TypeName:=Self.TypeName;
 end;
 
+function TIDLTypeDefDefinition.GetJSTypeName: String;
+begin
+  Result:=FTypeName;
+end;
+
 function TIDLTypeDefDefinition.AsString(Full: Boolean): UTF8String;
 begin
   Result:=TypeName;
@@ -1014,6 +1044,19 @@ begin
     Result:=Attributes.AsString(Full)+' '+Result;
 end;
 
+{ TIDLCallBackDefinition }
+
+destructor TIDLCallBackDefinition.Destroy;
+begin
+  FreeAndNil(FFunctionDef);
+  inherited Destroy;
+end;
+
+function TIDLCallBackDefinition.GetJSTypeName: String;
+begin
+  Result:=Name;
+end;
+
 { TIDLDictionaryDefinition }
 
 function TIDLDictionaryDefinition.GetDM(AIndex : Integer
@@ -1189,6 +1232,11 @@ begin
   inherited Destroy;
 end;
 
+function TIDLEnumDefinition.GetJSTypeName: String;
+begin
+  Result:=Name;
+end;
+
 procedure TIDLEnumDefinition.AddValue(const aValue: String);
 begin
   FValues.Add(aValue);
@@ -1221,6 +1269,11 @@ begin
   Result:=FPartials;
 end;
 
+function TIDLStructuredDefinition.GetJSTypeName: String;
+begin
+  Result:=Name;
+end;
+
 destructor TIDLStructuredDefinition.Destroy;
 begin
   FreeAndNil(FMembers);

+ 17 - 8
packages/webidl/src/webidlparser.pp

@@ -103,12 +103,12 @@ Type
     function ParseExtAttributes: TExtAttributeList;
     procedure ParseExtAttributes(aList: TExtAttributeList; aTerminator: TIDLToken; ForSerializer: Boolean=False); virtual;
     // Definitions
-    // Type is a type without name of the type
     function AddDefinition(aParent : TIDLBaseObject; aClass : TIDLDefinitionClass; const AName : UTF8String) : TIDLDefinition; virtual;
     function ParseAttribute(aParent: TIDLBaseObject): TIDLAttributeDefinition; virtual;
     function ParseArgument(aParent: TIDLBaseObject): TIDLArgumentDefinition; virtual;
     procedure ParseArguments(aParent: TIDLBaseObject);virtual;
     function ParseFunction(aParent: TIDLBaseObject): TIDLFunctionDefinition; virtual;
+    // Type is a type without name of the type
     function ParseType(aParent: TIDLBaseObject; FetchFirst: Boolean=True; AllowExtraTypes : Boolean = False): TIDLTypeDefDefinition; virtual;
     function ParseDictionaryMember(aParent: TIDLBaseObject): TIDLDictionaryMemberDefinition; virtual;
     function CompleteSimpleType(tk: TIDLToken; Var S: UTF8String; out IsNull: Boolean): TIDLToken; virtual;
@@ -532,6 +532,7 @@ function TWebIDLParser.ParseCallBack(aParent : TIDLBaseObject): TIDLDefinition;
 var
   tk : TIDLToken;
   isConstructor : Boolean;
+  CB : TIDLCallBackDefinition;
 
 begin
   tk:=GetToken;
@@ -546,13 +547,21 @@ begin
        end;
     tkIdentifier :
        begin
-       Result:=ParseFunction(aParent);
-       With TIDLFunctionDefinition(Result) do
-         begin
-         Options:=Options+[foCallBack];
-         if isConstructor then
-           Options:=Options+[foConstructor];
-         end;
+       CB:=TIDLCallBackDefinition(AddDefinition(aParent,TIDLCallBackDefinition,''));
+       try
+         Result:=CB;
+         CB.FunctionDef:=ParseFunction(CB);
+         CB.Name:=CB.FunctionDef.Name;
+         With CB.FunctionDef do
+           begin
+           Options:=Options+[foCallBack];
+           if isConstructor then
+             Options:=Options+[foConstructor];
+           end;
+       except
+         CB.Free;
+         Raise;
+       end;
        end;
   else
     Error('[20220725174529] '+SErrInvalidTokenList,[GetTokenNames([tkInterface,tkIdentifier]),CurrentTokenString]);

+ 52 - 17
packages/webidl/src/webidltopas.pp

@@ -39,7 +39,7 @@ Type
     IDL: TIDLBaseObject;
     Line, Column: integer;
     SrcFile: string;
-    Resolved: TIDLDefinition;
+    Resolved: TIDLTypeDefinition;
     Constructor Create(APasName: String; D: TIDLBaseObject);
     Property PasName: String read FPasName write FPasName;
   end;
@@ -127,9 +127,9 @@ type
     function AddSequenceDef(ST: TIDLSequenceTypeDefDefinition): Boolean; virtual;
     function GetName(ADef: TIDLDefinition): String; virtual;
     function GetPasClassName(const aName: string): string; overload; virtual;
-    function GetTypeName(Const aTypeName: String; ForTypeDef: Boolean=False): String; overload; virtual;
+    function GetPascalTypeName(Const aTypeName: String; ForTypeDef: Boolean=False): String; overload; virtual;
     function GetTypeName(aTypeDef: TIDLTypeDefDefinition; ForTypeDef: Boolean=False): String; overload; virtual;
-    function GetResolvedType(aDef: TIDLTypeDefDefinition; out aTypeName, aResolvedTypename: string): TIDLDefinition; overload; virtual;
+    function GetResolvedType(aDef: TIDLTypeDefDefinition; out aTypeName, aResolvedTypename: string): TIDLTypeDefinition; overload; virtual;
     function GetSequenceTypeName(Seq: TIDLSequenceTypeDefDefinition; ForTypeDef: Boolean=False): string; virtual;
     function GetInterfaceDefHead(Intf: TIDLInterfaceDefinition): String; virtual;
     function GetNamespaceDefHead(Intf: TIDLNamespaceDefinition): String; virtual;
@@ -1023,12 +1023,14 @@ begin
     else
       Result:=GetSequenceTypeName(TIDLSequenceTypeDefDefinition(aTypeDef),ForTypeDef);
     end
+  else if assigned(aTypeDef) then
+    Result:=GetPascalTypeName(aTypeDef.GetJSTypeName,ForTypeDef)
   else
-    Result:=GetTypeName(aTypeDef.TypeName,ForTypeDef);
+    Result:='';
 end;
 
 function TBaseWebIDLToPas.GetResolvedType(aDef: TIDLTypeDefDefinition; out
-  aTypeName, aResolvedTypename: string): TIDLDefinition;
+  aTypeName, aResolvedTypename: string): TIDLTypeDefinition;
 begin
   Result:=nil;
   if aDef=nil then
@@ -1037,7 +1039,7 @@ begin
     aResolvedTypename:='';
     exit;
     end;
-  aTypeName:=GetTypeName(aDef.TypeName);
+  aTypeName:=GetPascalTypeName(aDef.GetJSTypeName);
   //writeln('TBaseWebIDLToPas.GetResolvedType START aDef=',aDef.Name,':',aDef.ClassName,' ',aDef.TypeName,' ',GetDefPos(aDef),' Resolved=',(aDef.Data is TPasData) and (TPasData(aDef.Data).Resolved<>nil));
   Result:=aDef;
   while (aDef.Data is TPasData) and (TPasData(aDef.Data).Resolved<>nil) do
@@ -1060,8 +1062,12 @@ function TBaseWebIDLToPas.GetSequenceTypeName(
   Seq: TIDLSequenceTypeDefDefinition; ForTypeDef: Boolean): string;
 begin
   Result:=GetTypeName(Seq.ElementType,ForTypeDef);
-  if Result='' then
-    raise EConvertError.Create('[20220725172227] sequence without name at '+GetDefPos(Seq));
+  if (Result='') then
+    begin
+    if ForTypeDef then
+      raise EConvertError.Create('[20220725172227] sequence without name at '+GetDefPos(Seq));
+    Result:=GetName(Seq);
+    end;
   if LeftStr(Result,length(ArrayPrefix))<>ArrayPrefix then
     Result:=ArrayPrefix+Result;
   Result:=Result+ArraySuffix;
@@ -1098,7 +1104,7 @@ begin
   Result:=CurClassName+' = '+Result;
 end;
 
-function TBaseWebIDLToPas.GetTypeName(const aTypeName: String; ForTypeDef: Boolean
+function TBaseWebIDLToPas.GetPascalTypeName(const aTypeName: String; ForTypeDef: Boolean
   ): String;
 Var
   A: UTF8String;
@@ -1230,7 +1236,7 @@ begin
     S:=S+(D as TIDLTypeDefDefinition).TypeName;
     end;
   Comment('Union of '+S);
-  AddLn(GetName(aDef)+' = '+GetTypeName('any')+';');
+  AddLn(GetName(aDef)+' = '+GetPascalTypeName('any')+';');
 end;
 
 
@@ -1340,7 +1346,7 @@ function TBaseWebIDLToPas.WriteTypeDefsAndCallbacks(aList: TIDLDefinitionList):
 Var
   D: TIDLDefinition;
   TD: TIDLTypeDefDefinition absolute D;
-  FD: TIDLFunctionDefinition absolute D;
+  CD: TIDLCallbackDefinition absolute D;
 
 begin
   Result:=0;
@@ -1353,11 +1359,10 @@ begin
         if WriteTypeDef(TD)  then
           Inc(Result);
       end
-    else if D is TIDLFunctionDefinition then
+    else if D is TIDLCallbackDefinition then
       begin
-      if (foCallBack in FD.Options) then
         if ConvertDef(D) then
-          if WriteFunctionTypeDefinition(FD) then
+          if WriteFunctionTypeDefinition(CD.FunctionDef) then
            Inc(Result);
       end;
     end;
@@ -1405,6 +1410,7 @@ begin
     ArgName:=ArgName+': '+ArgTypeName;
     //writeln('TBaseWebIDLToPas.GetArguments Arg="',ArgName,'" A.ArgumentType.TypeName=',Arg.ArgumentType.TypeName,' ',Def<>nil);
     if (ArgType is TIDLFunctionDefinition)
+        or (ArgType is TIDLCallBackDefinition)
         or (ArgType is TIDLDictionaryDefinition)
         or (ArgType is TIDLSequenceTypeDefDefinition)
         or (ArgResolvedTypeName='Variant')
@@ -1866,6 +1872,10 @@ end;
 
 function TBaseWebIDLToPas.AllocatePasName(D: TIDLDefinition; ParentName: String): TPasData;
 
+{
+  Here we make sure every definition for which code will be generated has a pascal (type) name.
+}
+
 Var
   CN: String;
   aData: TPasData;
@@ -1941,6 +1951,16 @@ begin
     D.Data:=Result;
     AllocatePasNames((D as TIDLUnionTypeDefDefinition).Union,D.Name)
     end
+  else if D Is TIDLCallBackDefinition then
+    begin
+    if CN='' then
+      CN:=ParentName+'Type';
+    CN:=TypePrefix+CN;
+    AddJSIdentifier(D);
+    Result:=CreatePasData(CN,D,true);
+    D.Data:=Result;
+    AllocatePasName(TIDLCallBackDefinition(D).FunctionDef,D.Name)
+    end
   else
     begin
     if (D is TIDLTypeDefDefinition)
@@ -2013,23 +2033,36 @@ begin
 end;
 
 procedure TBaseWebIDLToPas.ResolveTypeDef(D: TIDLDefinition);
+{
+  Here we make sure every type name is resolved to
+  - Either a Javascript base type
+  - a TIDLTypeDefinition instance.
+  In the latter case the resulting resolved TIDLTypeDefinition instance is stored in the Resolved field of a TPasData() element.
+
+  Conceivably, we can create type defs for all base types, so every type results in a TIDLTypeDefinition,
+  regardless of whether it is a base type or not.
+}
 
   procedure ResolveTypeName(const aTypeName: string);
   var
     Def: TIDLDefinition;
     Data: TPasData;
+
   begin
     if (D.Data is TPasData) and (TPasData(D.Data).Resolved<>nil) then
       exit;
 
     Def:=FindGlobalDef(aTypeName);
-    //writeln('ResolveTypeName Searched D=',D.Name,':',D.ClassName,' aTypeName="',aTypeName,'" Def=',Def<>nil);
     if Def=nil then
       begin
       if (NameToWebIDLBaseType(aTypeName)=wibtNone)
           and (TypeAliases.Values[aTypeName]='') then
         raise EConvertError.Create('[20220725172231] type "'+aTypeName+'" of "'+D.Name+'" not found at '+GetDefPos(D));
       end
+    else if not (Def is TIDLTypeDefinition) then
+      begin
+      raise EConvertError.Create('[20220725172231] type "'+D.ClassName+'" of "'+D.Name+'" is not a type at '+GetDefPos(D));
+      end
     else
       begin
       Data:=TPasData(D.Data);
@@ -2038,7 +2071,7 @@ procedure TBaseWebIDLToPas.ResolveTypeDef(D: TIDLDefinition);
         Data:=CreatePasData('',D,false);
         D.Data:=Data;
         end;
-      Data.Resolved:=Def;
+      Data.Resolved:=Def as TIDLTypeDefinition;
       //writeln('ResolveTypeName Resolved D=',D.Name,':',D.ClassName,' at ',GetDefPos(D),' Data.Resolved=',Def.Name,':',Def.ClassName,' at ',GetDefPos(Def));
       end;
   end;
@@ -2052,7 +2085,7 @@ begin
   if D=nil then exit;
   if not ConvertDef(D) then
     exit;
-  //writeln('TBaseWebIDLToPas.ResolveTypeDef START ',D.Name,':',D.ClassName,' at ',GetDefPos(D),' D=',hexstr(ptruint(D),sizeof(ptruint)*2));
+  // writeln('TBaseWebIDLToPas.ResolveTypeDef START ',D.Name,':',D.ClassName,' at ',GetDefPos(D),' D=',hexstr(ptruint(D),sizeof(ptruint)*2));
   if D Is TIDLInterfaceDefinition then
     ResolveTypeDefs(TIDLInterfaceDefinition(D).Members)
   else if D Is TIDLNamespaceDefinition then
@@ -2100,6 +2133,8 @@ begin
     end
   else if D is TIDLEnumDefinition then
     //
+  else if D is TIDLCallBackDefinition then
+    ResolveTypeDef(TIDLCallBackDefinition(D).FunctionDef)
   else if D is TIDLSetlikeDefinition then
     ResolveTypeDef(TIDLSetlikeDefinition(D).ElementType)
   else if D is TIDLImplementsOrIncludesDefinition then

+ 4 - 4
packages/webidl/src/webidltopas2js.pp

@@ -52,7 +52,7 @@ type
     Function BaseUnits: String; override;
     // Auxiliary routines
     procedure GetOptions(L: TStrings; Full: boolean); override;
-    function GetTypeName(const aTypeName: String; ForTypeDef: Boolean=False
+    function GetPascalTypeName(const aTypeName: String; ForTypeDef: Boolean=False
       ): String; override;
     function GetInterfaceDefHead(Intf: TIDLInterfaceDefinition): String;
       override;
@@ -115,7 +115,7 @@ begin
   L.Add('Extended Options: '+Pas2jsConversionOptionsToStr(Pas2jsOptions));
 end;
 
-function TWebIDLToPas2js.GetTypeName(const aTypeName: String;
+function TWebIDLToPas2js.GetPascalTypeName(const aTypeName: String;
   ForTypeDef: Boolean): String;
 
   Function UsePascalType(Const aPascalType: string): String;
@@ -146,7 +146,7 @@ begin
     'USVString',
     'ByteString': Result:=UsePascalType('String');
   else
-    Result:=inherited GetTypeName(aTypeName,ForTypeDef);
+    Result:=inherited GetPascalTypeName(aTypeName,ForTypeDef);
   end;
 end;
 
@@ -159,7 +159,7 @@ begin
   if Assigned(Intf.ParentInterface) then
     aParentName:=GetName(Intf.ParentInterface)
   else
-    aParentName:=GetTypeName(Intf.ParentName);
+    aParentName:=GetPascalTypeName(Intf.ParentName);
   if aParentName<>'' then
     Result:=Result+' ('+aParentName+')';
 end;

+ 34 - 32
packages/webidl/src/webidltowasmjob.pp

@@ -84,18 +84,15 @@ type
   Protected
     function BaseUnits: String; override;
     // Auxiliary routines
-    function GetPasClassName(const aName: String): String; overload; // convert to PasInterfacePrefix+X+FPasInterfaceSuffix
-      override;
+    function GetPasClassName(const aName: String): String; overload; override; // convert to PasInterfacePrefix+X+FPasInterfaceSuffix
     function IntfToPasClassName(const aName: TIDLString): TIDLString; virtual;
     function ComputeGUID(const Prefix: TIDLString; aList: TIDLDefinitionList): TIDLString; virtual;
     procedure GetOptions(L: TStrings; Full: boolean); override;
-    function GetTypeName(const aTypeName: String; ForTypeDef: Boolean=False): String; override;
+    function GetPascalTypeName(const aTypeName: String; ForTypeDef: Boolean=False): String; override;
     function GetPasIntfName(Intf: TIDLDefinition): TIDLString;
-    function GetResolvedType(aDef: TIDLTypeDefDefinition; out aTypeName,
-      aResolvedTypename: String): TIDLDefinition; overload; override;
+    function GetResolvedType(aDef: TIDLTypeDefDefinition; out aTypeName, aResolvedTypename: String): TIDLTypeDefinition; overload; override;
 {$IF SIZEOF(CHAR)=1}      
-    function GetResolvedType(aDef: TIDLTypeDefDefinition; out aTypeName,
-      aResolvedTypename: TIDLString): TIDLDefinition; overload; 
+    function GetResolvedType(aDef: TIDLTypeDefDefinition; out aTypeName, aResolvedTypename: TIDLString): TIDLDefinition; overload;
 {$ENDIF}      
     function GetInterfaceDefHead(Intf: TIDLInterfaceDefinition): String; override;
     function GetNamespaceDefHead(aNamespace: TIDLNamespaceDefinition): String; override;
@@ -291,7 +288,7 @@ begin
   inherited GetOptions(L, Full);
 end;
 
-function TWebIDLToPasWasmJob.GetTypeName(const aTypeName: String;
+function TWebIDLToPasWasmJob.GetPascalTypeName(const aTypeName: String;
   ForTypeDef: Boolean): String;
 begin
   Case aTypeName of
@@ -300,7 +297,7 @@ begin
     'void','undefined': Result:=aTypeName;
   else
     //writeln('TWebIDLToPasWasmJob.GetTypeName ',aTypeName,' ',Def<>nil);
-    Result:=inherited GetTypeName(aTypeName,ForTypeDef);
+    Result:=inherited GetPascalTypeName(aTypeName,ForTypeDef);
     if (Result=aTypeName)
     and (LeftStr(Result,length(PasInterfacePrefix))<>PasInterfacePrefix)
     and (RightStr(Result,length(PasInterfaceSuffix))<>PasInterfaceSuffix)
@@ -336,7 +333,7 @@ end;
 {$ENDIF}
 
 function TWebIDLToPasWasmJob.GetResolvedType(aDef: TIDLTypeDefDefinition; out
-  aTypeName, aResolvedTypename: String): TIDLDefinition;
+  aTypeName, aResolvedTypename: String): TIDLTypeDefinition;
 begin
   Result:=inherited GetResolvedType(aDef, aTypeName, aResolvedTypename);
   if Result is TIDLInterfaceDefinition then
@@ -354,7 +351,7 @@ begin
   if Assigned(Intf.ParentInterface) then
     aParentName:=GetName(Intf.ParentInterface)
   else
-    aParentName:=GetTypeName(Intf.ParentName);
+    aParentName:=GetPascalTypeName(Intf.ParentName);
   if aParentName='' then
     aParentName:=ClassPrefix+'Object'+ClassSuffix;
   if aParentName<>'' then
@@ -400,7 +397,7 @@ begin
       if Assigned(iIntf.ParentInterface) then
         ParentName:=GetPasIntfName(iIntf.ParentInterface as TIDLInterfaceDefinition)
       else
-        ParentName:=GetTypeName(Intf.ParentName);
+        ParentName:=GetPascalTypeName(Intf.ParentName);
     if ParentName='' then
       ParentName:=PasInterfacePrefix+'Object'+PasInterfaceSuffix;
     if ParentName<>'' then
@@ -805,11 +802,13 @@ begin
             Args:=Args+',';
           ArgName:=GetArgName(ArgDef);
           ArgType:=GetResolvedType(ArgDef.ArgumentType,ArgTypeName,ArgResolvedTypeName);
-          if (ArgType is TIDLFunctionDefinition) and (foCallBack in TIDLFunctionDefinition(ArgType).Options) then
+          if (ArgType is TIDLCallbackDefinition)  then
             begin
+            if not (Assigned(TIDLCallbackDefinition(ArgType).FunctionDef)) then
+              Raise EWebIDLParser.Create('[20220725181726] callback definition in '+GetName(aDef)+'without function signature type '+GetDefPos(ArgType));
             LocalName:=CreateLocal('m');
             VarSection:=Concat(VarSection,[ (LocalName+': '+JOB_JSValueTypeNames[jivkMethod]+';')]);
-            WrapperFn:='JOBCall'+GetName(TIDLFunctionDefinition(ArgType));
+            WrapperFn:='JOBCall'+GetName(TIDLCallbackDefinition(ArgType).FunctionDef);
             TryCode:=Concat(TryCode,[LocalName+':='+JOB_JSValueTypeNames[jivkMethod]+'.Create(TMethod('+ArgName+'),@'+WrapperFn+');']);
             FinallyCode:=Concat(FinallyCode,[LocalName+'.free;']);
             ArgName:=LocalName;
@@ -947,16 +946,13 @@ procedure TWebIDLToPasWasmJob.WriteTypeDefsAndCallbackImplementations(aList: TID
 
 Var
   D: TIDLDefinition;
-  FD: TIDLFunctionDefinition absolute D;
+  CD: TIDLCallbackDefinition absolute D;
 
 begin
   for D in aList do
-    if D is TIDLFunctionDefinition then
-      begin
-      if (foCallBack in FD.Options) then
-        if ConvertDef(FD) then
-          WriteFunctionTypeCallback(FD);
-      end;
+    if D is TIDLCallbackDefinition then
+      if ConvertDef(D) then
+        WriteFunctionTypeCallback(CD.FunctionDef);
 end;
 
 
@@ -970,11 +966,13 @@ var
   ArgName, ArgTypeName, ArgResolvedTypename: TIDLString;
   Params, Call, GetFunc: TIDLString;
   FetchArgs, VarSection : Array of string;
+  Msg : String;
   Args: TIDLDefinitionList;
   ArgDef: TIDLArgumentDefinition;
   ArgNames: TStringList;
   j, i: Integer;
   ReturnDef, ArgType: TIDLDefinition;
+
 begin
   FuncName:=GetName(aDef);
 
@@ -1032,13 +1030,15 @@ begin
       'Variant': GetFunc:='GetVariant';
       'TJOB_JSValue': GetFunc:='GetValue';
       else
-        if ArgType is TIDLInterfaceDefinition then
+        if (ArgType is TIDLInterfaceDefinition) or (ArgType is TIDLDictionaryDefinition) then
           GetFunc:='GetObject('+GetName(ArgType)+') as '+ArgTypeName
         else
           begin
           if ArgType<>nil then
-            writeln('TWebIDLToPasWasmJob.WriteFunctionTypeCallBack ArgType=',ArgType.ClassName);
-          raise EWebIDLParser.Create('[20220725181732] not yet supported: function type arg['+IntToStr(I)+'] type '+ArgDef.ArgumentType.TypeName+' at '+GetDefPos(ArgDef));
+            Msg:=Format('%s (%s)',[ArgDef.ArgumentType.TypeName,ArgType.ClassName])
+          else
+            Msg:='No type';
+          raise EWebIDLParser.Create('[20220725181732] not yet supported: function type arg['+IntToStr(I)+'] type '+Msg+' at '+GetDefPos(ArgDef));
           end;
       end;
 
@@ -1630,10 +1630,11 @@ begin
       begin
       aDef:=Context.Definitions[i];
       if aDef is TIDLNamespaceDefinition then
-        begin
-        PasVarName:=Context.Definitions[i].Name;
-        AddLn(PasVarName+':='+GetName(aDef)+'.JOBCreateGlobal('''+PasVarName+''');');
-        end;
+        if not TIDLNamespaceDefinition(aDef).IsPartial then
+          begin
+          PasVarName:=Context.Definitions[i].Name;
+          AddLn(PasVarName+':='+GetName(aDef)+'.JOBCreateGlobal('''+PasVarName+''');');
+          end;
       end;
     Undent;
 
@@ -1648,10 +1649,11 @@ begin
       begin
       aDef:=Context.Definitions[i];
       if aDef is TIDLNamespaceDefinition then
-        begin
-        PasVarName:=Context.Definitions[i].Name;
-        AddLn(PasVarName+':=Nil;');
-        end;
+        if not TIDLNamespaceDefinition(aDef).IsPartial then
+          begin
+          PasVarName:=Context.Definitions[i].Name;
+          AddLn(PasVarName+':=Nil;');
+          end;
       end;
     Undent;
     end;

+ 5 - 3
packages/webidl/tests/tcidlparser.pp

@@ -306,7 +306,8 @@ Type
 
   TTestFunctionCallbackParser = Class(TTestParser)
   private
-    FFunction: TIDLFunctionDefinition;
+    FCallBack: TIDLCallbackDefinition;
+    FFunction : TIDLFunctionDefinition;
     FIsConstructor : Boolean;
   Public
     Procedure Setup; override;
@@ -924,8 +925,9 @@ begin
   Src:=Src+');'+sLineBreak;
   InitSource(Src);
   Parser.Parse;
-  AssertEquals('Correct class',TIDLFunctionDefinition,Definitions[0].ClassType);
-  Result:=Definitions[0] as TIDLFunctionDefinition;
+  AssertEquals('Correct class',TIDLCallbackDefinition,Definitions[0].ClassType);
+  Result:=(Definitions[0] as TIDLCallbackDefinition).FunctionDef;
+  AssertNotNull('Have callback function definition',Result);
   AssertEquals('Name',AName,Result.Name);
   AssertNotNull('Have return type',Result.ReturnType);
   AssertEquals('Return type name',aReturnType,Result.ReturnType.TypeName);