Browse Source

* Support for namespaces

Michaël Van Canneyt 1 year ago
parent
commit
1933127d41

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

@@ -314,6 +314,13 @@ type
     Property IsForward: Boolean read FIsForward write FIsForward;
     Property IsForward: Boolean read FIsForward write FIsForward;
   end;
   end;
 
 
+  { TIDLNamespaceDefinition }
+
+  TIDLNamespaceDefinition = class(TIDLStructuredDefinition)
+  Public
+    Function AsString (aFull : Boolean) : UTF8String; override;
+  end;
+
   { TIDLArgumentDefinition }
   { TIDLArgumentDefinition }
 
 
   TIDLArgumentDefinition = Class(TIDLDefinition)
   TIDLArgumentDefinition = Class(TIDLDefinition)
@@ -722,6 +729,22 @@ begin
     Result:=Attributes.AsString(true)+' '+Result;
     Result:=Attributes.AsString(true)+' '+Result;
 end;
 end;
 
 
+{ TIDLNamespaceDefinition }
+
+function TIDLNamespaceDefinition.AsString(aFull: Boolean): UTF8String;
+
+begin
+  Result:='namespace '+Name;
+  if IsPartial then
+    Result:='partial '+Result;
+  if Not HasMembers then
+    Result:=Result+' {'+sLineBreak+'}'
+  else
+    Result:=Result+' '+Members.AsString(true);
+  if aFull and HasAttributes then
+    Result:=Attributes.AsString(true)+' '+Result;
+end;
+
 { TIDLTypeDefDefinition }
 { TIDLTypeDefDefinition }
 
 
 function TIDLTypeDefDefinition.Clone(aParent: TIDLDefinition): TIDLTypeDefDefinition;
 function TIDLTypeDefDefinition.Clone(aParent: TIDLDefinition): TIDLTypeDefDefinition;

+ 148 - 14
packages/webidl/src/webidlparser.pp

@@ -39,15 +39,20 @@ Type
 
 
   TWebIDLContext = Class (TIDLBaseObject)
   TWebIDLContext = Class (TIDLBaseObject)
   private
   private
+    Type TCalcBool = (cbCalc,cbFalse,cbTrue);
+  private
+    FHaveNameSpaces : TCalcBool;
     FAliases: TStrings;
     FAliases: TStrings;
     FDefinitions: TIDLDefinitionList;
     FDefinitions: TIDLDefinitionList;
     FHash : TFPObjectHashTable;
     FHash : TFPObjectHashTable;
   Protected
   Protected
     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;
     procedure AppendDictionaryPartials; virtual;
     procedure AppendDictionaryPartials; virtual;
     procedure AppendInterfacePartials; virtual;
     procedure AppendInterfacePartials; virtual;
     procedure AppendInterfaceIncludes; virtual;
     procedure AppendInterfaceIncludes; virtual;
+    procedure AppendNamespacePartials; virtual;
     procedure ResolveParentTypes; virtual;
     procedure ResolveParentTypes; virtual;
   Public
   Public
     Constructor Create(OwnsDefinitions : Boolean = True);
     Constructor Create(OwnsDefinitions : Boolean = True);
@@ -62,6 +67,7 @@ Type
     Function AsString(Full: Boolean): UTF8String; override;
     Function AsString(Full: Boolean): UTF8String; override;
     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(aParent : TIDLBaseObject; aClass : TIDLDefinitionClass; const AName : UTF8String; const aFile: string; aLine, aCol: integer) : TIDLDefinition; virtual;
     Function Add(aParent : TIDLBaseObject; aClass : TIDLDefinitionClass; const AName : UTF8String; const aFile: string; aLine, aCol: integer) : TIDLDefinition; virtual;
+    Function HaveNamespaces : boolean;
     Property Definitions : TIDLDefinitionList Read FDefinitions;
     Property Definitions : TIDLDefinitionList Read FDefinitions;
     Property Aliases : TStrings Read FAliases Write FAliases;
     Property Aliases : TStrings Read FAliases Write FAliases;
   end;
   end;
@@ -116,11 +122,12 @@ Type
     function ParseConst(aParent: TIDLBaseObject ): TIDLConstDefinition; virtual;
     function ParseConst(aParent: TIDLBaseObject ): TIDLConstDefinition; virtual;
     function ParseCallBack(aParent : TIDLBaseObject): TIDLDefinition; virtual;
     function ParseCallBack(aParent : TIDLBaseObject): TIDLDefinition; virtual;
     function ParseStringifier(aParent : TIDLBaseObject): TIDLDefinition; virtual;
     function ParseStringifier(aParent : TIDLBaseObject): TIDLDefinition; virtual;
-    function ParseOperation(aParent: TIDLBaseObject): TIDLFunctionDefinition; virtual;
+    function ParseOperation(aParent: TIDLBaseObject; allowSpecials : Boolean = True): TIDLFunctionDefinition; virtual;
     function ParseSerializer(aParent: TIDLBaseObject): TIDLSerializerDefinition; virtual;
     function ParseSerializer(aParent: TIDLBaseObject): TIDLSerializerDefinition; virtual;
     function ParseStatic(aParent: TIDLBaseObject): TIDLDefinition;virtual;
     function ParseStatic(aParent: TIDLBaseObject): TIDLDefinition;virtual;
     function ParseIterable(aParent : TIDLBaseObject): TIDLIterableDefinition; virtual;
     function ParseIterable(aParent : TIDLBaseObject): TIDLIterableDefinition; virtual;
     function ParseInterface(aParent : TIDLBaseObject): TIDLInterfaceDefinition; virtual;
     function ParseInterface(aParent : TIDLBaseObject): TIDLInterfaceDefinition; virtual;
+    function ParseNamespace(aParent : TIDLBaseObject): TIDLNamespaceDefinition; virtual;
     function ParseDictionary(aParent : TIDLBaseObject; AllowInheritance : Boolean = True): TIDLDictionaryDefinition; virtual;
     function ParseDictionary(aParent : TIDLBaseObject; AllowInheritance : Boolean = True): TIDLDictionaryDefinition; virtual;
     function ParseEnum(aParent : TIDLBaseObject): TIDLEnumDefinition; virtual;
     function ParseEnum(aParent : TIDLBaseObject): TIDLEnumDefinition; virtual;
     function ParseTypeDef(aParent : TIDLBaseObject): TIDLTypeDefDefinition; virtual;
     function ParseTypeDef(aParent : TIDLBaseObject): TIDLTypeDefDefinition; virtual;
@@ -569,7 +576,7 @@ begin
     end;
     end;
 end;
 end;
 
 
-function TWebIDLParser.ParseOperation(aParent: TIDLBaseObject): TIDLFunctionDefinition;
+function TWebIDLParser.ParseOperation(aParent: TIDLBaseObject; allowSpecials : Boolean = True): TIDLFunctionDefinition;
 { On entry, we're on the type definition or on one of getter,setter,deleter,legacycaller,
 { On entry, we're on the type definition or on one of getter,setter,deleter,legacycaller,
   on exit, we're on the final ) }
   on exit, we're on the final ) }
 
 
@@ -586,18 +593,19 @@ Var
 
 
 begin
 begin
   Opts:=[];
   Opts:=[];
-  While CurrentToken in Specials do
-    begin
-    Case CurrentToken of
-      tkGetter : FO:=foGetter;
-      tkSetter : FO:=foSetter;
-      tkDeleter : FO:=foDeleter;
-      tkLegacyCaller : FO:=foLegacyCaller;
-      tkConstructor : fo:=foConstructor;
-    end;
-    Include(Opts,FO);
-    GetToken;
-    end;
+  if AllowSpecials then
+    While CurrentToken in Specials do
+      begin
+      Case CurrentToken of
+        tkGetter : FO:=foGetter;
+        tkSetter : FO:=foSetter;
+        tkDeleter : FO:=foDeleter;
+        tkLegacyCaller : FO:=foLegacyCaller;
+        tkConstructor : fo:=foConstructor;
+      end;
+      Include(Opts,FO);
+      GetToken;
+      end;
   Result:=TIDLFunctionDefinition(AddDefinition(aParent,TIDLFunctionDefinition,''));
   Result:=TIDLFunctionDefinition(AddDefinition(aParent,TIDLFunctionDefinition,''));
   ok:=false;
   ok:=false;
   try
   try
@@ -1111,12 +1119,82 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TWebIDLParser.ParseNamespace(aParent: TIDLBaseObject): TIDLNamespaceDefinition;
+(*
+  On Entry we're on interface. On exit, we're on the } character or the ; if it is an empty forward definition
+*)
+
+Var
+  tk : TIDLToken;
+  Attrs : TExtAttributeList;
+  M : TIDLDefinition;
+  SemicolonSeen , ok: Boolean;
+
+begin
+  Attrs:=nil;
+  ExpectToken(tkIdentifier);
+  Result:=TIDLNamespaceDefinition(AddDefinition(aParent,TIDLNamespaceDefinition,CurrentTokenString));
+  ok:=false;
+  try
+    tk:=GetToken;
+    if tk=tkSemiColon then
+      // empty interface
+      exit;
+    CheckCurrentToken(tkCurlyBraceOpen);
+    tk:=GetToken;
+    While not (tk in [tkCurlyBraceClose,tkEof]) do
+      begin
+      SemicolonSeen:=False;
+      Attrs:=nil;
+      M:=Nil;
+      if tk=tkSquaredBraceOpen then
+        begin
+        Attrs:=ParseExtAttributes;
+        tk:=GetToken;
+        end;
+      Case tk of
+        tkConst : M:=ParseConst(Result.Members);
+        tkReadOnly :
+          begin
+          ExpectToken(tkAttribute);
+          M:=ParseAttribute(Result.Members);
+          With TIDLAttributeDefinition(M) do
+            Options:=Options+[aoReadOnly];
+          end;
+        tkStatic : M:=ParseStatic(Result.Members);
+      else
+        {
+        tkGetter, tkSetter, tkDeleter, tkLegacyCaller
+        }
+        M:=ParseOperation(Result.Members);
+      end;
+      IF Assigned(M) then
+        begin
+        M.Attributes:=Attrs;
+        Attrs:=Nil; // So it does not get freed in except
+        end;
+      if not SemicolonSeen then
+        GetToken;
+      CheckCurrentToken(tkSemicolon);
+      tk:=GetToken;
+      end;
+    ok:=true;
+  finally
+    if not ok then
+      begin
+      FreeAndNil(Attrs);
+      MaybeFree(Result,aParent);
+      end;
+  end;
+end;
+
 function TWebIDLParser.ParsePartial(aParent : TIDLBaseObject): TIDLStructuredDefinition;
 function TWebIDLParser.ParsePartial(aParent : TIDLBaseObject): TIDLStructuredDefinition;
 
 
 (* On entry, we're on Partial. On exit, we're on the } character *)
 (* On entry, we're on Partial. On exit, we're on the } character *)
 
 
 begin
 begin
   Case GetToken of
   Case GetToken of
+    tkNamespace : Result:=ParseNamespace(aParent);
     tkInterface : Result:=ParseInterface(aParent);
     tkInterface : Result:=ParseInterface(aParent);
     tkDictionary : Result:=ParseDictionary(aParent);
     tkDictionary : Result:=ParseDictionary(aParent);
   else
   else
@@ -1534,6 +1612,7 @@ begin
       tkPartial : Result:=ParsePartial(aParent);
       tkPartial : Result:=ParsePartial(aParent);
       tkEnum : Result:=ParseEnum(aParent);
       tkEnum : Result:=ParseEnum(aParent);
       tkTypeDef : Result:=ParseTypeDef(aParent);
       tkTypeDef : Result:=ParseTypeDef(aParent);
+      tkNamespace : Result:=ParseNameSpace(aParent);
       tkIdentifier :
       tkIdentifier :
         Result:=ParseImplementsOrIncludes(aParent);
         Result:=ParseImplementsOrIncludes(aParent);
       tkEOF : exit;
       tkEOF : exit;
@@ -1629,6 +1708,25 @@ begin
     end;
     end;
 end;
 end;
 
 
+function TWebIDLContext.FindNamespace(aName: UTF8String): TIDLNamespaceDefinition;
+Var
+  I : Integer;
+
+begin
+  I:=0;
+  Result:=Nil;
+  While (Result=Nil) and (I<FDefinitions.Count) do
+    begin
+    if (FDefinitions[i] is TIDLNamespaceDefinition) then
+      begin
+      Result:=TIDLNamespaceDefinition(FDefinitions[i]);
+      if (Result.Name<>aName) or (Result.IsPartial) then
+        Result:=nil;
+      end;
+    Inc(I);
+    end;
+end;
+
 procedure TWebIDLContext.AppendDictionaryPartials;
 procedure TWebIDLContext.AppendDictionaryPartials;
 
 
 Var
 Var
@@ -1711,11 +1809,29 @@ begin
       end;
       end;
 end;
 end;
 
 
+procedure TWebIDLContext.AppendNamespacePartials;
+
+Var
+  D : TIDLDefinition;
+  ID : TIDLNamespaceDefinition absolute D;
+  OD : TIDLNamespaceDefinition;
+
+begin
+  For D in FDefinitions do
+    if (D is TIDLNamespaceDefinition) and (ID.IsPartial) then
+      begin
+      OD:=FindNamespace(ID.Name);
+      If (OD<>Nil) then
+        OD.Partials.Add(ID);
+      end;
+end;
+
 procedure TWebIDLContext.AppendPartials;
 procedure TWebIDLContext.AppendPartials;
 
 
 begin
 begin
   AppendDictionaryPartials;
   AppendDictionaryPartials;
   AppendInterfacePartials;
   AppendInterfacePartials;
+  AppendNamespacePartials;
 end;
 end;
 
 
 procedure TWebIDLContext.AppendIncludes;
 procedure TWebIDLContext.AppendIncludes;
@@ -1933,5 +2049,23 @@ begin
     Result:=aClass.Create(Nil,aName,aFile,aLine,aCol);
     Result:=aClass.Create(Nil,aName,aFile,aLine,aCol);
 end;
 end;
 
 
+function TWebIDLContext.HaveNamespaces: boolean;
+var
+  I : Integer;
+begin
+  if FHaveNameSpaces=cbCalc then
+    begin
+    FHaveNameSpaces:=cbFalse;
+    I:=0;
+    While (FHaveNameSpaces=cbFalse) and (I<FDefinitions.Count) do
+      begin
+      if FDefinitions[i] is TIDLNamespaceDefinition then
+        FHaveNameSpaces:=cbTrue;
+      Inc(I);
+      end;
+    end;
+  Result:=(FHaveNameSpaces=cbtrue);
+end;
+
 end.
 end.
 
 

+ 10 - 6
packages/webidl/src/webidlscanner.pp

@@ -134,16 +134,21 @@ type
     tkSetLike,
     tkSetLike,
     tkOther,
     tkOther,
     tkConstructor,
     tkConstructor,
-    tkObservableArray
+    tkObservableArray,
+    tkNamespace
     );
     );
   TIDLTokens = Set of TIDLToken;
   TIDLTokens = Set of TIDLToken;
   EWebIDLScanner = class(EParserError);
   EWebIDLScanner = class(EParserError);
 
 
 Const
 Const
-  V2Tokens = [tkMixin,tkIncludes,tkMapLike,tkRecord,tkSetLike,tkFrozenArray,tkObservableArray,tkConstructor];
+  V2Tokens = [tkMixin,tkIncludes,tkMapLike,tkRecord,tkSetLike,tkFrozenArray,tkObservableArray,tkConstructor,tkNamespace];
   V1Tokens = [tkImplements];
   V1Tokens = [tkImplements];
   VersionNonTokens : Array[TWebIDLVersion] of TIDLTokens = (V2Tokens,V1Tokens);
   VersionNonTokens : Array[TWebIDLVersion] of TIDLTokens = (V2Tokens,V1Tokens);
 
 
+  V1NameTokens = [tkNan,tkInfinity,tkNegInfinity,tkByteString,tkUSVString,tkDOMString,tkPromise];
+  V2NameTokens = [tkNan,tkInfinity,tkNegInfinity,tkByteString,tkUSVString,tkDOMString,tkPromise,tkFrozenArray,tkObservableArray];
+  VersionNameTokens : Array[TWebIDLVersion] of TIDLTokens = (V1NameTokens,V2NameTokens);
+
   nErrXExpectedButYFound = 1001;
   nErrXExpectedButYFound = 1001;
   nErrRangeCheck = 1002;
   nErrRangeCheck = 1002;
   nErrOperandAndOperatorMismatch = 1003;
   nErrOperandAndOperatorMismatch = 1003;
@@ -402,7 +407,8 @@ const
   'setlike',
   'setlike',
   'other',
   'other',
   'constructor',
   'constructor',
-  'ObservableArray'
+  'ObservableArray',
+  'namespace'
   );
   );
 
 
 Function GetTokenName(aToken : TIDLToken) : String;
 Function GetTokenName(aToken : TIDLToken) : String;
@@ -1463,11 +1469,9 @@ end;
 
 
 function TWebIDLScanner.DetermineToken2 : TIDLToken;
 function TWebIDLScanner.DetermineToken2 : TIDLToken;
 
 
-Const
-  InfTokens = [tkNan,tkInfinity,tkNegInfinity,tkByteString,tkUSVString,tkDOMString,tkPromise,tkFrozenArray,tkObservableArray];
 
 
 begin
 begin
-  For Result in InfTokens do
+  For Result in VersionNameTokens[Version] do
     if (TokenInfos[result]=FCurTokenString) then exit;
     if (TokenInfos[result]=FCurTokenString) then exit;
   Result:=tkIdentifier;
   Result:=tkIdentifier;
 end;
 end;

+ 148 - 21
packages/webidl/src/webidltopas.pp

@@ -120,7 +120,7 @@ type
     function GetDefPos(Def: TIDLBaseObject; WithoutFile: boolean = false): string; virtual;
     function GetDefPos(Def: TIDLBaseObject; WithoutFile: boolean = false): string; virtual;
     function GetPasDataPos(D: TPasData; WithoutFile: boolean = false): string; virtual;
     function GetPasDataPos(D: TPasData; WithoutFile: boolean = false): string; virtual;
     procedure EnsureUniqueNames(ML: TIDLDefinitionList); virtual;
     procedure EnsureUniqueNames(ML: TIDLDefinitionList); virtual;
-    procedure EnsureUniqueArgNames(Intf: TIDLInterfaceDefinition); virtual;
+    procedure EnsureUniqueArgNames(Intf: TIDLStructuredDefinition); virtual;
     function AddSequenceDef(ST: TIDLSequenceTypeDefDefinition): Boolean; virtual;
     function AddSequenceDef(ST: TIDLSequenceTypeDefDefinition): Boolean; virtual;
     function GetName(ADef: TIDLDefinition): String; virtual;
     function GetName(ADef: TIDLDefinition): String; virtual;
     function GetPasClassName(const aName: string): string; overload; virtual;
     function GetPasClassName(const aName: string): string; overload; virtual;
@@ -129,6 +129,7 @@ type
     function GetResolvedType(aDef: TIDLTypeDefDefinition; out aTypeName, aResolvedTypename: string): TIDLDefinition; overload; virtual;
     function GetResolvedType(aDef: TIDLTypeDefDefinition; out aTypeName, aResolvedTypename: string): TIDLDefinition; overload; virtual;
     function GetSequenceTypeName(Seq: TIDLSequenceTypeDefDefinition; ForTypeDef: Boolean=False): string; virtual;
     function GetSequenceTypeName(Seq: TIDLSequenceTypeDefDefinition; ForTypeDef: Boolean=False): string; virtual;
     function GetInterfaceDefHead(Intf: TIDLInterfaceDefinition): String; virtual;
     function GetInterfaceDefHead(Intf: TIDLInterfaceDefinition): String; virtual;
+    function GetNamespaceDefHead(Intf: TIDLNamespaceDefinition): String; virtual;
     function GetDictionaryDefHead(const CurClassName: string; Dict: TIDLDictionaryDefinition): String; virtual;
     function GetDictionaryDefHead(const CurClassName: string; Dict: TIDLDictionaryDefinition): String; virtual;
     function CheckUnionTypeDefinition(D: TIDLDefinition): TIDLUnionTypeDefDefinition; virtual;
     function CheckUnionTypeDefinition(D: TIDLDefinition): TIDLUnionTypeDefDefinition; virtual;
     Function CloneArgument(Arg: TIDLArgumentDefinition): TIDLArgumentDefinition; virtual;
     Function CloneArgument(Arg: TIDLArgumentDefinition): TIDLArgumentDefinition; virtual;
@@ -143,13 +144,14 @@ type
     // Code generation routines. Return the number of actually written defs.
     // Code generation routines. Return the number of actually written defs.
     function WriteFunctionImplicitTypes(aList: TIDLDefinitionList): Integer; virtual;
     function WriteFunctionImplicitTypes(aList: TIDLDefinitionList): Integer; virtual;
     function WriteAttributeImplicitTypes(aList: TIDLDefinitionList): Integer; virtual;
     function WriteAttributeImplicitTypes(aList: TIDLDefinitionList): Integer; virtual;
-    function WriteOtherImplicitTypes(Intf: TIDLInterfaceDefinition; aMemberList: TIDLDefinitionList): Integer; virtual;
+    function WriteOtherImplicitTypes(Intf: TIDLStructuredDefinition; aMemberList: TIDLDefinitionList): Integer; virtual;
     function WriteDictionaryMemberImplicitTypes(aDict: TIDLDictionaryDefinition; aList: TIDLDefinitionList): Integer; virtual;
     function WriteDictionaryMemberImplicitTypes(aDict: TIDLDictionaryDefinition; aList: TIDLDefinitionList): Integer; virtual;
     function WriteDictionaryDefs(aList: TIDLDefinitionList): Integer; virtual;
     function WriteDictionaryDefs(aList: TIDLDefinitionList): Integer; virtual;
     function WriteForwardClassDefs(aList: TIDLDefinitionList): Integer; virtual;
     function WriteForwardClassDefs(aList: TIDLDefinitionList): Integer; virtual;
     function WriteInterfaceDefs(aList: TIDLDefinitionList): Integer; virtual;
     function WriteInterfaceDefs(aList: TIDLDefinitionList): Integer; virtual;
-    function WriteMethodDefs(aParent: TIDLInterfaceDefinition; aList: TIDLDefinitionList): Integer; virtual;
-    function WriteUtilityMethods(Intf: TIDLInterfaceDefinition): Integer; virtual;
+    function WriteNamespaceDefs(aList: TIDLDefinitionList): Integer; virtual;
+    function WriteMethodDefs(aParent: TIDLStructuredDefinition; aList: TIDLDefinitionList): Integer; virtual;
+    function WriteUtilityMethods(Intf: TIDLStructuredDefinition): Integer; virtual;
     function WriteTypeDefsAndCallbacks(aList: TIDLDefinitionList): Integer; virtual;
     function WriteTypeDefsAndCallbacks(aList: TIDLDefinitionList): Integer; virtual;
     function WriteEnumDefs(aList: TIDLDefinitionList): Integer; virtual;
     function WriteEnumDefs(aList: TIDLDefinitionList): Integer; virtual;
     function WriteConsts(aParent: TIDLDefinition; aList: TIDLDefinitionList): Integer; virtual;
     function WriteConsts(aParent: TIDLDefinition; aList: TIDLDefinitionList): Integer; virtual;
@@ -162,7 +164,7 @@ type
     // Definitions. Return true if a definition was written.
     // Definitions. Return true if a definition was written.
     function WriteForwardClassDef(D: TIDLStructuredDefinition): Boolean; virtual;
     function WriteForwardClassDef(D: TIDLStructuredDefinition): Boolean; virtual;
     function WriteFunctionTypeDefinition(aDef: TIDLFunctionDefinition): Boolean; virtual;
     function WriteFunctionTypeDefinition(aDef: TIDLFunctionDefinition): Boolean; virtual;
-    function WriteFunctionDefinition(aParent: TIDLInterfaceDefinition; aDef: TIDLFunctionDefinition): Boolean; virtual;
+    function WriteFunctionDefinition(aParent: TIDLStructuredDefinition; aDef: TIDLFunctionDefinition): Boolean; virtual;
     function WriteTypeDef(aDef: TIDLTypeDefDefinition): Boolean; virtual;
     function WriteTypeDef(aDef: TIDLTypeDefDefinition): Boolean; virtual;
     function WriteRecordDef(aDef: TIDLRecordDefinition): Boolean; virtual;
     function WriteRecordDef(aDef: TIDLRecordDefinition): Boolean; virtual;
     function WriteEnumDef(aDef: TIDLEnumDefinition): Boolean; virtual;
     function WriteEnumDef(aDef: TIDLEnumDefinition): Boolean; virtual;
@@ -170,6 +172,7 @@ type
     function WriteField(aAttr: TIDLAttributeDefinition): Boolean; virtual;
     function WriteField(aAttr: TIDLAttributeDefinition): Boolean; virtual;
     function WriteConst(aConst: TIDLConstDefinition): Boolean ; virtual;
     function WriteConst(aConst: TIDLConstDefinition): Boolean ; virtual;
     function WriteInterfaceDef(Intf: TIDLInterfaceDefinition): Boolean; virtual;
     function WriteInterfaceDef(Intf: TIDLInterfaceDefinition): Boolean; virtual;
+    function WriteNamespaceDef(aNamespace: TIDLNamespaceDefinition): Boolean; virtual;
     function WriteDictionaryDef(aDict: TIDLDictionaryDefinition): Boolean; virtual;
     function WriteDictionaryDef(aDict: TIDLDictionaryDefinition): Boolean; virtual;
     // Additional
     // Additional
     procedure WriteAliasTypeDef(aDef: TIDLTypeDefDefinition); virtual;
     procedure WriteAliasTypeDef(aDef: TIDLTypeDefDefinition); virtual;
@@ -177,7 +180,9 @@ type
     procedure WriteSequenceDef(aDef: TIDLSequenceTypeDefDefinition); virtual;
     procedure WriteSequenceDef(aDef: TIDLSequenceTypeDefDefinition); virtual;
     procedure WriteUnionDef(aDef: TIDLUnionTypeDefDefinition); virtual;
     procedure WriteUnionDef(aDef: TIDLUnionTypeDefDefinition); virtual;
     // Extra interface/Implementation code.
     // Extra interface/Implementation code.
-    procedure WriteGlobalVars; virtual;
+    procedure WriteGlobalVar(aDef: String); virtual;
+    procedure WriteNamespaceVars; virtual;
+    procedure WriteGlobalVars;
     procedure WriteImplementation; virtual;
     procedure WriteImplementation; virtual;
     procedure WriteIncludeInterfaceCode; virtual;
     procedure WriteIncludeInterfaceCode; virtual;
     Property Context: TWebIDLContext Read FContext;
     Property Context: TWebIDLContext Read FContext;
@@ -375,7 +380,7 @@ begin
 end;
 end;
 
 
 function TBaseWebIDLToPas.WriteOtherImplicitTypes(
 function TBaseWebIDLToPas.WriteOtherImplicitTypes(
-  Intf: TIDLInterfaceDefinition; aMemberList: TIDLDefinitionList): Integer;
+  Intf: TIDLStructuredDefinition; aMemberList: TIDLDefinitionList): Integer;
 begin
 begin
   Result:=0;
   Result:=0;
   if Intf=nil then ;
   if Intf=nil then ;
@@ -516,7 +521,7 @@ begin
   Undent;
   Undent;
 end;
 end;
 
 
-function TBaseWebIDLToPas.WriteMethodDefs(aParent: TIDLInterfaceDefinition;
+function TBaseWebIDLToPas.WriteMethodDefs(aParent: TIDLStructuredDefinition;
   aList: TIDLDefinitionList): Integer;
   aList: TIDLDefinitionList): Integer;
 
 
 Var
 Var
@@ -532,7 +537,7 @@ begin
            Inc(Result);
            Inc(Result);
 end;
 end;
 
 
-function TBaseWebIDLToPas.WriteUtilityMethods(Intf: TIDLInterfaceDefinition
+function TBaseWebIDLToPas.WriteUtilityMethods(Intf: TIDLStructuredDefinition
   ): Integer;
   ): Integer;
 begin
 begin
   Result:=0;
   Result:=0;
@@ -622,7 +627,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TBaseWebIDLToPas.EnsureUniqueArgNames(Intf: TIDLInterfaceDefinition);
+procedure TBaseWebIDLToPas.EnsureUniqueArgNames(Intf: TIDLStructuredDefinition);
 var
 var
   Names: TFPObjectHashTable;
   Names: TFPObjectHashTable;
 
 
@@ -654,7 +659,7 @@ var
 
 
 var
 var
   Members, MembersWithParents: TIDLDefinitionList;
   Members, MembersWithParents: TIDLDefinitionList;
-  CurIntf: TIDLInterfaceDefinition;
+  CurIntf: TIDLStructuredDefinition;
   D: TIDLDefinition;
   D: TIDLDefinition;
   CurName: String;
   CurName: String;
 begin
 begin
@@ -667,7 +672,10 @@ begin
     while CurIntf<>nil do
     while CurIntf<>nil do
       begin
       begin
       CurIntf.GetFullMemberList(MembersWithParents);
       CurIntf.GetFullMemberList(MembersWithParents);
-      CurIntf:=CurIntf.ParentInterface;
+      if CurIntf is TIDLInterfaceDefinition then
+        CurIntf:=TIDLInterfaceDefinition(CurIntf).ParentInterface
+      else
+        CurIntf:=nil;
       end;
       end;
     For D in MembersWithParents Do
     For D in MembersWithParents Do
       begin
       begin
@@ -739,6 +747,59 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TBaseWebIDLToPas.WriteNamespaceDef(aNamespace: TIDLNamespaceDefinition): Boolean;
+
+Var
+  aClassName: String;
+  Decl: String;
+  ML: TIDLDefinitionList;
+
+begin
+  Result:=True;
+  ML:=TIDLDefinitionList.Create(Nil,False);
+  try
+    aNamespace.GetFullMemberList(ML);
+    EnsureUniqueNames(ML);
+    EnsureUniqueArgNames(aNamespace);
+    aClassName:=GetName(aNamespace);
+    // class comment
+    ClassComment(aClassName);
+    // sub types
+    WriteFunctionImplicitTypes(ML);
+    WriteAttributeImplicitTypes(ML);
+    WriteOtherImplicitTypes(aNameSpace,ML);
+    // class and ancestor
+    Decl:=aClassName+' = '+GetNamespaceDefHead(aNamespace);
+    AddLn(Decl);
+    // private section
+    AddLn('Private');
+    Indent;
+    WritePrivateReadOnlyFields(aNamespace,ML);
+    WritePrivateGetters(aNamespace,ML);
+    WritePrivateSetters(aNamespace,ML);
+    Undent;
+    // write public section
+    AddLn('Public');
+    if HaveConsts(ML) then
+      begin
+      Indent;
+      PushSection(csUnknown);
+      WriteConsts(aNamespace,ML);
+      PopSection;
+      Undent;
+      AddLn('Public');
+      end;
+    Indent;
+    WriteMethodDefs(aNamespace,ML);
+    WriteUtilityMethods(aNamespace);
+    WriteProperties(aNamespace,ML);
+    Undent;
+    AddLn('end;');
+  finally
+    ML.Free;
+  end;
+end;
+
 function TBaseWebIDLToPas.WriteDictionaryDef(aDict: TIDLDictionaryDefinition
 function TBaseWebIDLToPas.WriteDictionaryDef(aDict: TIDLDictionaryDefinition
   ): Boolean;
   ): Boolean;
 
 
@@ -878,6 +939,12 @@ begin
   if Intf=nil then ;
   if Intf=nil then ;
 end;
 end;
 
 
+function TBaseWebIDLToPas.GetNamespaceDefHead(Intf: TIDLNamespaceDefinition): String;
+begin
+  Result:='class';
+  if Intf=nil then ;
+end;
+
 function TBaseWebIDLToPas.GetDictionaryDefHead(const CurClassName: string;
 function TBaseWebIDLToPas.GetDictionaryDefHead(const CurClassName: string;
   Dict: TIDLDictionaryDefinition): String;
   Dict: TIDLDictionaryDefinition): String;
 var
 var
@@ -986,9 +1053,11 @@ begin
   Result:=0;
   Result:=0;
   Comment('Forward class definitions');
   Comment('Forward class definitions');
   For D in aList do
   For D in aList do
-    if D is TIDLInterfaceDefinition then
-      if WriteForwardClassDef(D as TIDLInterfaceDefinition) then
+    if (D is TIDLInterfaceDefinition) or (D is TIDLNamespaceDefinition) then
+      begin
+      if WriteForwardClassDef(D as TIDLStructuredDefinition) then
         Inc(Result);
         Inc(Result);
+      end;
   if coDictionaryAsClass in BaseOptions then
   if coDictionaryAsClass in BaseOptions then
     For D in aList do
     For D in aList do
       if D is TIDLDictionaryDefinition then
       if D is TIDLDictionaryDefinition then
@@ -1020,23 +1089,52 @@ begin
   AddLn(GetName(aDef)+' = '+GetTypeName('any')+';');
   AddLn(GetName(aDef)+' = '+GetTypeName('any')+';');
 end;
 end;
 
 
+
+procedure TBaseWebIDLToPas.WriteGlobalVar(aDef : String);
+
+var
+  P : Integer;
+  VarName, VarType: String;
+
+begin
+  P:=Pos('=',aDef);
+  VarName:=Trim(Copy(aDef,1,P-1));
+  VarType:=Trim(Copy(aDef,P+1));
+  AddLn(VarName+': '+VarType+';');
+end;
+
 procedure TBaseWebIDLToPas.WriteGlobalVars;
 procedure TBaseWebIDLToPas.WriteGlobalVars;
 var
 var
   i: Integer;
   i: Integer;
-  VarName, VarType: String;
 begin
 begin
-  if GlobalVars.Count=0 then exit;
+  if (GlobalVars.Count=0) and Not Context.HaveNamespaces  then
+    exit;
   AddLn('var');
   AddLn('var');
   Indent;
   Indent;
   for i:=0 to GlobalVars.Count-1 do
   for i:=0 to GlobalVars.Count-1 do
     begin
     begin
-    VarName:=GlobalVars.Names[i];
-    VarType:=GlobalVars.ValueFromIndex[i];
-    AddLn(VarName+': '+VarType+';');
+    WriteGlobalvar(GlobalVars[i]);
     end;
     end;
+  WriteNamespaceVars;
   Undent;
   Undent;
 end;
 end;
 
 
+procedure TBaseWebIDLToPas.WriteNamespaceVars;
+
+var
+  i: Integer;
+  VarName, VarType: String;
+
+begin
+  for I:=0 to Context.Definitions.Count-1 do
+    if Context.Definitions[i] is TIDLNamespaceDefinition then
+      begin
+      VarName:=Context.Definitions[i].Name;
+      VarType:=GetName(Context.Definitions[i]);
+      AddLn(VarName+': '+VarType+';');
+      end;
+end;
+
 procedure TBaseWebIDLToPas.WritePromiseDef(aDef: TIDLPromiseTypeDefDefinition);
 procedure TBaseWebIDLToPas.WritePromiseDef(aDef: TIDLPromiseTypeDefDefinition);
 
 
 begin
 begin
@@ -1393,7 +1491,7 @@ begin
 end;
 end;
 
 
 function TBaseWebIDLToPas.WriteFunctionDefinition(
 function TBaseWebIDLToPas.WriteFunctionDefinition(
-  aParent: TIDLInterfaceDefinition; aDef: TIDLFunctionDefinition): Boolean;
+  aParent: TIDLStructuredDefinition; aDef: TIDLFunctionDefinition): Boolean;
 begin
 begin
   Result:=true;
   Result:=true;
   if aDef=nil then exit;
   if aDef=nil then exit;
@@ -1427,11 +1525,26 @@ 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 not TIDLInterfaceDefinition(D).IsPartial then
+      if not ID.IsPartial then
         if WriteInterfaceDef(ID) then
         if WriteInterfaceDef(ID) then
           Inc(Result);
           Inc(Result);
 end;
 end;
 
 
+function TBaseWebIDLToPas.WriteNamespaceDefs(aList: TIDLDefinitionList): Integer;
+Var
+  D: TIDLDefinition;
+  ND: TIDLNamespaceDefinition absolute D;
+
+begin
+  Result:=0;
+  EnsureSection(csType);
+  for D in aList do
+    if D is TIDLNamespaceDefinition then
+      if not ND.IsPartial then
+        if WriteNamespaceDef(ND) then
+          Inc(Result);
+end;
+
 procedure TBaseWebIDLToPas.GetOptions(L: TStrings; Full: boolean);
 procedure TBaseWebIDLToPas.GetOptions(L: TStrings; Full: boolean);
 
 
   function CountLines(const s: string): integer;
   function CountLines(const s: string): integer;
@@ -1554,6 +1667,7 @@ begin
   WriteTypeDefsAndCallbacks(Context.Definitions);
   WriteTypeDefsAndCallbacks(Context.Definitions);
   WriteDictionaryDefs(Context.Definitions);
   WriteDictionaryDefs(Context.Definitions);
   WriteInterfaceDefs(Context.GetInterfacesTopologically);
   WriteInterfaceDefs(Context.GetInterfacesTopologically);
+  WriteNamespaceDefs(Context.Definitions);
   Undent;
   Undent;
   WriteGlobalVars;
   WriteGlobalVars;
   WriteIncludeInterfaceCode;
   WriteIncludeInterfaceCode;
@@ -1610,6 +1724,17 @@ begin
     D.Data:=Result;
     D.Data:=Result;
     AllocatePasNames((D as TIDLInterfaceDefinition).Members,D.Name);
     AllocatePasNames((D as TIDLInterfaceDefinition).Members,D.Name);
     end
     end
+  else if D Is TIDLNamespaceDefinition then
+    begin
+    if CN='' then
+      raise EConvertError.Create('[20240405142524] at '+GetDefPos(D));
+    if not TIDLNamespaceDefinition(D).IsPartial then
+      AddJSIdentifier(D);
+    CN:=ClassPrefix+CN+ClassSuffix;
+    Result:=CreatePasData(CN,D,true);
+    D.Data:=Result;
+    AllocatePasNames((D as TIDLNamespaceDefinition).Members,D.Name);
+    end
   else if D Is TIDLDictionaryDefinition then
   else if D Is TIDLDictionaryDefinition then
     begin
     begin
     if CN='' then
     if CN='' then
@@ -1732,6 +1857,8 @@ begin
   //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
   if D Is TIDLInterfaceDefinition then
     ResolveTypeDefs(TIDLInterfaceDefinition(D).Members)
     ResolveTypeDefs(TIDLInterfaceDefinition(D).Members)
+  else if D Is TIDLNamespaceDefinition then
+    ResolveTypeDefs(TIDLNamespaceDefinition(D).Members)
   else if D Is TIDLDictionaryDefinition then
   else if D Is TIDLDictionaryDefinition then
     ResolveTypeDefs(TIDLDictionaryDefinition(D).Members)
     ResolveTypeDefs(TIDLDictionaryDefinition(D).Members)
   else if D is TIDLIncludesDefinition then
   else if D is TIDLIncludesDefinition then

+ 73 - 36
packages/webidl/src/webidltowasmjob.pp

@@ -90,26 +90,23 @@ type
     function GetResolvedType(aDef: TIDLTypeDefDefinition; out aTypeName,
     function GetResolvedType(aDef: TIDLTypeDefDefinition; out aTypeName,
       aResolvedTypename: TIDLString): TIDLDefinition; overload; 
       aResolvedTypename: TIDLString): TIDLDefinition; overload; 
 {$ENDIF}      
 {$ENDIF}      
-    function GetInterfaceDefHead(Intf: TIDLInterfaceDefinition): String;
-      override;
+    function GetInterfaceDefHead(Intf: TIDLInterfaceDefinition): String; override;
+    function GetNamespaceDefHead(aNamespace: TIDLNamespaceDefinition): String; override;
     function GetDictionaryDefHead(const CurClassName: String;
     function GetDictionaryDefHead(const CurClassName: String;
       Dict: TIDLDictionaryDefinition): String; override;
       Dict: TIDLDictionaryDefinition): String; override;
-    function WriteOtherImplicitTypes(Intf: TIDLInterfaceDefinition; aMemberList: TIDLDefinitionList): Integer;
-      override;
+    function WriteOtherImplicitTypes(Intf: TIDLStructuredDefinition; aMemberList: TIDLDefinitionList): Integer; override;
     // Code generation routines. Return the number of actually written defs.
     // Code generation routines. Return the number of actually written defs.
     function WritePrivateGetters(aParent: TIDLStructuredDefinition; aList: TIDLDefinitionList): Integer; override;
     function WritePrivateGetters(aParent: TIDLStructuredDefinition; aList: TIDLDefinitionList): Integer; override;
     function WritePrivateSetters(aParent: TIDLStructuredDefinition; aList: TIDLDefinitionList): Integer; override;
     function WritePrivateSetters(aParent: TIDLStructuredDefinition; aList: TIDLDefinitionList): Integer; override;
     function WriteProperties(aParent: TIDLDefinition; aList: TIDLDefinitionList): Integer; override;
     function WriteProperties(aParent: TIDLDefinition; aList: TIDLDefinitionList): Integer; override;
-    function WriteUtilityMethods(Intf: TIDLInterfaceDefinition): Integer;
+    function WriteUtilityMethods(Intf: TIDLStructuredDefinition): Integer;
       override;
       override;
     // Definitions. Return true if a definition was written.
     // Definitions. Return true if a definition was written.
     function WriteEnumDef(aDef: TIDLEnumDefinition): Boolean; override;
     function WriteEnumDef(aDef: TIDLEnumDefinition): Boolean; override;
     function WriteDictionaryField(aDict: TIDLDictionaryDefinition;
     function WriteDictionaryField(aDict: TIDLDictionaryDefinition;
       aField: TIDLDictionaryMemberDefinition): Boolean; override;
       aField: TIDLDictionaryMemberDefinition): Boolean; override;
-    function WriteForwardClassDef(D: TIDLStructuredDefinition): Boolean;
-      override;
-    function WriteFunctionDefinition(aParent: TIDLInterfaceDefinition; aDef: TIDLFunctionDefinition): Boolean;
-      override;
+    function WriteForwardClassDef(D: TIDLStructuredDefinition): Boolean; override;
+    function WriteFunctionDefinition(aParent: TIDLStructuredDefinition; aDef: TIDLFunctionDefinition): Boolean; override;
     function WriteFunctionTypeDefinition(aDef: TIDLFunctionDefinition
     function WriteFunctionTypeDefinition(aDef: TIDLFunctionDefinition
       ): Boolean; override;
       ): Boolean; override;
     function WritePrivateGetter(aParent: TIDLStructuredDefinition; Attr: TIDLAttributeDefinition): boolean; virtual;
     function WritePrivateGetter(aParent: TIDLStructuredDefinition; Attr: TIDLAttributeDefinition): boolean; virtual;
@@ -118,7 +115,8 @@ type
     function WriteRecordDef(aDef: TIDLRecordDefinition): Boolean; override;
     function WriteRecordDef(aDef: TIDLRecordDefinition): Boolean; override;
     procedure WriteSequenceDef(aDef: TIDLSequenceTypeDefDefinition); override;
     procedure WriteSequenceDef(aDef: TIDLSequenceTypeDefDefinition); override;
     // Extra interface/Implementation code.
     // Extra interface/Implementation code.
-    procedure WriteGlobalVars; override;
+    procedure WriteNamespaceVars; override;
+    procedure WriteGlobalVar(aDef : String); override;
     procedure WriteImplementation; override;
     procedure WriteImplementation; override;
   Public
   Public
     constructor Create(ThOwner: TComponent); override;
     constructor Create(ThOwner: TComponent); override;
@@ -324,6 +322,16 @@ begin
   Result:=Result+','+aPasIntfName+')';
   Result:=Result+','+aPasIntfName+')';
 end;
 end;
 
 
+function TWebIDLToPasWasmJob.GetNamespaceDefHead(aNamespace: TIDLNamespaceDefinition): String;
+
+var
+  aPasIntfName: TIDLString;
+begin
+  Result:='class('+ClassPrefix+'Object'+ClassSuffix;
+  aPasIntfName:=GetPasIntfName(aNameSpace);
+  Result:=Result+','+aPasIntfName+')';
+end;
+
 function TWebIDLToPasWasmJob.GetDictionaryDefHead(const CurClassName: String;
 function TWebIDLToPasWasmJob.GetDictionaryDefHead(const CurClassName: String;
   Dict: TIDLDictionaryDefinition): String;
   Dict: TIDLDictionaryDefinition): String;
 begin
 begin
@@ -331,12 +339,15 @@ begin
   if Dict=nil then ;
   if Dict=nil then ;
 end;
 end;
 
 
-function TWebIDLToPasWasmJob.WriteOtherImplicitTypes(
-  Intf: TIDLInterfaceDefinition; aMemberList: TIDLDefinitionList): Integer;
+function TWebIDLToPasWasmJob.WriteOtherImplicitTypes(Intf: TIDLStructuredDefinition; aMemberList: TIDLDefinitionList): Integer;
 var
 var
+  iIntf : TIDLInterfaceDefinition absolute Intf;
   aPasIntfName, Decl, ParentName: TIDLString;
   aPasIntfName, Decl, ParentName: TIDLString;
+  isNamespace : Boolean;
 begin
 begin
   Result:=1;
   Result:=1;
+  isNameSpace:=Intf is TIDLNamespaceDefinition;
+  ParentName:='';
 
 
   FWritingPasInterface:=true;
   FWritingPasInterface:=true;
   try
   try
@@ -345,10 +356,11 @@ begin
     aPasIntfName:=GetPasIntfName(Intf);
     aPasIntfName:=GetPasIntfName(Intf);
 
 
     Decl:=aPasIntfName+' = interface';
     Decl:=aPasIntfName+' = interface';
-    if Assigned(Intf.ParentInterface) then
-      ParentName:=GetPasIntfName(Intf.ParentInterface as TIDLInterfaceDefinition)
-    else
-      ParentName:=GetTypeName(Intf.ParentName);
+    if (not IsNamespace) then
+      if Assigned(iIntf.ParentInterface) then
+        ParentName:=GetPasIntfName(iIntf.ParentInterface as TIDLInterfaceDefinition)
+      else
+        ParentName:=GetTypeName(Intf.ParentName);
     if ParentName='' then
     if ParentName='' then
       ParentName:=PasInterfacePrefix+'Object'+PasInterfaceSuffix;
       ParentName:=PasInterfacePrefix+'Object'+PasInterfaceSuffix;
     if ParentName<>'' then
     if ParentName<>'' then
@@ -412,7 +424,7 @@ begin
         inc(Result);
         inc(Result);
 end;
 end;
 
 
-function TWebIDLToPasWasmJob.WriteUtilityMethods(Intf: TIDLInterfaceDefinition
+function TWebIDLToPasWasmJob.WriteUtilityMethods(Intf: TIDLStructuredDefinition
   ): Integer;
   ): Integer;
 var
 var
   aClassName, aPasIntfName, Code: TIDLString;
   aClassName, aPasIntfName, Code: TIDLString;
@@ -456,14 +468,14 @@ begin
     AddLn(GetName(D)+' = '+JOB_JSValueTypeNames[jjvkDictionary]+';')
     AddLn(GetName(D)+' = '+JOB_JSValueTypeNames[jjvkDictionary]+';')
   else
   else
     begin
     begin
-    if (not D.IsPartial) and (D is TIDLInterfaceDefinition) then
+    if (not D.IsPartial) and ((D is TIDLInterfaceDefinition) or (D is TIDLNamespaceDefinition)) then
       AddLn(GetPasIntfName(D)+' = interface;');
       AddLn(GetPasIntfName(D)+' = interface;');
     Result:=inherited WriteForwardClassDef(D);
     Result:=inherited WriteForwardClassDef(D);
     end;
     end;
 end;
 end;
 
 
 function TWebIDLToPasWasmJob.WriteFunctionDefinition(
 function TWebIDLToPasWasmJob.WriteFunctionDefinition(
-  aParent: TIDLInterfaceDefinition; aDef: TIDLFunctionDefinition): Boolean;
+  aParent: TIDLStructuredDefinition; aDef: TIDLFunctionDefinition): Boolean;
 var
 var
   ArgNames: TStringList;
   ArgNames: TStringList;
 
 
@@ -976,26 +988,33 @@ begin
   Addln(GetName(aDef)+' = '+PasInterfacePrefix+'Array'+PasInterfaceSuffix+'; // array of '+GetTypeName(aDef.ElementType));
   Addln(GetName(aDef)+' = '+PasInterfacePrefix+'Array'+PasInterfaceSuffix+'; // array of '+GetTypeName(aDef.ElementType));
 end;
 end;
 
 
-procedure TWebIDLToPasWasmJob.WriteGlobalVars;
+procedure TWebIDLToPasWasmJob.WriteNamespaceVars;
+
 var
 var
   i: Integer;
   i: Integer;
+  VarName, VarType: String;
+
+begin
+  for I:=0 to Context.Definitions.Count-1 do
+    if Context.Definitions[i] is TIDLNamespaceDefinition then
+      begin
+      VarName:=Context.Definitions[i].Name;
+      VarType:=GetPasIntfName(Context.Definitions[i]);
+      AddLn(VarName+': '+VarType+';');
+      end;
+end;
+
+procedure TWebIDLToPasWasmJob.WriteGlobalVar(aDef : String);
+var
   PasVarName, JSClassName, JOBRegisterName: TIDLString;
   PasVarName, JSClassName, JOBRegisterName: TIDLString;
-  aDef: TIDLDefinition;
+  iDef: TIDLDefinition;
 begin
 begin
-  if GlobalVars.Count=0 then exit;
-  AddLn('');
-  AddLn('var');
-  Indent;
-  for i:=0 to GlobalVars.Count-1 do
-    begin
-    if not SplitGlobalVar(GlobalVars[i],PasVarName,JSClassName,JOBRegisterName) then
-      raise EConvertError.Create('invalid global var "'+GlobalVars[i]+'"');
-    aDef:=FindGlobalDef(JSClassName);
-    if aDef=nil then
-      raise EConvertError.Create('missing global var "'+PasVarName+'" type "'+JSClassName+'"');
-    AddLn(PasVarName+': '+GetName(aDef)+';');
-    end;
-  Undent;
+  if not SplitGlobalVar(aDef,PasVarName,JSClassName,JOBRegisterName) then
+    raise EConvertError.Create('invalid global var "'+aDef+'"');
+  iDef:=FindGlobalDef(JSClassName);
+  if iDef=nil then
+    raise EConvertError.Create('missing global var "'+PasVarName+'" type "'+JSClassName+'"');
+  AddLn(PasVarName+': '+GetName(iDef)+';');
 end;
 end;
 
 
 procedure TWebIDLToPasWasmJob.WriteImplementation;
 procedure TWebIDLToPasWasmJob.WriteImplementation;
@@ -1005,7 +1024,7 @@ var
   PasVarName, JSClassName, JOBRegisterName: TIDLString;
   PasVarName, JSClassName, JOBRegisterName: TIDLString;
 begin
 begin
   inherited WriteImplementation;
   inherited WriteImplementation;
-  if GlobalVars.Count>0 then
+  if (GlobalVars.Count>0) or Context.HaveNameSpaces then
     begin
     begin
     AddLn('initialization');
     AddLn('initialization');
     Indent;
     Indent;
@@ -1015,6 +1034,15 @@ begin
       aDef:=FindGlobalDef(JSClassName);
       aDef:=FindGlobalDef(JSClassName);
       AddLn(PasVarName+':='+GetName(aDef)+'.JOBCreateGlobal('''+JOBRegisterName+''');');
       AddLn(PasVarName+':='+GetName(aDef)+'.JOBCreateGlobal('''+JOBRegisterName+''');');
       end;
       end;
+    for I:=0 to Context.Definitions.Count-1 do
+      begin
+      aDef:=Context.Definitions[i];
+      if aDef is TIDLNamespaceDefinition then
+        begin
+        PasVarName:=Context.Definitions[i].Name;
+        AddLn(PasVarName+':='+GetName(aDef)+'.JOBCreateGlobal('''+PasVarName+''');');
+        end;
+      end;
     Undent;
     Undent;
 
 
     AddLn('finalization');
     AddLn('finalization');
@@ -1024,6 +1052,15 @@ begin
       SplitGlobalVar(GlobalVars[i],PasVarName,JSClassName,JOBRegisterName);
       SplitGlobalVar(GlobalVars[i],PasVarName,JSClassName,JOBRegisterName);
       AddLn(PasVarName+'.Free;');
       AddLn(PasVarName+'.Free;');
       end;
       end;
+    for I:=0 to Context.Definitions.Count-1 do
+      begin
+      aDef:=Context.Definitions[i];
+      if aDef is TIDLNamespaceDefinition then
+        begin
+        PasVarName:=Context.Definitions[i].Name;
+        AddLn(PasVarName+':=Nil;');
+        end;
+      end;
     Undent;
     Undent;
     end;
     end;
 end;
 end;

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

@@ -183,6 +183,25 @@ Type
     Procedure ParseConstIdentifier;
     Procedure ParseConstIdentifier;
   end;
   end;
 
 
+  { TTestNamespaceParser }
+
+  TTestNamespaceParser = Class(TTestParser)
+  Private
+    FCustAttributes : string;
+  Public
+    Procedure Setup; override;
+    function ParseNamespace(aName : UTF8String;aMembers : Array of UTF8String) : TIDLNamespaceDefinition;
+    Property ExtAttributes : String Read FCustAttributes Write FCustAttributes;
+  Published
+    Procedure ParseEmpty;
+    Procedure ParseEmptyNoBrackets;
+    Procedure ParseConst;
+    Procedure ParseReadonlyAttribute;
+    Procedure ParseMethod;
+  end;
+
+
+
   { TTestAttributeInterfaceParser }
   { TTestAttributeInterfaceParser }
 
 
   TTestAttributeInterfaceParser = Class(TTestBaseInterfaceParser)
   TTestAttributeInterfaceParser = Class(TTestBaseInterfaceParser)
@@ -1296,11 +1315,13 @@ end;
 
 
 procedure TTestTypeDefParser.TestFrozenArray;
 procedure TTestTypeDefParser.TestFrozenArray;
 begin
 begin
+  Version:=v2;
   DoTestSequence('FrozenArray<byte> A',stFrozenArray);
   DoTestSequence('FrozenArray<byte> A',stFrozenArray);
 end;
 end;
 
 
 procedure TTestTypeDefParser.TestObservableArray;
 procedure TTestTypeDefParser.TestObservableArray;
 begin
 begin
+  Version:=v2;
   DoTestSequence('ObservableArray<byte> A',stObservableArray);
   DoTestSequence('ObservableArray<byte> A',stObservableArray);
 end;
 end;
 
 
@@ -1372,9 +1393,10 @@ Var
 
 
 begin
 begin
   if IsMixin then
   if IsMixin then
-    Src:='interface mixin '+aName+' '
+    Src:='interface mixin'
   else
   else
-    Src:='interface '+aName+' ';
+    Src:='interface';
+  Src:=Src+' '+aName+' ';
   if (FCustAttributes<>'') then
   if (FCustAttributes<>'') then
     Src:=FCustAttributes+' '+Src;
     Src:=FCustAttributes+' '+Src;
   if (aInheritance<>'') then
   if (aInheritance<>'') then
@@ -1619,6 +1641,103 @@ begin
   ParseConst('A','Zaza','false',ctBoolean);
   ParseConst('A','Zaza','false',ctBoolean);
 end;
 end;
 
 
+{ TTestNamespaceParser }
+
+procedure TTestNamespaceParser.Setup;
+begin
+  inherited Setup;
+  Version:=v2;
+end;
+
+function TTestNamespaceParser.ParseNamespace(aName: UTF8String; aMembers: array of UTF8String): TIDLNamespaceDefinition;
+
+Var
+  Src : UTF8String;
+  I : integer;
+
+begin
+  Src:='namespace '+aName+' ';
+  if (FCustAttributes<>'') then
+    Src:=FCustAttributes+' '+Src;
+  Src:=Src+'{'+sLineBreak;
+  For I:=0 to Length(AMembers)-1 do
+    Src:=Src+'  '+AMembers[I]+';'+sLineBreak;
+  Src:=Src+'};'+sLineBreak;
+  InitSource(Src);
+  Parser.Parse;
+  AssertEquals('Correct class',TIDLNamespaceDefinition,Definitions[0].ClassType);
+  Result:=Definitions[0] as TIDLNamespaceDefinition;
+  AssertEquals('Name',AName,Result.Name);
+  AssertEquals('Member count',Length(AMembers),Result.Members.Count);
+end;
+
+procedure TTestNamespaceParser.ParseEmpty;
+begin
+  ParseNameSpace('A',[]);
+end;
+
+procedure TTestNamespaceParser.ParseEmptyNoBrackets;
+
+var
+  d : TIDLNamespaceDefinition;
+
+begin
+  InitSource('namespace A;'+sLineBreak);
+  Parser.Parse;
+  AssertEquals('Correct class',TIDLNamespaceDefinition,Definitions[0].ClassType);
+  d:=Definitions[0] as TIDLNamespaceDefinition;
+  AssertEquals('Name','A',d.Name);
+  AssertEquals('Member count',0,d.Members.Count);
+end;
+
+procedure TTestNamespaceParser.ParseConst;
+
+var
+  d : TIDLNamespaceDefinition;
+  c : TIDLConstDefinition;
+
+begin
+  ParseNamespace('A',['const short q = 1']);
+  D:=Definitions[0] as TIDLNamespaceDefinition;
+  AssertEquals('Member count',1,d.Members.Count);
+  AssertEquals('Member class',TIDLConstDefinition,D.Member[0].ClassType);
+  c:=TIDLConstDefinition(D.Member[0]);
+  AssertEquals('Member name','q',C.Name);
+  AssertEquals('Member const type',ctInteger,C.ConstType);
+end;
+
+procedure TTestNamespaceParser.ParseReadonlyAttribute;
+
+var
+  d : TIDLNamespaceDefinition;
+  a : TIDLAttributeDefinition;
+
+begin
+  ParseNamespace('A',['readonly attribute short q']);
+  D:=Definitions[0] as TIDLNamespaceDefinition;
+  AssertEquals('Member count',1,d.Members.Count);
+  AssertEquals('Member class',TIDLAttributeDefinition,D.Member[0].ClassType);
+  a:=TIDLAttributeDefinition(D.Member[0]);
+  AssertEquals('Member name','q',a.Name);
+  AssertTrue('Is readonly',aoReadOnly in a.Options);
+end;
+
+procedure TTestNamespaceParser.ParseMethod;
+var
+  d : TIDLNamespaceDefinition;
+  f : TIDLFunctionDefinition;
+
+begin
+  ParseNamespace('A',['short q()']);
+  D:=Definitions[0] as TIDLNamespaceDefinition;
+  AssertEquals('Member count',1,d.Members.Count);
+  AssertEquals('Member class',TIDLFunctionDefinition,D.Member[0].ClassType);
+  f:=TIDLFunctionDefinition(D.Member[0]);
+  AssertEquals('Member name','q',f.Name);
+  AssertNotNull('Have return',f.ReturnType);
+  AssertEquals('Have return name','short',f.ReturnType.TypeName);
+end;
+
 
 
 { TTestEnumParser }
 { TTestEnumParser }
 
 
@@ -1765,6 +1884,7 @@ initialization
                  TTestSerializerInterfaceParser,
                  TTestSerializerInterfaceParser,
                  TTestOperationInterfaceParser,
                  TTestOperationInterfaceParser,
                  TTestMapLikeInterfaceParser,
                  TTestMapLikeInterfaceParser,
-                 TTestSetLikeInterfaceParser]);
+                 TTestSetLikeInterfaceParser,
+                 TTestNamespaceParser]);
 end.
 end.
 
 

+ 45 - 0
packages/webidl/tests/tcidlscanner.pp

@@ -73,6 +73,7 @@ type
     Procedure TestSetLike;
     Procedure TestSetLike;
     Procedure TestRecord;
     Procedure TestRecord;
     Procedure TestInfinity;
     Procedure TestInfinity;
+    Procedure TestIncludes;
     Procedure TestInherit;
     Procedure TestInherit;
     Procedure TestInterface;
     Procedure TestInterface;
     Procedure TestIterable;
     Procedure TestIterable;
@@ -102,6 +103,10 @@ type
     Procedure Testoctet;
     Procedure Testoctet;
     Procedure Testunsigned;
     Procedure Testunsigned;
     Procedure Testvoid;
     Procedure Testvoid;
+    Procedure TestConstructor;
+    Procedure TestObservableArray;
+    Procedure TestFrozenArray;
+    Procedure TestNamespace;
   end;
   end;
 
 
 implementation
 implementation
@@ -336,6 +341,14 @@ begin
   TestSingle('Infinity',tkinfinity);
   TestSingle('Infinity',tkinfinity);
 end;
 end;
 
 
+procedure TTestScanner.TestIncludes;
+begin
+  Version:=v2;
+  TestSingle('includes',tkincludes);
+  Version:=v1;
+  TestSingle('includes',tkIdentifier);
+end;
+
 procedure TTestScanner.TestInherit;
 procedure TTestScanner.TestInherit;
 begin
 begin
   TestSingle('inherit',tkinherit);
   TestSingle('inherit',tkinherit);
@@ -481,6 +494,38 @@ begin
   TestSingle('void',tkVoid);
   TestSingle('void',tkVoid);
 end;
 end;
 
 
+procedure TTestScanner.TestConstructor;
+begin
+  Version:=v2;
+  TestSingle('constructor',tkConstructor);
+  Version:=v1;
+  TestSingle('constructor',tkIdentifier);
+end;
+
+procedure TTestScanner.TestObservableArray;
+begin
+  Version:=v2;
+  TestSingle('ObservableArray',tkObservableArray);
+  Version:=v1;
+  TestSingle('ObservableArray',tkIdentifier);
+end;
+
+procedure TTestScanner.TestFrozenArray;
+begin
+  Version:=v2;
+  TestSingle('FrozenArray',tkFrozenArray);
+  Version:=v1;
+  TestSingle('FrozenArray',tkIdentifier);
+end;
+
+procedure TTestScanner.TestNamespace;
+begin
+  Version:=v2;
+  TestSingle('namespace',tkNamespace);
+  Version:=v1;
+  TestSingle('namespace',tkIdentifier);
+end;
+
 procedure TTestScanner.SetVersion(AValue: TWEbIDLversion);
 procedure TTestScanner.SetVersion(AValue: TWEbIDLversion);
 begin
 begin
   if FVersion=AValue then Exit;
   if FVersion=AValue then Exit;

+ 57 - 0
packages/webidl/tests/tcwebidl2wasmjob.pas

@@ -46,6 +46,8 @@ type
     procedure TestWJ_IntfFunction_SetEventHandler;
     procedure TestWJ_IntfFunction_SetEventHandler;
     procedure TestWJ_IntfFunction_Promise;
     procedure TestWJ_IntfFunction_Promise;
     procedure TestWJ_IntfFunction_ArgAny;
     procedure TestWJ_IntfFunction_ArgAny;
+    // Namespace attribute
+    procedure TestWJ_NamespaceAttribute_Boolean;
   end;
   end;
 
 
 function LinesToStr(Args: array of const): TIDLString;
 function LinesToStr(Args: array of const): TIDLString;
@@ -684,6 +686,61 @@ begin
   '']);
   '']);
 end;
 end;
 
 
+procedure TTestWebIDL2WasmJob.TestWJ_NamespaceAttribute_Boolean;
+begin
+  TestWebIDL([
+  'namespace Attr {',
+  '  readonly attribute boolean aBoolean;',
+  '};',
+  ''],
+  ['Type',
+  '  // Forward class definitions',
+  '  IJSAttr = interface;',
+  '  TJSAttr = class;',
+  '  { --------------------------------------------------------------------',
+  '    TJSAttr',
+  '    --------------------------------------------------------------------}',
+  '',
+  '  IJSAttr = interface(IJSObject)',
+  '    [''{AA94F48A-7955-3EBA-B086-85B24440AF2A}'']',
+  '    function _GetaBoolean: Boolean;',
+  '    property aBoolean: Boolean read _GetaBoolean;',
+  '  end;',
+  '',
+  '  TJSAttr = class(TJSObject,IJSAttr)',
+  '  Private',
+  '    function _GetaBoolean: Boolean;',
+  '  Public',
+  '    class function Cast(const Intf: IJSObject): IJSAttr;',
+  '    property aBoolean: Boolean read _GetaBoolean;',
+  '  end;',
+  '',
+  'var ',
+  '  Attr : IJSAttr;',
+  '',
+  'implementation',
+  '',
+  'function TJSAttr._GetaBoolean: Boolean;',
+  'begin',
+  '  Result:=ReadJSPropertyBoolean(''aBoolean'');',
+  'end;',
+  '',
+  'class function TJSAttr.Cast(const Intf: IJSObject): IJSAttr;',
+  'begin',
+  '  Result:=TJSAttr.JOBCast(Intf);',
+  'end;',
+  '',
+  'initialization',
+  '  Attr:=TJSAttr.JOBCreateGlobal(''Attr'');',
+  '',
+  'finalization',
+  '  Attr:=Nil;',
+  '',
+  'end.',
+  '']);
+
+end;
+
 initialization
 initialization
   RegisterTests([TTestWebIDL2Wasmjob]);
   RegisterTests([TTestWebIDL2Wasmjob]);