Explorar o código

* Fix callback interface treatment

Michaël Van Canneyt hai 1 ano
pai
achega
328ff5f0c3

+ 7 - 0
packages/webidl/src/webidldefs.pp

@@ -224,6 +224,7 @@ type
     Function Add(aClass : TIDLDefinitionClass; Const AName : UTF8String; const aFile: string; aLine, aCol: integer) : TIDLDefinition; override;
     Function Add(aClass : TIDLDefinitionClass; Const AName : UTF8String; const aFile: string; aLine, aCol: integer) : TIDLDefinition; override;
     Function Add(aItem : TIDLDefinition) : Integer;
     Function Add(aItem : TIDLDefinition) : Integer;
     Function Delete(aItem : TIDLDefinition) : boolean; // true if found and deleted
     Function Delete(aItem : TIDLDefinition) : boolean; // true if found and deleted
+    Function Extract(aItem : TIDLDefinition) : TIDLDefinition;
     Function IndexOfName(aName : UTF8String) : Integer;
     Function IndexOfName(aName : UTF8String) : Integer;
     Function HasName(aName : UTF8String) : Boolean;
     Function HasName(aName : UTF8String) : Boolean;
     function GetEnumerator: TIDLDefinitionEnumerator;
     function GetEnumerator: TIDLDefinitionEnumerator;
@@ -1474,6 +1475,12 @@ begin
   Result:=false;
   Result:=false;
 end;
 end;
 
 
+function TIDLDefinitionList.Extract(aItem: TIDLDefinition): TIDLDefinition;
+
+begin
+  Result:=TIDLDefinition(FList.Extract(aItem));
+end;
+
 function TIDLDefinitionList.IndexOfName(aName: UTF8String): Integer;
 function TIDLDefinitionList.IndexOfName(aName: UTF8String): Integer;
 begin
 begin
   Result:=Count-1;
   Result:=Count-1;

+ 32 - 0
packages/webidl/src/webidlparser.pp

@@ -51,6 +51,7 @@ Type
     function FindDictionary(aName: UTF8String): TIDLDictionaryDefinition; virtual;
     function FindDictionary(aName: UTF8String): TIDLDictionaryDefinition; virtual;
     function FindInterface(aName: UTF8String): TIDLInterfaceDefinition; virtual;
     function FindInterface(aName: UTF8String): TIDLInterfaceDefinition; virtual;
     function FindNamespace(aName: UTF8String): TIDLNamespaceDefinition; virtual;
     function FindNamespace(aName: UTF8String): TIDLNamespaceDefinition; virtual;
+
     procedure AppendDictionaryPartials; virtual;
     procedure AppendDictionaryPartials; virtual;
     procedure AppendInterfacePartials; virtual;
     procedure AppendInterfacePartials; virtual;
     procedure AppendInterfaceIncludes; virtual;
     procedure AppendInterfaceIncludes; virtual;
@@ -63,6 +64,8 @@ Type
     Procedure AppendIncludes; virtual;
     Procedure AppendIncludes; virtual;
     Function GetInterfacesTopologically: TIDLDefinitionList; virtual;
     Function GetInterfacesTopologically: TIDLDefinitionList; virtual;
     Procedure ResolveTypes; virtual;
     Procedure ResolveTypes; virtual;
+    procedure ResolveCallbackInterfaces; virtual;
+    function CreateCallBackFromInterface(aDef: TIDLInterfaceDefinition): TIDLCallBackDefinition;
     function GetDefPos(Def: TIDLBaseObject; WithoutFile: boolean = false): string; virtual;
     function GetDefPos(Def: TIDLBaseObject; WithoutFile: boolean = false): string; virtual;
     function IndexOfDefinition(const AName: String): Integer;
     function IndexOfDefinition(const AName: String): Integer;
     Function FindDefinition(const AName : String) : TIDLDefinition;
     Function FindDefinition(const AName : String) : TIDLDefinition;
@@ -2016,8 +2019,37 @@ begin
         DD.ParentDictionary:=FindDictionary(DD.ParentName);
         DD.ParentDictionary:=FindDictionary(DD.ParentName);
 end;
 end;
 
 
+Function TWebIDLContext.CreateCallBackFromInterface(aDef : TIDLInterfaceDefinition) : TIDLCallBackDefinition;
+
+begin
+  if (aDef.Members.Count<>1)  then
+    Raise EWebIDLParser.CreateFmt('Callback Interface %s has wrong member count',[aDef.Name]);
+  if (aDef.Member[0] is TIDLFunctionDefinition) then
+    Raise EWebIDLParser.CreateFmt('Callback Interface %s member %s is not a function',[aDef.Name,aDef.Members[0].Name]);
+  Result:=TIDLCallBackDefinition(FDefinitions.Add(TIDLCallBackDefinition,aDef.Name,aDef.SrcFile,aDef.Line,aDef.Column));
+  Result.FunctionDef:=TIDLFunctionDefinition(aDef.Members.Extract(aDef.Member[0]));
+end;
+
+procedure TWebIDLContext.ResolveCallbackInterfaces;
+
+var
+  D : TIDLDefinition;
+  DI : TIDLInterfaceDefinition absolute D;
+
+begin
+  For D In FDefinitions do
+    if (D is TIDLInterfaceDefinition) and DI.IsCallBack then
+      begin
+      CreateCallBackFromInterface(DI);
+      FDefinitions.Delete(D);
+      FreeAndNil(FHash);
+      end;
+
+end;
+
 procedure TWebIDLContext.ResolveTypes;
 procedure TWebIDLContext.ResolveTypes;
 begin
 begin
+  ResolveCallbackInterfaces;
   ResolveParentTypes;
   ResolveParentTypes;
 end;
 end;
 
 

+ 45 - 1
packages/webidl/src/webidltopas.pp

@@ -148,6 +148,8 @@ type
     FTypeAliases: TStrings; // user defined type maping name to name
     FTypeAliases: TStrings; // user defined type maping name to name
     FVerbose: Boolean;
     FVerbose: Boolean;
     FWebIDLVersion: TWebIDLVersion;
     FWebIDLVersion: TWebIDLVersion;
+    function CreateCallBackFromInterface(aDef: TIDLInterfaceDefinition): TIDLCallBackDefinition;
+    procedure ResolveCallbackInterfaces;
     procedure SetGlobalVars(const AValue: TStrings);
     procedure SetGlobalVars(const AValue: TStrings);
     procedure SetIncludeImplementationCode(AValue: TStrings);
     procedure SetIncludeImplementationCode(AValue: TStrings);
     procedure SetIncludeInterfaceCode(AValue: TStrings);
     procedure SetIncludeInterfaceCode(AValue: TStrings);
@@ -3026,21 +3028,63 @@ begin
     AllocatePasName(D,ParentName,True);
     AllocatePasName(D,ParentName,True);
 end;
 end;
 
 
+
+Function TBaseWebIDLToPas.CreateCallBackFromInterface(aDef : TIDLInterfaceDefinition) : TIDLCallBackDefinition;
+
+var
+  I,Idx,Count : Integer;
+
+begin
+  DoLog('Converting callback interface %s to callback',[aDef.Name]);
+  Count:=0;
+  For I:=0 to aDef.Members.Count-1 do
+    if (aDef.Member[I] is TIDLFunctionDefinition) then
+      begin
+      Idx:=I;
+      Inc(Count);
+      end;
+  if (Count<>1)  then
+    Raise EWebIDLParser.CreateFmt('Callback Interface %s has wrong function member count',[aDef.Name]);
+  if not (aDef.Member[Idx] is TIDLFunctionDefinition) then
+    Raise EWebIDLParser.CreateFmt('Callback Interface %s member %s is not a function',[aDef.Name,aDef.Members[Idx].Name]);
+  Result:=TIDLCallBackDefinition(FContext.Add(TIDLCallBackDefinition,aDef.Name,aDef.SrcFile,aDef.Line,aDef.Column));
+  Result.FunctionDef:=TIDLFunctionDefinition(aDef.Members.Extract(aDef.Member[Idx]));
+  Result.FunctionDef.Name:=Result.Name;
+end;
+
+procedure TBaseWebIDLToPas.ResolveCallbackInterfaces;
+
+var
+  D : TIDLDefinition;
+  DI : TIDLInterfaceDefinition absolute D;
+
+begin
+  For D In FContext.Definitions do
+    if (D is TIDLInterfaceDefinition) and DI.IsCallBack then
+      begin
+      CreateCallBackFromInterface(DI);
+      FContext.Definitions.Delete(D);
+      end;
+
+end;
+
 procedure TBaseWebIDLToPas.ProcessDefinitions;
 procedure TBaseWebIDLToPas.ProcessDefinitions;
 
 
 var
 var
   D : TIDLDefinition;
   D : TIDLDefinition;
 
 
 begin
 begin
+  ResolveCallbackInterfaces;
   RemoveInterfaceForwards(FContext.Definitions);
   RemoveInterfaceForwards(FContext.Definitions);
   FContext.AppendPartials;
   FContext.AppendPartials;
   FContext.AppendIncludes;
   FContext.AppendIncludes;
   For D in FContext.Definitions do
   For D in FContext.Definitions do
     if D.Name<>'' then
     if D.Name<>'' then
-      AddGlobalJSIdentifier(D);
+    AddGlobalJSIdentifier(D);
   AllocatePasNames(FContext.Definitions);
   AllocatePasNames(FContext.Definitions);
   ResolveParentInterfaces(FContext.Definitions);
   ResolveParentInterfaces(FContext.Definitions);
   ResolveTypeDefs(FContext.Definitions);
   ResolveTypeDefs(FContext.Definitions);
+
 end;
 end;
 
 
 procedure TBaseWebIDLToPas.Execute;
 procedure TBaseWebIDLToPas.Execute;