<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[204404] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/204404">204404</a></dd>
<dt>Author</dt> <dd>weinig@apple.com</dd>
<dt>Date</dt> <dd>2016-08-11 21:34:30 -0700 (Thu, 11 Aug 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Support WebIDL unions (Part 1)
https://bugs.webkit.org/show_bug.cgi?id=160769

Reviewed by Chris Dumez.

This is the first part of an effort to add support for union types
in our code generators. This change:
- Adds a domType struct to hold the parsed type information. For now, we only
  use it temporarily while parsing, and don't expose it to the code generators,
  but that will change in a later patch.
- Remove support for scoped identifiers for types. They are not supported by WebIDL.
- Make debugging the parser easier by providing backtraces when asserting.

There should be no observable changes.

* bindings/scripts/IDLParser.pm:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsIDLParserpm">trunk/Source/WebCore/bindings/scripts/IDLParser.pm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (204403 => 204404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-08-12 03:38:54 UTC (rev 204403)
+++ trunk/Source/WebCore/ChangeLog        2016-08-12 04:34:30 UTC (rev 204404)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2016-08-11  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        Support WebIDL unions (Part 1)
+        https://bugs.webkit.org/show_bug.cgi?id=160769
+
+        Reviewed by Chris Dumez.
+
+        This is the first part of an effort to add support for union types
+        in our code generators. This change:
+        - Adds a domType struct to hold the parsed type information. For now, we only
+          use it temporarily while parsing, and don't expose it to the code generators,
+          but that will change in a later patch.
+        - Remove support for scoped identifiers for types. They are not supported by WebIDL.
+        - Make debugging the parser easier by providing backtraces when asserting.
+
+        There should be no observable changes.
+
+        * bindings/scripts/IDLParser.pm:
+
</ins><span class="cx"> 2016-08-11  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Migrate from ints to unsigneds when referring to indices into strings
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsIDLParserpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/IDLParser.pm (204403 => 204404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/IDLParser.pm        2016-08-12 03:38:54 UTC (rev 204403)
+++ trunk/Source/WebCore/bindings/scripts/IDLParser.pm        2016-08-12 04:34:30 UTC (rev 204404)
</span><span class="lines">@@ -23,6 +23,9 @@
</span><span class="cx"> 
</span><span class="cx"> use strict;
</span><span class="cx"> 
</span><ins>+use Carp qw&lt;longmess&gt;;
+use Data::Dumper;
+
</ins><span class="cx"> use preprocessor;
</span><span class="cx"> use Class::Struct;
</span><span class="cx"> 
</span><span class="lines">@@ -74,17 +77,24 @@
</span><span class="cx">     signature =&gt; '$',         # Attribute signature
</span><span class="cx"> });
</span><span class="cx"> 
</span><ins>+struct( domType =&gt; {
+    name =&gt;         '$', # Type identifier
+    isNullable =&gt;   '$', # Is the type Nullable (T?)
+    isUnion =&gt;      '$', # Is the type a union (T or U)
+    subtypes =&gt;     '@', # Array of subtypes, only valid if isUnion or sequence
+});
+
</ins><span class="cx"> # Used to represent a map of 'variable name' &lt;-&gt; 'variable type'
</span><span class="cx"> struct( domSignature =&gt; {
</span><del>-    direction =&gt; '$', # Variable direction (in or out)
-    name =&gt; '$',      # Variable name
-    type =&gt; '$',      # Variable type
-    specials =&gt; '@',  # Specials
</del><ins>+    direction =&gt; '$',   # Variable direction (in or out)
+    name =&gt; '$',        # Variable name
+    type =&gt; '$'      ,  # Variable type
+    specials =&gt; '@',    # Specials
</ins><span class="cx">     extendedAttributes =&gt; '$', # Extended attributes
</span><del>-    isNullable =&gt; '$', # Is variable type Nullable (T?)
-    isVariadic =&gt; '$', # Is variable variadic (long... numbers)
-    isOptional =&gt; '$', # Is variable optional (optional T)
-    default =&gt; '$', # Default value for parameters
</del><ins>+    isNullable =&gt; '$',  # Is variable type Nullable (T?)
+    isVariadic =&gt; '$',  # Is variable variadic (long... numbers)
+    isOptional =&gt; '$',  # Is variable optional (optional T)
+    default =&gt; '$',     # Default value for parameters
</ins><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> # Used to represent Iterable interfaces
</span><span class="lines">@@ -96,12 +106,11 @@
</span><span class="cx">     extendedAttributes =&gt; '$', # Extended attributes
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> # Used to represent string constants
</span><span class="cx"> struct( domConstant =&gt; {
</span><del>-    name =&gt; '$',      # DOM Constant identifier
-    type =&gt; '$',      # Type of data
-    value =&gt; '$',      # Constant value
</del><ins>+    name =&gt; '$',        # DOM Constant identifier
+    type =&gt; '$',        # Type of data
+    value =&gt; '$',       # Constant value
</ins><span class="cx">     extendedAttributes =&gt; '$', # Extended attributes
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="lines">@@ -149,6 +158,16 @@
</span><span class="cx">     return bless $self, $class;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+sub assert
+{
+    my $message = shift;
+    
+    my $mess = longmess();
+    print Dumper($mess);
+
+    die $message;
+}
+
</ins><span class="cx"> sub assertTokenValue
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="lines">@@ -155,11 +174,12 @@
</span><span class="cx">     my $token = shift;
</span><span class="cx">     my $value = shift;
</span><span class="cx">     my $line = shift;
</span><del>-    my $msg = &quot;Next token should be &quot; . $value . &quot;, but &quot; . $token-&gt;value() . &quot; at &quot; . $self-&gt;{Line};
</del><ins>+    my $msg = &quot;Next token should be &quot; . $value . &quot;, but &quot; . $token-&gt;value() . &quot; on line &quot; . $self-&gt;{Line};
</ins><span class="cx">     if (defined ($line)) {
</span><span class="cx">         $msg .= &quot; IDLParser.pm:&quot; . $line;
</span><span class="cx">     }
</span><del>-    die $msg unless $token-&gt;value() eq $value;
</del><ins>+
+    assert $msg unless $token-&gt;value() eq $value;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> sub assertTokenType
</span><span class="lines">@@ -167,7 +187,8 @@
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $token = shift;
</span><span class="cx">     my $type = shift;
</span><del>-    die &quot;Next token's type should be &quot; . $type . &quot;, but &quot; . $token-&gt;type() . &quot; at &quot; . $self-&gt;{Line} unless $token-&gt;type() eq $type;
</del><ins>+    
+    assert &quot;Next token's type should be &quot; . $type . &quot;, but &quot; . $token-&gt;type() . &quot; on line &quot; . $self-&gt;{Line} unless $token-&gt;type() eq $type;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> sub assertUnexpectedToken
</span><span class="lines">@@ -175,11 +196,12 @@
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $token = shift;
</span><span class="cx">     my $line = shift;
</span><del>-    my $msg = &quot;Unexpected token &quot; . $token . &quot; at &quot; . $self-&gt;{Line};
</del><ins>+    my $msg = &quot;Unexpected token &quot; . $token . &quot; on line &quot; . $self-&gt;{Line};
</ins><span class="cx">     if (defined ($line)) {
</span><span class="cx">         $msg .= &quot; IDLParser.pm:&quot; . $line;
</span><span class="cx">     }
</span><del>-    die $msg;
</del><ins>+
+    assert $msg;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> sub assertNoExtendedAttributesInTypedef
</span><span class="lines">@@ -188,11 +210,12 @@
</span><span class="cx">     my $name = shift;
</span><span class="cx">     my $line = shift;
</span><span class="cx">     my $typedef = $typedefs{$name};
</span><del>-    my $msg = &quot;Unexpected extendedAttributeList in typedef \&quot;$name\&quot; at &quot; . $self-&gt;{Line};
</del><ins>+    my $msg = &quot;Unexpected extendedAttributeList in typedef \&quot;$name\&quot; on line &quot; . $self-&gt;{Line};
</ins><span class="cx">     if (defined ($line)) {
</span><span class="cx">         $msg .= &quot; IDLParser.pm:&quot; . $line;
</span><span class="cx">     }
</span><del>-    die $msg if %{$typedef-&gt;extendedAttributes};
</del><ins>+
+    assert $msg if %{$typedef-&gt;extendedAttributes};
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> sub Parse
</span><span class="lines">@@ -216,7 +239,7 @@
</span><span class="cx">         my $next = $self-&gt;nextToken();
</span><span class="cx">         $self-&gt;assertTokenType($next, EmptyToken);
</span><span class="cx">     };
</span><del>-    die $@ . &quot; in $fileName&quot; if $@;
</del><ins>+    assert $@ . &quot; in $fileName&quot; if $@;
</ins><span class="cx"> 
</span><span class="cx">     my $document = idlDocument-&gt;new();
</span><span class="cx">     $document-&gt;fileName($fileName);
</span><span class="lines">@@ -253,7 +276,7 @@
</span><span class="cx"> my $integerTokenPattern = '^(-?[1-9][0-9]*|-?0[Xx][0-9A-Fa-f]+|-?0[0-7]*)';
</span><span class="cx"> my $stringTokenPattern = '^(\&quot;[^\&quot;]*\&quot;)';
</span><span class="cx"> my $identifierTokenPattern = '^([A-Z_a-z][0-9A-Z_a-z]*)';
</span><del>-my $otherTokenPattern = '^(::|\.\.\.|[^\t\n\r 0-9A-Z_a-z])';
</del><ins>+my $otherTokenPattern = '^(\.\.\.|[^\t\n\r 0-9A-Z_a-z])';
</ins><span class="cx"> 
</span><span class="cx"> sub getTokenInternal
</span><span class="cx"> {
</span><span class="lines">@@ -318,21 +341,6 @@
</span><span class="cx">     die &quot;Failed to parse string (&quot; . $quotedString . &quot;) at &quot; . $self-&gt;{Line};
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub typeHasNullableSuffix
-{
-    my $type = shift;
-    return $type ? $type =~ /\?$/ : 0;
-}
-
-sub typeRemoveNullableSuffix
-{
-    my $type = shift;
-    if ($type) {
-        $type =~ s/\?//g;
-    }
-    return $type;
-}
-
</del><span class="cx"> sub identifierRemoveNullablePrefix
</span><span class="cx"> {
</span><span class="cx">     my $type = shift;
</span><span class="lines">@@ -343,26 +351,26 @@
</span><span class="cx"> my $nextAttribute_1 = '^(attribute|inherit|readonly)$';
</span><span class="cx"> my $nextPrimitiveType_1 = '^(int|long|short|unsigned)$';
</span><span class="cx"> my $nextPrimitiveType_2 = '^(double|float|unrestricted)$';
</span><del>-my $nextArgumentList_1 = '^(\(|::|ByteString|DOMString|USVString|Date|\[|any|boolean|byte|double|float|in|long|object|octet|optional|sequence|short|unrestricted|unsigned)$';
</del><ins>+my $nextArgumentList_1 = '^(\(|ByteString|DOMString|USVString|Date|\[|any|boolean|byte|double|float|in|long|object|octet|optional|sequence|short|unrestricted|unsigned)$';
</ins><span class="cx"> my $nextNonAnyType_1 = '^(boolean|byte|double|float|long|octet|short|unrestricted|unsigned)$';
</span><del>-my $nextInterfaceMember_1 = '^(\(|::|ByteString|DOMString|USVString|Date|any|attribute|boolean|byte|creator|deleter|double|float|getter|inherit|legacycaller|long|object|octet|readonly|sequence|serializer|setter|short|static|stringifier|unrestricted|unsigned|void)$';
</del><ins>+my $nextInterfaceMember_1 = '^(\(|ByteString|DOMString|USVString|Date|any|attribute|boolean|byte|creator|deleter|double|float|getter|inherit|legacycaller|long|object|octet|readonly|sequence|serializer|setter|short|static|stringifier|unrestricted|unsigned|void)$';
</ins><span class="cx"> my $nextAttributeOrOperation_1 = '^(static|stringifier)$';
</span><del>-my $nextAttributeOrOperation_2 = '^(\(|::|ByteString|DOMString|USVString|Date|any|boolean|byte|creator|deleter|double|float|getter|legacycaller|long|object|octet|sequence|setter|short|unrestricted|unsigned|void)$';
</del><ins>+my $nextAttributeOrOperation_2 = '^(\(|ByteString|DOMString|USVString|Date|any|boolean|byte|creator|deleter|double|float|getter|legacycaller|long|object|octet|sequence|setter|short|unrestricted|unsigned|void)$';
</ins><span class="cx"> my $nextUnrestrictedFloatType_1 = '^(double|float)$';
</span><del>-my $nextExtendedAttributeRest3_1 = '^(\,|::|\])$';
-my $nextExceptionField_1 = '^(\(|::|ByteString|DOMString|USVString|Date|any|boolean|byte|double|float|long|object|octet|sequence|short|unrestricted|unsigned)$';
-my $nextType_1 = '^(::|ByteString|DOMString|USVString|Date|any|boolean|byte|double|float|long|object|octet|sequence|short|unrestricted|unsigned)$';
</del><ins>+my $nextExtendedAttributeRest3_1 = '^(\,|\])$';
+my $nextExceptionField_1 = '^(\(|ByteString|DOMString|USVString|Date|any|boolean|byte|double|float|long|object|octet|sequence|short|unrestricted|unsigned)$';
+my $nextType_1 = '^(ByteString|DOMString|USVString|Date|any|boolean|byte|double|float|long|object|octet|sequence|short|unrestricted|unsigned)$';
</ins><span class="cx"> my $nextSpecials_1 = '^(creator|deleter|getter|legacycaller|setter)$';
</span><del>-my $nextDefinitions_1 = '^(::|callback|dictionary|enum|exception|interface|partial|typedef)$';
-my $nextExceptionMembers_1 = '^(\(|::|ByteString|DOMString|USVString|Date|\[|any|boolean|byte|const|double|float|long|object|octet|optional|sequence|short|unrestricted|unsigned)$';
</del><ins>+my $nextDefinitions_1 = '^(callback|dictionary|enum|exception|interface|partial|typedef)$';
+my $nextExceptionMembers_1 = '^(\(|ByteString|DOMString|USVString|Date|\[|any|boolean|byte|const|double|float|long|object|octet|optional|sequence|short|unrestricted|unsigned)$';
</ins><span class="cx"> my $nextAttributeRest_1 = '^(attribute|readonly)$';
</span><del>-my $nextInterfaceMembers_1 = '^(\(|::|ByteString|DOMString|USVString|Date|any|attribute|boolean|byte|const|creator|deleter|double|float|getter|inherit|legacycaller|long|object|octet|readonly|sequence|serializer|setter|short|static|stringifier|unrestricted|unsigned|void)$';
-my $nextSingleType_1 = '^(::|ByteString|DOMString|USVString|Date|boolean|byte|double|float|long|object|octet|sequence|short|unrestricted|unsigned)$';
</del><ins>+my $nextInterfaceMembers_1 = '^(\(|ByteString|DOMString|USVString|Date|any|attribute|boolean|byte|const|creator|deleter|double|float|getter|inherit|legacycaller|long|object|octet|readonly|sequence|serializer|setter|short|static|stringifier|unrestricted|unsigned|void)$';
+my $nextSingleType_1 = '^(ByteString|DOMString|USVString|Date|boolean|byte|double|float|long|object|octet|sequence|short|unrestricted|unsigned)$';
</ins><span class="cx"> my $nextArgumentName_1 = '^(attribute|callback|const|creator|deleter|dictionary|enum|exception|getter|implements|inherit|interface|legacycaller|partial|serializer|setter|static|stringifier|typedef|unrestricted)$';
</span><span class="cx"> my $nextConstValue_1 = '^(false|true)$';
</span><span class="cx"> my $nextConstValue_2 = '^(-|Infinity|NaN)$';
</span><span class="cx"> my $nextDefinition_1 = '^(callback|interface)$';
</span><del>-my $nextAttributeOrOperationRest_1 = '^(\(|::|ByteString|DOMString|USVString|Date|any|boolean|byte|double|float|long|object|octet|sequence|short|unrestricted|unsigned|void)$';
</del><ins>+my $nextAttributeOrOperationRest_1 = '^(\(|ByteString|DOMString|USVString|Date|any|boolean|byte|double|float|long|object|octet|sequence|short|unrestricted|unsigned|void)$';
</ins><span class="cx"> my $nextUnsignedIntegerType_1 = '^(long|short)$';
</span><span class="cx"> my $nextDefaultValue_1 = '^(-|Infinity|NaN|false|null|true)$';
</span><span class="cx"> 
</span><span class="lines">@@ -480,7 +488,7 @@
</span><span class="cx">     if ($next-&gt;value() eq &quot;typedef&quot;) {
</span><span class="cx">         return $self-&gt;parseTypedef($extendedAttributeList);
</span><span class="cx">     }
</span><del>-    if ($next-&gt;type() == IdentifierToken || $next-&gt;value() eq &quot;::&quot;) {
</del><ins>+    if ($next-&gt;type() == IdentifierToken) {
</ins><span class="cx">         return $self-&gt;parseImplementsStatement($extendedAttributeList);
</span><span class="cx">     }
</span><span class="cx">     $self-&gt;assertUnexpectedToken($next-&gt;value(), __LINE__);
</span><span class="lines">@@ -687,13 +695,10 @@
</span><span class="cx">             $member-&gt;isOptional(0);
</span><span class="cx">         }
</span><span class="cx">         $member-&gt;extendedAttributes($extendedAttributeList);
</span><ins>+
</ins><span class="cx">         my $type = $self-&gt;parseType();
</span><del>-        if (typeHasNullableSuffix($type)) {
-            $member-&gt;isNullable(1);
-        } else {
-            $member-&gt;isNullable(0);
-        }
-        $member-&gt;type(typeRemoveNullableSuffix($type));
</del><ins>+        $member-&gt;type($type-&gt;name);
+        $member-&gt;isNullable($type-&gt;isNullable);
</ins><span class="cx"> 
</span><span class="cx">         my $nameToken = $self-&gt;getToken();
</span><span class="cx">         $self-&gt;assertTokenType($nameToken, IdentifierToken);
</span><span class="lines">@@ -806,9 +811,10 @@
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><span class="cx">     if ($next-&gt;value() eq &quot;:&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;:&quot;, __LINE__);
</span><del>-        my $scopedName = $self-&gt;parseScopedName();
-        push(@parent, $scopedName);
-        # Multiple inheritance (needed for ObjC bindings).
</del><ins>+        my $name = $self-&gt;parseName();
+        push(@parent, $name);
+
+        # FIXME: Remove. Was needed for needed for ObjC bindings.
</ins><span class="cx">         push(@parent, @{$self-&gt;parseIdentifiers()});
</span><span class="cx">     }
</span><span class="cx">     return \@parent;
</span><span class="lines">@@ -900,7 +906,10 @@
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;typedef&quot;, __LINE__);
</span><span class="cx">         my $typedef = Typedef-&gt;new();
</span><span class="cx">         $typedef-&gt;extendedAttributes($self-&gt;parseExtendedAttributeListAllowEmpty());
</span><del>-        $typedef-&gt;type($self-&gt;parseType());
</del><ins>+
+        my $type = $self-&gt;parseType();
+        $typedef-&gt;type($type-&gt;name);
+
</ins><span class="cx">         my $nameToken = $self-&gt;getToken();
</span><span class="cx">         $self-&gt;assertTokenType($nameToken, IdentifierToken);
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;;&quot;, __LINE__);
</span><span class="lines">@@ -919,9 +928,9 @@
</span><span class="cx"> 
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><span class="cx">     if ($next-&gt;type() == IdentifierToken) {
</span><del>-        $self-&gt;parseScopedName();
</del><ins>+        $self-&gt;parseName();
</ins><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;implements&quot;, __LINE__);
</span><del>-        $self-&gt;parseScopedName();
</del><ins>+        $self-&gt;parseName();
</ins><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;;&quot;, __LINE__);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -937,7 +946,10 @@
</span><span class="cx">     if ($next-&gt;value() eq &quot;const&quot;) {
</span><span class="cx">         my $newDataNode = domConstant-&gt;new();
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;const&quot;, __LINE__);
</span><del>-        $newDataNode-&gt;type($self-&gt;parseConstType());
</del><ins>+        
+        my $type = $self-&gt;parseConstType();
+        $newDataNode-&gt;type($type-&gt;name);
+
</ins><span class="cx">         my $constNameToken = $self-&gt;getToken();
</span><span class="cx">         $self-&gt;assertTokenType($constNameToken, IdentifierToken);
</span><span class="cx">         $newDataNode-&gt;name(identifierRemoveNullablePrefix($constNameToken-&gt;value()));
</span><span class="lines">@@ -1185,12 +1197,8 @@
</span><span class="cx">         my $returnType = $self-&gt;parseReturnType();
</span><span class="cx">         my $interface = $self-&gt;parseOperationRest($extendedAttributeList);
</span><span class="cx">         if (defined ($interface)) {
</span><del>-            if (typeHasNullableSuffix($returnType)) {
-                $interface-&gt;signature-&gt;isNullable(1);
-            } else {
-                $interface-&gt;signature-&gt;isNullable(0);
-            }
-            $interface-&gt;signature-&gt;type(typeRemoveNullableSuffix($returnType));
</del><ins>+            $interface-&gt;signature-&gt;type($returnType-&gt;name);
+            $interface-&gt;signature-&gt;isNullable($returnType-&gt;isNullable);
</ins><span class="cx">         }
</span><span class="cx">         return $interface;
</span><span class="cx">     }
</span><span class="lines">@@ -1226,14 +1234,11 @@
</span><span class="cx">         }
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;attribute&quot;, __LINE__);
</span><span class="cx">         $newDataNode-&gt;signature(domSignature-&gt;new());
</span><ins>+        
</ins><span class="cx">         my $type = $self-&gt;parseType();
</span><del>-        if (typeHasNullableSuffix($type)) {
-            $newDataNode-&gt;signature-&gt;isNullable(1);
-        } else {
-            $newDataNode-&gt;signature-&gt;isNullable(0);
-        }
-        # Remove all &quot;?&quot; in the type declaration, e.g. &quot;double?&quot; -&gt; &quot;double&quot;.
-        $newDataNode-&gt;signature-&gt;type(typeRemoveNullableSuffix($type));
</del><ins>+        $newDataNode-&gt;signature-&gt;type($type-&gt;name);
+        $newDataNode-&gt;signature-&gt;isNullable($type-&gt;isNullable);
+
</ins><span class="cx">         my $token = $self-&gt;getToken();
</span><span class="cx">         $self-&gt;assertTokenType($token, IdentifierToken);
</span><span class="cx">         $newDataNode-&gt;signature-&gt;name(identifierRemoveNullablePrefix($token-&gt;value()));
</span><span class="lines">@@ -1288,12 +1293,8 @@
</span><span class="cx">         my $next = $self-&gt;nextToken();
</span><span class="cx">         if ($next-&gt;type() == IdentifierToken || $next-&gt;value() eq &quot;(&quot;) {
</span><span class="cx">             my $operation = $self-&gt;parseOperationRest($extendedAttributeList);
</span><del>-            if (typeHasNullableSuffix($returnType)) {
-                $operation-&gt;signature-&gt;isNullable(1);
-            } else {
-                $operation-&gt;signature-&gt;isNullable(0);
-            }
-            $operation-&gt;signature-&gt;type(typeRemoveNullableSuffix($returnType));
</del><ins>+            $operation-&gt;signature-&gt;type($returnType-&gt;name);
+            $operation-&gt;signature-&gt;isNullable($returnType-&gt;isNullable);
</ins><span class="cx"> 
</span><span class="cx">             return $operation;
</span><span class="cx">         }
</span><span class="lines">@@ -1313,13 +1314,8 @@
</span><span class="cx">         my $returnType = $self-&gt;parseReturnType();
</span><span class="cx">         my $interface = $self-&gt;parseOperationRest($extendedAttributeList);
</span><span class="cx">         if (defined ($interface)) {
</span><del>-            if (typeHasNullableSuffix($returnType)) {
-                $interface-&gt;signature-&gt;isNullable(1);
-            } else {
-                $interface-&gt;signature-&gt;isNullable(0);
-            }
-            $interface-&gt;signature-&gt;type(typeRemoveNullableSuffix($returnType));
-
</del><ins>+            $interface-&gt;signature-&gt;type($returnType-&gt;name);
+            $interface-&gt;signature-&gt;isNullable($returnType-&gt;isNullable);
</ins><span class="cx">             $interface-&gt;signature-&gt;specials(\@specials);
</span><span class="cx">         }
</span><span class="cx">         return $interface;
</span><span class="lines">@@ -1530,15 +1526,10 @@
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><span class="cx">     if ($next-&gt;value() eq &quot;optional&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;optional&quot;, __LINE__);
</span><ins>+
</ins><span class="cx">         my $type = $self-&gt;parseType();
</span><del>-        # domDataNode can only consider last &quot;?&quot;.
-        if (typeHasNullableSuffix($type)) {
-            $paramDataNode-&gt;isNullable(1);
-        } else {
-            $paramDataNode-&gt;isNullable(0);
-        }
-        # Remove &quot;?&quot; if exists, e.g. &quot;object?&quot; -&gt; &quot;object&quot;.
-        $paramDataNode-&gt;type(identifierRemoveNullablePrefix(typeRemoveNullableSuffix($type)));
</del><ins>+        $paramDataNode-&gt;type(identifierRemoveNullablePrefix($type-&gt;name));
+        $paramDataNode-&gt;isNullable($type-&gt;isNullable);
</ins><span class="cx">         $paramDataNode-&gt;isOptional(1);
</span><span class="cx">         $paramDataNode-&gt;name($self-&gt;parseArgumentName());
</span><span class="cx">         $paramDataNode-&gt;default($self-&gt;parseDefault());
</span><span class="lines">@@ -1546,14 +1537,8 @@
</span><span class="cx">     }
</span><span class="cx">     if ($next-&gt;type() == IdentifierToken || $next-&gt;value() =~ /$nextExceptionField_1/) {
</span><span class="cx">         my $type = $self-&gt;parseType();
</span><del>-        # domDataNode can only consider last &quot;?&quot;.
-        if (typeHasNullableSuffix($type)) {
-            $paramDataNode-&gt;isNullable(1);
-        } else {
-            $paramDataNode-&gt;isNullable(0);
-        }
-        # Remove &quot;?&quot; if exists, e.g. &quot;object?&quot; -&gt; &quot;object&quot;.
-        $paramDataNode-&gt;type(typeRemoveNullableSuffix($type));
</del><ins>+        $paramDataNode-&gt;type($type-&gt;name);
+        $paramDataNode-&gt;isNullable($type-&gt;isNullable);
</ins><span class="cx">         $paramDataNode-&gt;isOptional(0);
</span><span class="cx">         $paramDataNode-&gt;isVariadic($self-&gt;parseEllipsis());
</span><span class="cx">         $paramDataNode-&gt;name($self-&gt;parseArgumentName());
</span><span class="lines">@@ -1612,7 +1597,11 @@
</span><span class="cx">         $newDataNode-&gt;type(&quot;attribute&quot;);
</span><span class="cx">         $newDataNode-&gt;isReadOnly(1);
</span><span class="cx">         $newDataNode-&gt;signature(domSignature-&gt;new());
</span><del>-        $newDataNode-&gt;signature-&gt;type($self-&gt;parseType());
</del><ins>+
+        my $type = $self-&gt;parseType();
+        $newDataNode-&gt;signature-&gt;type($type-&gt;name);
+        $newDataNode-&gt;signature-&gt;isNullable($type-&gt;isNullable);
+        
</ins><span class="cx">         my $token = $self-&gt;getToken();
</span><span class="cx">         $self-&gt;assertTokenType($token, IdentifierToken);
</span><span class="cx">         $newDataNode-&gt;signature-&gt;name(identifierRemoveNullablePrefix($token-&gt;value()));
</span><span class="lines">@@ -1698,9 +1687,9 @@
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><del>-    if ($next-&gt;type() == IdentifierToken || $next-&gt;value() eq &quot;::&quot;) {
-        my $scopedName = $self-&gt;parseScopedName();
-        return $self-&gt;parseExtendedAttributeRest($scopedName);
</del><ins>+    if ($next-&gt;type() == IdentifierToken) {
+        my $name = $self-&gt;parseName();
+        return $self-&gt;parseExtendedAttributeRest($name);
</ins><span class="cx">     }
</span><span class="cx">     # backward compatibility. Spec doesn' allow &quot;[]&quot;. But WebKit requires.
</span><span class="cx">     if ($next-&gt;value() eq ']') {
</span><span class="lines">@@ -1713,9 +1702,9 @@
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><del>-    if ($next-&gt;type() == IdentifierToken || $next-&gt;value() eq &quot;::&quot;) {
-        my $scopedName = $self-&gt;parseScopedName();
-        return $self-&gt;parseExtendedAttributeRest($scopedName);
</del><ins>+    if ($next-&gt;type() == IdentifierToken) {
+        my $name = $self-&gt;parseName();
+        return $self-&gt;parseExtendedAttributeRest($name);
</ins><span class="cx">     }
</span><span class="cx">     return {};
</span><span class="cx"> }
</span><span class="lines">@@ -1757,9 +1746,9 @@
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;)&quot;, __LINE__);
</span><span class="cx">         return @arguments;
</span><span class="cx">     }
</span><del>-    if ($next-&gt;type() == IdentifierToken || $next-&gt;value() eq &quot;::&quot;) {
-        my $scopedName = $self-&gt;parseScopedName();
-        return $self-&gt;parseExtendedAttributeRest3($scopedName);
</del><ins>+    if ($next-&gt;type() == IdentifierToken) {
+        my $name = $self-&gt;parseName();
+        return $self-&gt;parseExtendedAttributeRest3($name);
</ins><span class="cx">     }
</span><span class="cx">     if ($next-&gt;type() == IntegerToken) {
</span><span class="cx">         my $token = $self-&gt;getToken();
</span><span class="lines">@@ -1776,12 +1765,12 @@
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><span class="cx">     if ($next-&gt;value() eq &quot;&amp;&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&amp;&quot;, __LINE__);
</span><del>-        my $rightValue = $self-&gt;parseScopedName();
</del><ins>+        my $rightValue = $self-&gt;parseName();
</ins><span class="cx">         return $name . &quot;&amp;&quot; . $rightValue;
</span><span class="cx">     }
</span><span class="cx">     if ($next-&gt;value() eq &quot;|&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;|&quot;, __LINE__);
</span><del>-        my $rightValue = $self-&gt;parseScopedName();
</del><ins>+        my $rightValue = $self-&gt;parseName();
</ins><span class="cx">         return $name . &quot;|&quot; . $rightValue;
</span><span class="cx">     }
</span><span class="cx">     if ($next-&gt;value() eq &quot;(&quot;) {
</span><span class="lines">@@ -1792,30 +1781,12 @@
</span><span class="cx">         return $attr;
</span><span class="cx">     }
</span><span class="cx">     if ($next-&gt;type() == IdentifierToken || $next-&gt;value() =~ /$nextExtendedAttributeRest3_1/) {
</span><del>-        my @names = ();
-        push(@names, $name);
-        push(@names, @{$self-&gt;parseScopedNameListNoComma()});
-        return join(' ', @names);
</del><ins>+        $self-&gt;parseNameNoComma();
+        return $name;
</ins><span class="cx">     }
</span><span class="cx">     $self-&gt;assertUnexpectedToken($next-&gt;value());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub parseScopedNameListNoComma
-{
-    my $self = shift;
-    my @names = ();
-
-    while (1) {
-        my $next = $self-&gt;nextToken();
-        if ($next-&gt;type() == IdentifierToken || $next-&gt;value() eq &quot;::&quot;) {
-            push(@names, $self-&gt;parseScopedName());
-        } else {
-            last;
-        }
-    }
-    return \@names;
-}
-
</del><span class="cx"> sub parseArgumentNameKeyword
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="lines">@@ -1888,9 +1859,7 @@
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><span class="cx">     if ($next-&gt;value() eq &quot;(&quot;) {
</span><del>-        $self-&gt;parseUnionType();
-        $self-&gt;parseTypeSuffix();
-        return;
</del><ins>+        return $self-&gt;parseUnionType();
</ins><span class="cx">     }
</span><span class="cx">     if ($next-&gt;type() == IdentifierToken || $next-&gt;value() =~ /$nextType_1/) {
</span><span class="cx">         return $self-&gt;parseSingleType();
</span><span class="lines">@@ -1904,10 +1873,15 @@
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><span class="cx">     if ($next-&gt;value() eq &quot;any&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;any&quot;, __LINE__);
</span><del>-        return &quot;any&quot;;
</del><ins>+        
+        my $anyType = domType-&gt;new();
+        $anyType-&gt;name(&quot;any&quot;);
+        return $anyType;
</ins><span class="cx">     }
</span><span class="cx">     if ($next-&gt;type() == IdentifierToken || $next-&gt;value() =~ /$nextSingleType_1/) {
</span><del>-        return $self-&gt;parseNonAnyType();
</del><ins>+        my $nonAnyType = $self-&gt;parseNonAnyType();
+        $nonAnyType-&gt;isNullable($self-&gt;parseNull());
+        return $nonAnyType;
</ins><span class="cx">     }
</span><span class="cx">     $self-&gt;assertUnexpectedToken($next-&gt;value(), __LINE__);
</span><span class="cx"> }
</span><span class="lines">@@ -1916,14 +1890,24 @@
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><ins>+
+    my $unionType = domType-&gt;new();
+    $unionType-&gt;name(&quot;UNION&quot;);
+    $unionType-&gt;isUnion(1);
+
</ins><span class="cx">     if ($next-&gt;value() eq &quot;(&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;(&quot;, __LINE__);
</span><del>-        $self-&gt;parseUnionMemberType();
</del><ins>+        
+        push(@{$unionType-&gt;subtypes}, $self-&gt;parseUnionMemberType());
+        
</ins><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;or&quot;, __LINE__);
</span><del>-        $self-&gt;parseUnionMemberType();
-        $self-&gt;parseUnionMemberTypes();
</del><ins>+        
+        push(@{$unionType-&gt;subtypes}, $self-&gt;parseUnionMemberType());
+        push(@{$unionType-&gt;subtypes}, $self-&gt;parseUnionMemberTypes());
+        
</ins><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;)&quot;, __LINE__);
</span><del>-        return;
</del><ins>+
+        return $unionType;
</ins><span class="cx">     }
</span><span class="cx">     $self-&gt;assertUnexpectedToken($next-&gt;value(), __LINE__);
</span><span class="cx"> }
</span><span class="lines">@@ -1933,20 +1917,14 @@
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><span class="cx">     if ($next-&gt;value() eq &quot;(&quot;) {
</span><del>-        $self-&gt;parseUnionType();
-        $self-&gt;parseTypeSuffix();
-        return;
</del><ins>+        my $unionType = $self-&gt;parseUnionType();
+        $unionType-&gt;isNullable($self-&gt;parseNull());
+        return $unionType;
</ins><span class="cx">     }
</span><del>-    if ($next-&gt;value() eq &quot;any&quot;) {
-        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;any&quot;, __LINE__);
-        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;[&quot;, __LINE__);
-        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;]&quot;, __LINE__);
-        $self-&gt;parseTypeSuffix();
-        return;
-    }
</del><span class="cx">     if ($next-&gt;type() == IdentifierToken || $next-&gt;value() =~ /$nextSingleType_1/) {
</span><del>-        $self-&gt;parseNonAnyType();
-        return;
</del><ins>+        my $nonAnyType = $self-&gt;parseNonAnyType();
+        $nonAnyType-&gt;isNullable($self-&gt;parseNull());
+        return $nonAnyType;
</ins><span class="cx">     }
</span><span class="cx">     $self-&gt;assertUnexpectedToken($next-&gt;value(), __LINE__);
</span><span class="cx"> }
</span><span class="lines">@@ -1955,11 +1933,16 @@
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><ins>+
+    my @subtypes = ();
+
</ins><span class="cx">     if ($next-&gt;value() eq &quot;or&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;or&quot;, __LINE__);
</span><del>-        $self-&gt;parseUnionMemberType();
-        $self-&gt;parseUnionMemberTypes();
</del><ins>+        push(@subtypes, $self-&gt;parseUnionMemberType());
+        push(@subtypes, $self-&gt;parseUnionMemberTypes());
</ins><span class="cx">     }
</span><ins>+
+    return @subtypes;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> sub parseNonAnyType
</span><span class="lines">@@ -1966,41 +1949,82 @@
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><ins>+
+    my $type = domType-&gt;new();
+
</ins><span class="cx">     if ($next-&gt;value() =~ /$nextNonAnyType_1/) {
</span><del>-        return $self-&gt;parsePrimitiveType() . $self-&gt;parseTypeSuffix();
</del><ins>+        $type-&gt;name($self-&gt;parsePrimitiveType());
+        return $type;
</ins><span class="cx">     }
</span><span class="cx">     if ($next-&gt;value() eq &quot;ByteString&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;ByteString&quot;, __LINE__);
</span><del>-        return &quot;ByteString&quot; . $self-&gt;parseTypeSuffix();
</del><ins>+
+        $type-&gt;name(&quot;ByteString&quot;);
+        return $type;
</ins><span class="cx">     }
</span><span class="cx">     if ($next-&gt;value() eq &quot;DOMString&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;DOMString&quot;, __LINE__);
</span><del>-        return &quot;DOMString&quot; . $self-&gt;parseTypeSuffix();
</del><ins>+
+        $type-&gt;name(&quot;DOMString&quot;);
+        return $type;
</ins><span class="cx">     }
</span><span class="cx">     if ($next-&gt;value() eq &quot;USVString&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;USVString&quot;, __LINE__);
</span><del>-        return &quot;USVString&quot; . $self-&gt;parseTypeSuffix();
</del><ins>+
+        $type-&gt;name(&quot;USVString&quot;);
+        return $type;
</ins><span class="cx">     }
</span><del>-    
-    if ($next-&gt;value() eq &quot;sequence&quot;) {
-        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;sequence&quot;, __LINE__);
-        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&lt;&quot;, __LINE__);
-        my $type = $self-&gt;parseType();
-        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&gt;&quot;, __LINE__);
-        return &quot;sequence&lt;&quot; . $type . &quot;&gt;&quot; . $self-&gt;parseNull();
-    }
</del><span class="cx">     if ($next-&gt;value() eq &quot;object&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;object&quot;, __LINE__);
</span><del>-        return &quot;object&quot; . $self-&gt;parseTypeSuffix();
</del><ins>+
+        $type-&gt;name(&quot;object&quot;);
+        return $type;
</ins><span class="cx">     }
</span><ins>+    if ($next-&gt;value() eq &quot;RegExp&quot;) {
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;RegExp&quot;, __LINE__);
+
+        $type-&gt;name(&quot;RegExp&quot;);
+        return $type;
+    }
+    if ($next-&gt;value() eq &quot;Error&quot;) {
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;Error&quot;, __LINE__);
+
+        $type-&gt;name(&quot;Error&quot;);
+        return $type;
+    }
+    if ($next-&gt;value() eq &quot;DOMException&quot;) {
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;DOMException&quot;, __LINE__);
+
+        $type-&gt;name(&quot;DOMException&quot;);
+        return $type;
+    }
</ins><span class="cx">     if ($next-&gt;value() eq &quot;Date&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;Date&quot;, __LINE__);
</span><del>-        return &quot;Date&quot; . $self-&gt;parseTypeSuffix();
</del><ins>+
+        $type-&gt;name(&quot;Date&quot;);
+        return $type;
</ins><span class="cx">     }
</span><del>-    if ($next-&gt;type() == IdentifierToken || $next-&gt;value() eq &quot;::&quot;) {
-        my $name = identifierRemoveNullablePrefix($self-&gt;parseScopedName());
-        return $name . $self-&gt;parseTypeSuffix();
</del><ins>+    if ($next-&gt;value() eq &quot;sequence&quot;) {
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;sequence&quot;, __LINE__);
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&lt;&quot;, __LINE__);
+
+        my $subtype = $self-&gt;parseType();
+        my $subtypeName = $subtype-&gt;name;
+
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&gt;&quot;, __LINE__);
+
+        # FIXME: This should just be &quot;sequence&quot; when we start using domTypes in the CodeGenerators
+        $type-&gt;name(&quot;sequence&lt;${subtypeName}&gt;&quot;);
+        push(@{$type-&gt;subtypes}, $subtype);
+
+        return $type;
</ins><span class="cx">     }
</span><ins>+    if ($next-&gt;type() == IdentifierToken) {
+        my $identifier = $self-&gt;getToken();
+
+        $type-&gt;name(identifierRemoveNullablePrefix($identifier-&gt;value()));
+        return $type;
+    }
</ins><span class="cx">     $self-&gt;assertUnexpectedToken($next-&gt;value(), __LINE__);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -2008,12 +2032,21 @@
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><ins>+
+    my $type = domType-&gt;new();
+
</ins><span class="cx">     if ($next-&gt;value() =~ /$nextNonAnyType_1/) {
</span><del>-        return $self-&gt;parsePrimitiveType() . $self-&gt;parseNull();
</del><ins>+        $type-&gt;name($self-&gt;parsePrimitiveType());
+        $type-&gt;isNullable($self-&gt;parseNull());
+        return $type;
</ins><span class="cx">     }
</span><span class="cx">     if ($next-&gt;type() == IdentifierToken) {
</span><del>-        my $token = $self-&gt;getToken();
-        return $token-&gt;value() . $self-&gt;parseNull();
</del><ins>+        my $identifier = $self-&gt;getToken();
+        
+        $type-&gt;name($identifier-&gt;value());
+        $type-&gt;isNullable($self-&gt;parseNull());
+
+        return $type;
</ins><span class="cx">     }
</span><span class="cx">     $self-&gt;assertUnexpectedToken($next-&gt;value(), __LINE__);
</span><span class="cx"> }
</span><span class="lines">@@ -2119,17 +2152,6 @@
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub parseTypeSuffix
-{
-    my $self = shift;
-    my $next = $self-&gt;nextToken();
-    if ($next-&gt;value() eq &quot;?&quot;) {
-        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;?&quot;, __LINE__);
-        return &quot;?&quot;;
-    }
-    return &quot;&quot;;
-}
-
</del><span class="cx"> sub parseNull
</span><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="lines">@@ -2136,9 +2158,9 @@
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><span class="cx">     if ($next-&gt;value() eq &quot;?&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;?&quot;, __LINE__);
</span><del>-        return &quot;?&quot;;
</del><ins>+        return 1;
</ins><span class="cx">     }
</span><del>-    return &quot;&quot;;
</del><ins>+    return 0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> sub parseReturnType
</span><span class="lines">@@ -2147,7 +2169,10 @@
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><span class="cx">     if ($next-&gt;value() eq &quot;void&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;void&quot;, __LINE__);
</span><del>-        return &quot;void&quot;;
</del><ins>+        
+        my $voidType = domType-&gt;new();
+        $voidType-&gt;name(&quot;void&quot;);
+        return $voidType;
</ins><span class="cx">     }
</span><span class="cx">     if ($next-&gt;type() == IdentifierToken || $next-&gt;value() =~ /$nextExceptionField_1/) {
</span><span class="cx">         return $self-&gt;parseType();
</span><span class="lines">@@ -2175,93 +2200,30 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub parseScopedName
</del><ins>+sub parseNameNoComma
</ins><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><del>-    if ($next-&gt;value() eq &quot;::&quot;) {
-        return $self-&gt;parseAbsoluteScopedName();
-    }
</del><span class="cx">     if ($next-&gt;type() == IdentifierToken) {
</span><del>-        return $self-&gt;parseRelativeScopedName();
</del><ins>+        my $identifier = $self-&gt;getToken();
+        return ($identifier-&gt;value());
</ins><span class="cx">     }
</span><del>-    $self-&gt;assertUnexpectedToken($next-&gt;value());
-}
</del><span class="cx"> 
</span><del>-sub parseAbsoluteScopedName
-{
-    my $self = shift;
-    my $next = $self-&gt;nextToken();
-    if ($next-&gt;value() eq &quot;::&quot;) {
-        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;::&quot;);
-        my $token = $self-&gt;getToken();
-        $self-&gt;assertTokenType($token, IdentifierToken);
-        return &quot;::&quot; . $token-&gt;value() . $self-&gt;parseScopedNameParts();
-    }
-    $self-&gt;assertUnexpectedToken($next-&gt;value());
</del><ins>+    return ();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub parseRelativeScopedName
</del><ins>+sub parseName
</ins><span class="cx"> {
</span><span class="cx">     my $self = shift;
</span><span class="cx">     my $next = $self-&gt;nextToken();
</span><span class="cx">     if ($next-&gt;type() == IdentifierToken) {
</span><del>-        my $token = $self-&gt;getToken();
-        return $token-&gt;value() . $self-&gt;parseScopedNameParts();
</del><ins>+        my $identifier = $self-&gt;getToken();
+        return $identifier-&gt;value();
</ins><span class="cx">     }
</span><span class="cx">     $self-&gt;assertUnexpectedToken($next-&gt;value());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub parseScopedNameParts
-{
-    my $self = shift;
-    my @names = ();
</del><span class="cx"> 
</span><del>-    while (1) {
-        my $next = $self-&gt;nextToken();
-        if ($next-&gt;value() eq &quot;::&quot;) {
-            $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;::&quot;);
-            push(@names, &quot;::&quot;);
-            my $token = $self-&gt;getToken();
-            $self-&gt;assertTokenType($token, IdentifierToken);
-            push(@names, $token-&gt;value());
-        } else {
-            last;
-        }
-    }
-    return join(&quot;&quot;, @names);
-}
-
-sub parseScopedNameList
-{
-    my $self = shift;
-    my $next = $self-&gt;nextToken();
-    if ($next-&gt;type() == IdentifierToken || $next-&gt;value() eq &quot;::&quot;) {
-        my @names = ();
-        push(@names, $self-&gt;parseScopedName());
-        push(@names, @{$self-&gt;parseScopedNames()});
-        return \@names;
-    }
-    $self-&gt;assertUnexpectedToken($next-&gt;value(), __LINE__);
-}
-
-sub parseScopedNames
-{
-    my $self = shift;
-    my @names = ();
-
-    while (1) {
-        my $next = $self-&gt;nextToken();
-        if ($next-&gt;value() eq &quot;,&quot;) {
-            $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;,&quot;);
-            push(@names, $self-&gt;parseScopedName());
-        } else {
-            last;
-        }
-    }
-    return \@names;
-}
-
</del><span class="cx"> sub applyMemberList
</span><span class="cx"> {
</span><span class="cx">     my $interface = shift;
</span></span></pre>
</div>
</div>

</body>
</html>