瀏覽代碼

webidl: remove empty forward interfaces

mattias 3 年之前
父節點
當前提交
99f34158ca
共有 3 個文件被更改,包括 75 次插入8 次删除
  1. 16 0
      packages/webidl/src/webidldefs.pp
  2. 7 6
      packages/webidl/src/webidlparser.pp
  3. 52 2
      packages/webidl/src/webidltopas.pp

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

@@ -203,6 +203,7 @@ type
     Function AsString(Full : Boolean): UTF8String; override;
     Function Add(aClass : TIDLDefinitionClass; Const AName : UTF8String; const aFile: string; aLine, aCol: integer) : TIDLDefinition; override;
     Function Add(aItem : TIDLDefinition) : Integer;
+    Function Delete(aItem : TIDLDefinition) : boolean; // true if found and deleted
     function GetEnumerator: TIDLDefinitionEnumerator;
     Property Parent : TIDLDefinition Read FParent;
     Property Definitions[aIndex : Integer] : TIDLDefinition Read GetD;default;
@@ -283,6 +284,7 @@ type
   private
     FHasSerializer: Boolean;
     FHasStringifier: Boolean;
+    FIsForward: Boolean;
     FIsInclude: Boolean;
     FIsMixin: Boolean;
     FParentInterface: TIDLInterfaceDefinition;
@@ -294,6 +296,7 @@ type
     // is this a mixin definition?
     Property IsMixin : Boolean Read FIsMixin Write FIsMixin;
     Property IsInclude : Boolean Read FIsInclude Write FIsInclude;
+    Property IsForward: Boolean read FIsForward write FIsForward;
   end;
 
   { TIDLArgumentDefinition }
@@ -1323,6 +1326,19 @@ begin
     aItem.Parent:=FParent;
 end;
 
+function TIDLDefinitionList.Delete(aItem: TIDLDefinition): boolean;
+var
+  i: Integer;
+begin
+  for i:=0 to FList.Count-1 do
+    if FList[i]=aItem then
+      begin
+      FList.Delete(i);
+      exit(true);
+      end;
+  Result:=false;
+end;
+
 function TIDLDefinitionList.GetEnumerator: TIDLDefinitionEnumerator;
 begin
   Result:=TIDLDefinitionEnumerator.Create(Self);

+ 7 - 6
packages/webidl/src/webidlparser.pp

@@ -889,7 +889,7 @@ end;
 
 function TWebIDLParser.ParseInterface(aParent : TIDLBaseObject): TIDLInterfaceDefinition;
 (*
-  On Entry we're on interface. On exit, we're on the } character
+  On Entry we're on interface. On exit, we're on the } character or the ; if it is an empty forward definition
 *)
 
 Var
@@ -909,17 +909,18 @@ begin
   try
     Result.IsMixin:=IsMixin;
     tk:=GetToken;
+    if tk=tkSemiColon then
+      begin
+      // empty interface
+      Result.IsForward:=true;
+      exit;
+      end;
     if tk=tkColon then
       begin
       ExpectToken(tkIdentifier);
       Result.ParentName:=CurrentTokenString;
       tk:=GetToken;
       end;
-    if CurrentToken=tkSemiColon then
-      begin
-      // empty interface
-      exit;
-      end;
     CheckCurrentToken(tkCurlyBraceOpen);
     tk:=GetToken;
     While (tk<>tkCurlyBraceClose) do

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

@@ -99,6 +99,7 @@ type
     procedure AddJSIdentifier(D: TIDLDefinition); virtual;
     procedure ResolveTypeDefs(aList: TIDLDefinitionList); virtual;
     procedure ResolveTypeDef(D: TIDLDefinition); virtual;
+    procedure RemoveInterfaceForwards(aList: TIDLDefinitionList); virtual;
     function FindGlobalDef(const aName: UTF8String): TIDLDefinition; virtual;
     function GetDefPos(Def: TIDLBaseObject; WithoutFile: boolean = false): string; virtual;
     function GetPasDataPos(D: TPasData; WithoutFile: boolean = false): string; virtual;
@@ -561,7 +562,6 @@ Var
 
 var
   D: TIDLDefinition;
-
 begin
   L:=TFPObjectHashTable.Create(False);
   try
@@ -1467,7 +1467,7 @@ begin
     begin
     Old:=FindGlobalDef(D.Name);
     if Old<>nil then
-      raise EWebIDLParser.Create('Duplicate identifier '+D.Name+' at '+GetDefPos(D)+' and '+GetDefPos(Old));
+      raise EWebIDLParser.Create('Duplicate identifier '+D.Name+' at '+GetDefPos(D)+' and '+GetDefPos(Old)+' (20220718185400)');
     FGlobalDefs.Add(D.Name,D);
     end
   else
@@ -1551,6 +1551,55 @@ begin
     writeln('TBaseWebIDLToPas.ResolveTypeDef unknown ',D.Name,':',D.ClassName,' at ',GetDefPos(D));
 end;
 
+procedure TBaseWebIDLToPas.RemoveInterfaceForwards(aList: TIDLDefinitionList);
+
+Var
+  L: TFPObjectHashTable;
+
+  Procedure DeleteIntf(Def: TIDLInterfaceDefinition);
+  begin
+    writeln('DeleteIntf ',Def.Name);
+    aList.Delete(Def);
+  end;
+
+  Procedure CheckDuplicateInterfaceDef(Def: TIDLInterfaceDefinition);
+  var
+    aName: UTF8String;
+    OldDef: TIDLInterfaceDefinition;
+  begin
+    if Def.IsPartial then exit;
+    aName:=Def.Name;
+    OldDef:=TIDLInterfaceDefinition(L.Items[aName]);
+    if OldDef=nil then
+      L.add(aName,Def)
+    else
+      begin
+      if OldDef.IsForward then
+        begin
+        L.Delete(OldDef.Name);
+        DeleteIntf(OldDef);
+        L.Add(aName,Def);
+        end
+      else if Def.IsForward then
+        DeleteIntf(Def)
+      else
+        raise EConvertError.Create('Duplicate interface '+GetDefPos(Def)+' and '+GetDefPos(OldDef)+' (20220718184717)');
+      end;
+  end;
+
+var
+  i: Integer;
+begin
+  L:=TFPObjectHashTable.Create(False);
+  try
+    For i:=aList.Count-1 downto 0 do
+      if (aList[i] is TIDLInterfaceDefinition) then
+        CheckDuplicateInterfaceDef(TIDLInterfaceDefinition(aList[i]));
+  finally
+    L.Free;
+  end;
+end;
+
 function TBaseWebIDLToPas.FindGlobalDef(const aName: UTF8String
   ): TIDLDefinition;
 begin
@@ -1604,6 +1653,7 @@ end;
 procedure TBaseWebIDLToPas.ProcessDefinitions;
 
 begin
+  RemoveInterfaceForwards(FContext.Definitions);
   FContext.AppendPartials;
   FContext.AppendIncludes;
   AllocatePasNames(FContext.Definitions);