| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 # |  | 
| 2 # KDOM IDL parser |  | 
| 3 # |  | 
| 4 # Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org> |  | 
| 5 # |  | 
| 6 # This library is free software; you can redistribute it and/or |  | 
| 7 # modify it under the terms of the GNU Library General Public |  | 
| 8 # License as published by the Free Software Foundation; either |  | 
| 9 # version 2 of the License, or (at your option) any later version. |  | 
| 10 # |  | 
| 11 # This library is distributed in the hope that it will be useful, |  | 
| 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of |  | 
| 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU |  | 
| 14 # Library General Public License for more details. |  | 
| 15 # |  | 
| 16 # You should have received a copy of the GNU Library General Public License |  | 
| 17 # along with this library; see the file COPYING.LIB.  If not, write to |  | 
| 18 # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |  | 
| 19 # Boston, MA 02110-1301, USA. |  | 
| 20 # |  | 
| 21 |  | 
| 22 package deprecated_idl_parser; |  | 
| 23 |  | 
| 24 use strict; |  | 
| 25 |  | 
| 26 use preprocessor; |  | 
| 27 use Class::Struct; |  | 
| 28 |  | 
| 29 use constant StringToken => 0; |  | 
| 30 use constant IntegerToken => 1; |  | 
| 31 use constant FloatToken => 2; |  | 
| 32 use constant IdentifierToken => 3; |  | 
| 33 use constant OtherToken => 4; |  | 
| 34 use constant EmptyToken => 5; |  | 
| 35 |  | 
| 36 # Used to represent a parsed IDL document |  | 
| 37 struct( idlDocument => { |  | 
| 38     fileName => '$', # file name |  | 
| 39     callbackFunctions => '@', |  | 
| 40     enumerations => '@', # All parsed enumerations |  | 
| 41     interfaces => '@', # All parsed interfaces |  | 
| 42 }); |  | 
| 43 |  | 
| 44 struct( callbackFunction => { |  | 
| 45     name => '$', |  | 
| 46     type => '$', |  | 
| 47     parameters => '@', |  | 
| 48 }); |  | 
| 49 |  | 
| 50 # Used to represent 'interface' blocks |  | 
| 51 struct( domInterface => { |  | 
| 52     name => '$',      # Class identifier |  | 
| 53     parent => '$',      # Parent class identifier |  | 
| 54     constants => '@',    # List of 'domConstant' |  | 
| 55     functions => '@',    # List of 'domFunction' |  | 
| 56     attributes => '@',    # List of 'domAttribute' |  | 
| 57     extendedAttributes => '$', # Extended attributes |  | 
| 58     constructors => '@', # Constructors, list of 'domFunction' |  | 
| 59     customConstructors => '@', # Custom constructors, list of 'domFunction' |  | 
| 60     isException => '$', # Used for exception interfaces |  | 
| 61     isCallback => '$', # Used for callback interfaces |  | 
| 62     isPartial => '$', # Used for partial interfaces |  | 
| 63 }); |  | 
| 64 |  | 
| 65 # Used to represent domInterface contents |  | 
| 66 struct( domFunction => { |  | 
| 67     isStatic => '$', |  | 
| 68     name => '$', |  | 
| 69     type => '$', |  | 
| 70     extendedAttributes => '$', # Extended attributes |  | 
| 71     specials => '@',  # Specials |  | 
| 72     parameters => '@',    # List of 'domParameter' |  | 
| 73     overloadedIndex => '$', |  | 
| 74 }); |  | 
| 75 |  | 
| 76 # Used to represent domInterface contents |  | 
| 77 struct( domAttribute => { |  | 
| 78     type => '$',              # Attribute type (including namespace) (string or 
      UnionType) |  | 
| 79     name => '$', |  | 
| 80     isNullable => '$', # Is variable type Nullable (T?) |  | 
| 81     isStatic => '$', |  | 
| 82     isReadOnly => '$', |  | 
| 83     getterExceptions => '@',  # Possibly raised exceptions. |  | 
| 84     setterExceptions => '@',  # Possibly raised exceptions. |  | 
| 85     extendedAttributes => '$', # Extended attributes |  | 
| 86 }); |  | 
| 87 |  | 
| 88 # Used to represent a map of 'variable name' <-> 'variable type' |  | 
| 89 struct( domParameter => { |  | 
| 90     name => '$',      # Variable name |  | 
| 91     type => '$',      # Variable type (string or UnionType) |  | 
| 92     extendedAttributes => '$', # Extended attributes |  | 
| 93     isOptional => '$', # Is variable optional (optional T) |  | 
| 94     isNullable => '$', # Is variable type Nullable (T?) |  | 
| 95     isVariadic => '$' # Is variable variadic (long... numbers) |  | 
| 96 }); |  | 
| 97 |  | 
| 98 # Used to represent string constants |  | 
| 99 struct( domConstant => { |  | 
| 100     name => '$',      # DOM Constant identifier |  | 
| 101     type => '$',      # Type of data |  | 
| 102     value => '$',      # Constant value |  | 
| 103     extendedAttributes => '$', # Extended attributes |  | 
| 104 }); |  | 
| 105 |  | 
| 106 # Used to represent 'enum' definitions |  | 
| 107 struct( domEnum => { |  | 
| 108     name => '$', # Enumeration identifier |  | 
| 109     values => '@', # Enumeration values (list of unique strings) |  | 
| 110 }); |  | 
| 111 |  | 
| 112 struct( Token => { |  | 
| 113     type => '$', # type of token |  | 
| 114     value => '$' # value of token |  | 
| 115 }); |  | 
| 116 |  | 
| 117 struct( Typedef => { |  | 
| 118     extendedAttributes => '$', # Extended attributes |  | 
| 119     type => '$', # Type of data |  | 
| 120 }); |  | 
| 121 |  | 
| 122 struct( UnionType => { |  | 
| 123     unionMemberTypes => '@', # (UnionType or string)[] |  | 
| 124 }); |  | 
| 125 |  | 
| 126 # Maps 'typedef name' -> Typedef |  | 
| 127 my %typedefs = (); |  | 
| 128 |  | 
| 129 sub new { |  | 
| 130     my $class = shift; |  | 
| 131 |  | 
| 132     my $emptyToken = Token->new(); |  | 
| 133     $emptyToken->type(EmptyToken); |  | 
| 134     $emptyToken->value("empty"); |  | 
| 135 |  | 
| 136     my $self = { |  | 
| 137         DocumentContent => "", |  | 
| 138         EmptyToken => $emptyToken, |  | 
| 139         NextToken => $emptyToken, |  | 
| 140         Token => $emptyToken, |  | 
| 141         Line => "", |  | 
| 142         LineNumber => 1 |  | 
| 143     }; |  | 
| 144     return bless $self, $class; |  | 
| 145 } |  | 
| 146 |  | 
| 147 sub assertTokenValue |  | 
| 148 { |  | 
| 149     my $self = shift; |  | 
| 150     my $token = shift; |  | 
| 151     my $value = shift; |  | 
| 152     my $line = shift; |  | 
| 153     my $msg = "Next token should be " . $value . ", but " . $token->value() . " 
      at " . $self->{Line}; |  | 
| 154     if (defined ($line)) { |  | 
| 155         $msg .= " deprecated_idl_parser.pm:" . $line; |  | 
| 156     } |  | 
| 157     die $msg unless $token->value() eq $value; |  | 
| 158 } |  | 
| 159 |  | 
| 160 sub assertTokenType |  | 
| 161 { |  | 
| 162     my $self = shift; |  | 
| 163     my $token = shift; |  | 
| 164     my $type = shift; |  | 
| 165     die "Next token's type should be " . $type . ", but " . $token->type() . " a
      t " . $self->{Line} unless $token->type() eq $type; |  | 
| 166 } |  | 
| 167 |  | 
| 168 sub assertUnexpectedToken |  | 
| 169 { |  | 
| 170     my $self = shift; |  | 
| 171     my $token = shift; |  | 
| 172     my $line = shift; |  | 
| 173     my $msg = "Unexpected token " . $token . " at " . $self->{Line}; |  | 
| 174     if (defined ($line)) { |  | 
| 175         $msg .= " deprecated_idl_parser.pm:" . $line; |  | 
| 176     } |  | 
| 177     die $msg; |  | 
| 178 } |  | 
| 179 |  | 
| 180 sub assertNoExtendedAttributesInTypedef |  | 
| 181 { |  | 
| 182     my $self = shift; |  | 
| 183     my $name = shift; |  | 
| 184     my $line = shift; |  | 
| 185     my $typedef = $typedefs{$name}; |  | 
| 186     my $msg = "Unexpected extendedAttributeList in typedef \"$name\" at " . $sel
      f->{Line}; |  | 
| 187     if (defined ($line)) { |  | 
| 188         $msg .= " deprecated_idl_parser.pm:" . $line; |  | 
| 189     } |  | 
| 190     die $msg if %{$typedef->extendedAttributes}; |  | 
| 191 } |  | 
| 192 |  | 
| 193 sub Parse |  | 
| 194 { |  | 
| 195     my $self = shift; |  | 
| 196     my $fileName = shift; |  | 
| 197     my $preprocessor = shift; |  | 
| 198     my $defines = ""; |  | 
| 199 |  | 
| 200     my @definitions = (); |  | 
| 201 |  | 
| 202     my @lines = applyPreprocessor($fileName, $defines, $preprocessor); |  | 
| 203     $self->{Line} = $lines[0]; |  | 
| 204     $self->{DocumentContent} = join(' ', @lines); |  | 
| 205 |  | 
| 206     $self->getToken(); |  | 
| 207     eval { |  | 
| 208         my $result = $self->parseDefinitions(); |  | 
| 209         push(@definitions, @{$result}); |  | 
| 210 |  | 
| 211         my $next = $self->nextToken(); |  | 
| 212         $self->assertTokenType($next, EmptyToken); |  | 
| 213     }; |  | 
| 214     die $@ . " in $fileName" if $@; |  | 
| 215 |  | 
| 216     my $document = idlDocument->new(); |  | 
| 217     $document->fileName($fileName); |  | 
| 218     foreach my $definition (@definitions) { |  | 
| 219         if (ref($definition) eq "domInterface") { |  | 
| 220             push(@{$document->interfaces}, $definition); |  | 
| 221         } elsif (ref($definition) eq "domEnum") { |  | 
| 222             push(@{$document->enumerations}, $definition); |  | 
| 223         } elsif (ref($definition) eq "callbackFunction") { |  | 
| 224             push(@{$document->callbackFunctions}, $definition); |  | 
| 225         } else { |  | 
| 226             die "Unrecognized IDL definition kind: \"" . ref($definition) . "\""
      ; |  | 
| 227         } |  | 
| 228     } |  | 
| 229     # Sort so output independent of order in IDL file (e.g., for JSON output) |  | 
| 230     @{$document->callbackFunctions} = sort {$a->name cmp $b->name} @{$document->
      callbackFunctions}; |  | 
| 231     @{$document->enumerations} = sort {$a->name cmp $b->name} @{$document->enume
      rations}; |  | 
| 232     @{$document->interfaces} = sort {$a->name cmp $b->name} @{$document->interfa
      ces}; |  | 
| 233     return $document; |  | 
| 234 } |  | 
| 235 |  | 
| 236 sub nextToken |  | 
| 237 { |  | 
| 238     my $self = shift; |  | 
| 239     return $self->{NextToken}; |  | 
| 240 } |  | 
| 241 |  | 
| 242 sub getToken |  | 
| 243 { |  | 
| 244     my $self = shift; |  | 
| 245     $self->{Token} = $self->{NextToken}; |  | 
| 246     $self->{NextToken} = $self->getTokenInternal(); |  | 
| 247     return $self->{Token}; |  | 
| 248 } |  | 
| 249 |  | 
| 250 my $whitespaceTokenPattern = '^[\t\n\r ]*[\n\r]'; |  | 
| 251 my $floatTokenPattern = '^(-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|
      [0-9]+[Ee][+-]?[0-9]+))'; |  | 
| 252 my $integerTokenPattern = '^(-?[1-9][0-9]*|-?0[Xx][0-9A-Fa-f]+|-?0[0-7]*)'; |  | 
| 253 my $stringTokenPattern = '^(\"[^\"]*\")'; |  | 
| 254 my $identifierTokenPattern = '^([A-Z_a-z][0-9A-Z_a-z]*)'; |  | 
| 255 my $otherTokenPattern = '^(::|\.\.\.|[^\t\n\r 0-9A-Z_a-z])'; |  | 
| 256 |  | 
| 257 sub getTokenInternal |  | 
| 258 { |  | 
| 259     my $self = shift; |  | 
| 260 |  | 
| 261     if ($self->{DocumentContent} =~ /$whitespaceTokenPattern/) { |  | 
| 262         $self->{DocumentContent} =~ s/($whitespaceTokenPattern)//; |  | 
| 263         my $skipped = $1; |  | 
| 264         $self->{LineNumber}++ while ($skipped =~ /\n/g); |  | 
| 265         if ($self->{DocumentContent} =~ /^([^\n\r]+)/) { |  | 
| 266             $self->{Line} = $self->{LineNumber} . ":" . $1; |  | 
| 267         } else { |  | 
| 268             $self->{Line} = "Unknown"; |  | 
| 269         } |  | 
| 270     } |  | 
| 271     $self->{DocumentContent} =~ s/^([\t\n\r ]+)//; |  | 
| 272     if ($self->{DocumentContent} eq "") { |  | 
| 273         return $self->{EmptyToken}; |  | 
| 274     } |  | 
| 275 |  | 
| 276     my $token = Token->new(); |  | 
| 277     if ($self->{DocumentContent} =~ /$floatTokenPattern/) { |  | 
| 278         $token->type(FloatToken); |  | 
| 279         $token->value($1); |  | 
| 280         $self->{DocumentContent} =~ s/$floatTokenPattern//; |  | 
| 281         return $token; |  | 
| 282     } |  | 
| 283     if ($self->{DocumentContent} =~ /$integerTokenPattern/) { |  | 
| 284         $token->type(IntegerToken); |  | 
| 285         $token->value($1); |  | 
| 286         $self->{DocumentContent} =~ s/$integerTokenPattern//; |  | 
| 287         return $token; |  | 
| 288     } |  | 
| 289     if ($self->{DocumentContent} =~ /$stringTokenPattern/) { |  | 
| 290         $token->type(StringToken); |  | 
| 291         $token->value($1); |  | 
| 292         $self->{DocumentContent} =~ s/$stringTokenPattern//; |  | 
| 293         return $token; |  | 
| 294     } |  | 
| 295     if ($self->{DocumentContent} =~ /$identifierTokenPattern/) { |  | 
| 296         $token->type(IdentifierToken); |  | 
| 297         (my $value = $1) =~ s/^_//;  # strip leading underscore, used to strope 
      reserved words |  | 
| 298         $token->value($value); |  | 
| 299         $self->{DocumentContent} =~ s/$identifierTokenPattern//; |  | 
| 300         return $token; |  | 
| 301     } |  | 
| 302     if ($self->{DocumentContent} =~ /$otherTokenPattern/) { |  | 
| 303         $token->type(OtherToken); |  | 
| 304         $token->value($1); |  | 
| 305         $self->{DocumentContent} =~ s/$otherTokenPattern//; |  | 
| 306         return $token; |  | 
| 307     } |  | 
| 308     die "Failed in tokenizing at " . $self->{Line}; |  | 
| 309 } |  | 
| 310 |  | 
| 311 sub unquoteString |  | 
| 312 { |  | 
| 313     my $self = shift; |  | 
| 314     my $quotedString = shift; |  | 
| 315     if ($quotedString =~ /^"([^"]*)"$/) { |  | 
| 316         return $1; |  | 
| 317     } |  | 
| 318     die "Failed to parse string (" . $quotedString . ") at " . $self->{Line}; |  | 
| 319 } |  | 
| 320 |  | 
| 321 sub typeHasNullableSuffix |  | 
| 322 { |  | 
| 323     my $type = shift; |  | 
| 324     return $type =~ /\?$/; |  | 
| 325 } |  | 
| 326 |  | 
| 327 sub typeRemoveNullableSuffix |  | 
| 328 { |  | 
| 329     my $type = shift; |  | 
| 330     $type =~ s/\?$//g; |  | 
| 331     return $type; |  | 
| 332 } |  | 
| 333 |  | 
| 334 # Promise is not yet in the Web IDL spec but is going to be speced |  | 
| 335 # as primitive types in the future. |  | 
| 336 my $nextAttribute_1 = '^(attribute|inherit|readonly)$'; |  | 
| 337 my $nextPrimitiveType_1 = '^(int|long|short|unsigned)$'; |  | 
| 338 my $nextPrimitiveType_2 = '^(double|float|unrestricted)$'; |  | 
| 339 my $nextArgumentList_1 = '^(\(|::|ByteString|DOMString|Promise|Date|\[|any|boole
      an|byte|double|float|in|int|long|object|octet|optional|sequence|short|unrestrict
      ed|unsigned)$'; |  | 
| 340 my $nextNonAnyType_1 = '^(boolean|byte|double|float|int|long|octet|short|unrestr
      icted|unsigned)$'; |  | 
| 341 my $nextInterfaceMember_1 = '^(\(|::|ByteString|DOMString|Promise|Date|any|attri
      bute|boolean|byte|creator|deleter|double|float|getter|inherit|int|legacycaller|l
      ong|object|octet|readonly|sequence|serializer|setter|short|static|stringifier|un
      restricted|unsigned|void)$'; |  | 
| 342 my $nextOptionalIteratorInterfaceOrObject_1 = '^(;|=)$'; |  | 
| 343 my $nextAttributeOrOperationOrIterator_1 = '^(static|stringifier)$'; |  | 
| 344 my $nextAttributeOrOperationOrIterator_2 = '^(\(|::|ByteString|DOMString|Promise
      |Date|any|boolean|byte|creator|deleter|double|float|getter|int|legacycaller|long
      |object|octet|sequence|setter|short|unrestricted|unsigned|void)$'; |  | 
| 345 my $nextUnrestrictedFloatType_1 = '^(double|float)$'; |  | 
| 346 my $nextExtendedAttributeRest3_1 = '^(\,|::|\])$'; |  | 
| 347 my $nextExceptionField_1 = '^(\(|::|ByteString|DOMString|Promise|Date|any|boolea
      n|byte|double|float|int|long|object|octet|sequence|short|unrestricted|unsigned)$
      '; |  | 
| 348 my $nextType_1 = '^(::|ByteString|DOMString|Promise|Date|any|boolean|byte|double
      |float|int|long|object|octet|sequence|short|unrestricted|unsigned)$'; |  | 
| 349 my $nextSpecials_1 = '^(creator|deleter|getter|legacycaller|setter)$'; |  | 
| 350 my $nextDefinitions_1 = '^(::|callback|dictionary|enum|exception|interface|parti
      al|typedef)$'; |  | 
| 351 my $nextExceptionMembers_1 = '^(\(|::|ByteString|DOMString|Promise|Date|\[|any|b
      oolean|byte|const|double|float|int|long|object|octet|optional|sequence|short|unr
      estricted|unsigned)$'; |  | 
| 352 my $nextAttributeRest_1 = '^(attribute|readonly)$'; |  | 
| 353 my $nextInterfaceMembers_1 = '^(\(|::|ByteString|DOMString|Promise|Date|any|attr
      ibute|boolean|byte|const|creator|deleter|double|float|getter|inherit|int|legacyc
      aller|long|object|octet|readonly|sequence|serializer|setter|short|static|stringi
      fier|unrestricted|unsigned|void)$'; |  | 
| 354 my $nextSingleType_1 = '^(::|ByteString|DOMString|Promise|Date|boolean|byte|doub
      le|float|int|long|object|octet|sequence|short|unrestricted|unsigned)$'; |  | 
| 355 my $nextArgumentName_1 = '^(attribute|callback|const|creator|deleter|dictionary|
      enum|exception|getter|implements|inherit|interface|legacycaller|partial|serializ
      er|setter|static|stringifier|typedef|unrestricted)$'; |  | 
| 356 my $nextConstValue_1 = '^(false|true)$'; |  | 
| 357 my $nextConstValue_2 = '^(-|Infinity|NaN)$'; |  | 
| 358 my $nextDefinition_1 = '^(callback|interface)$'; |  | 
| 359 my $nextAttributeOrOperationRest_1 = '^(\(|::|ByteString|DOMString|Promise|Date|
      any|boolean|byte|double|float|int|long|object|octet|sequence|short|unrestricted|
      unsigned|void)$'; |  | 
| 360 my $nextUnsignedIntegerType_1 = '^(int|long|short)$'; |  | 
| 361 my $nextDefaultValue_1 = '^(-|Infinity|NaN|false|null|true)$'; |  | 
| 362 |  | 
| 363 |  | 
| 364 sub parseDefinitions |  | 
| 365 { |  | 
| 366     my $self = shift; |  | 
| 367     my @definitions = (); |  | 
| 368 |  | 
| 369     while (1) { |  | 
| 370         my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty(
      ); |  | 
| 371         my $next = $self->nextToken(); |  | 
| 372         my $definition; |  | 
| 373         if ($next->type() == IdentifierToken || $next->value() =~ /$nextDefiniti
      ons_1/) { |  | 
| 374             $definition = $self->parseDefinition($extendedAttributeList); |  | 
| 375         } else { |  | 
| 376             last; |  | 
| 377         } |  | 
| 378         if (defined ($definition)) { |  | 
| 379             push(@definitions, $definition); |  | 
| 380         } |  | 
| 381     } |  | 
| 382     $self->applyTypedefs(\@definitions); |  | 
| 383     return \@definitions; |  | 
| 384 } |  | 
| 385 |  | 
| 386 sub applyTypedefs |  | 
| 387 { |  | 
| 388     my $self = shift; |  | 
| 389     my $definitions = shift; |  | 
| 390 |  | 
| 391     if (!%typedefs) { |  | 
| 392         return; |  | 
| 393     } |  | 
| 394     foreach my $definition (@$definitions) { |  | 
| 395         if (ref($definition) eq "domInterface") { |  | 
| 396             foreach my $constant (@{$definition->constants}) { |  | 
| 397                 if (exists $typedefs{$constant->type}) { |  | 
| 398                     my $typedef = $typedefs{$constant->type}; |  | 
| 399                     $self->assertNoExtendedAttributesInTypedef($constant->type, 
      __LINE__); |  | 
| 400                     $constant->type($typedef->type); |  | 
| 401                 } |  | 
| 402             } |  | 
| 403             foreach my $attribute (@{$definition->attributes}) { |  | 
| 404                 $self->applyTypedefsForTypedObject($attribute); |  | 
| 405             } |  | 
| 406             foreach my $function (@{$definition->functions}, @{$definition->cons
      tructors}, @{$definition->customConstructors}) { |  | 
| 407                 $self->applyTypedefsForTypedObject($function); |  | 
| 408                 foreach my $parameter (@{$function->parameters}) { |  | 
| 409                     $self->applyTypedefsForTypedObject($parameter); |  | 
| 410                 } |  | 
| 411             } |  | 
| 412         } |  | 
| 413     } |  | 
| 414 } |  | 
| 415 |  | 
| 416 sub applyTypedefsForTypedObject |  | 
| 417 { |  | 
| 418     my $self = shift; |  | 
| 419     my $typedObject = shift; |  | 
| 420 |  | 
| 421     if (!defined ($typedObject->type)) { |  | 
| 422         return; |  | 
| 423     } |  | 
| 424 |  | 
| 425     my $type = $typedObject->type; |  | 
| 426     $type =~ s/[\?\[\]]+$//g; |  | 
| 427     my $typeSuffix = $typedObject->type; |  | 
| 428     $typeSuffix =~ s/^[^\?\[\]]+//g; |  | 
| 429     if (exists $typedefs{$type}) { |  | 
| 430         my $typedef = $typedefs{$type}; |  | 
| 431         $typedObject->type($typedef->type . $typeSuffix); |  | 
| 432         copyExtendedAttributes($typedObject->extendedAttributes, $typedef->exten
      dedAttributes); |  | 
| 433     } |  | 
| 434 |  | 
| 435     # Handle union types, sequences and etc. |  | 
| 436     foreach my $name (%typedefs) { |  | 
| 437         if (!exists $typedefs{$name}) { |  | 
| 438             next; |  | 
| 439         } |  | 
| 440         my $typedef = $typedefs{$name}; |  | 
| 441         my $regex = '\\b' . $name . '\\b'; |  | 
| 442         my $replacement = $typedef->type; |  | 
| 443         my $type = $typedObject->type; |  | 
| 444         $type =~ s/($regex)/$replacement/g; |  | 
| 445         $typedObject->type($type); |  | 
| 446     } |  | 
| 447 } |  | 
| 448 |  | 
| 449 sub parseDefinition |  | 
| 450 { |  | 
| 451     my $self = shift; |  | 
| 452     my $extendedAttributeList = shift; |  | 
| 453 |  | 
| 454     my $next = $self->nextToken(); |  | 
| 455     if ($next->value() =~ /$nextDefinition_1/) { |  | 
| 456         return $self->parseCallbackOrInterface($extendedAttributeList); |  | 
| 457     } |  | 
| 458     if ($next->value() eq "partial") { |  | 
| 459         return $self->parsePartial($extendedAttributeList); |  | 
| 460     } |  | 
| 461     if ($next->value() eq "dictionary") { |  | 
| 462         return $self->parseDictionary($extendedAttributeList); |  | 
| 463     } |  | 
| 464     if ($next->value() eq "exception") { |  | 
| 465         return $self->parseException($extendedAttributeList); |  | 
| 466     } |  | 
| 467     if ($next->value() eq "enum") { |  | 
| 468         return $self->parseEnum($extendedAttributeList); |  | 
| 469     } |  | 
| 470     if ($next->value() eq "typedef") { |  | 
| 471         return $self->parseTypedef($extendedAttributeList); |  | 
| 472     } |  | 
| 473     if ($next->type() == IdentifierToken || $next->value() eq "::") { |  | 
| 474         return $self->parseImplementsStatement($extendedAttributeList); |  | 
| 475     } |  | 
| 476     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 477 } |  | 
| 478 |  | 
| 479 sub parseCallbackOrInterface |  | 
| 480 { |  | 
| 481     my $self = shift; |  | 
| 482     my $extendedAttributeList = shift; |  | 
| 483 |  | 
| 484     my $next = $self->nextToken(); |  | 
| 485     if ($next->value() eq "callback") { |  | 
| 486         $self->assertTokenValue($self->getToken(), "callback", __LINE__); |  | 
| 487         return $self->parseCallbackRestOrInterface($extendedAttributeList); |  | 
| 488     } |  | 
| 489     if ($next->value() eq "interface") { |  | 
| 490         return $self->parseInterface($extendedAttributeList); |  | 
| 491     } |  | 
| 492     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 493 } |  | 
| 494 |  | 
| 495 sub parseCallbackRestOrInterface |  | 
| 496 { |  | 
| 497     my $self = shift; |  | 
| 498     my $extendedAttributeList = shift; |  | 
| 499 |  | 
| 500     my $next = $self->nextToken(); |  | 
| 501     if ($next->value() eq "interface") { |  | 
| 502         my $interface = $self->parseInterface($extendedAttributeList); |  | 
| 503         $interface->isCallback(1); |  | 
| 504         return $interface; |  | 
| 505     } |  | 
| 506     if ($next->type() == IdentifierToken) { |  | 
| 507         return $self->parseCallbackRest($extendedAttributeList); |  | 
| 508     } |  | 
| 509     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 510 } |  | 
| 511 |  | 
| 512 sub parseInterface |  | 
| 513 { |  | 
| 514     my $self = shift; |  | 
| 515     my $extendedAttributeList = shift; |  | 
| 516 |  | 
| 517     my $next = $self->nextToken(); |  | 
| 518     if ($next->value() eq "interface") { |  | 
| 519         my $interface = domInterface->new(); |  | 
| 520         $self->assertTokenValue($self->getToken(), "interface", __LINE__); |  | 
| 521         my $interfaceNameToken = $self->getToken(); |  | 
| 522         $self->assertTokenType($interfaceNameToken, IdentifierToken); |  | 
| 523         $interface->name($interfaceNameToken->value()); |  | 
| 524         $interface->parent($self->parseInheritance()); |  | 
| 525         $self->assertTokenValue($self->getToken(), "{", __LINE__); |  | 
| 526         my $interfaceMembers = $self->parseInterfaceMembers(); |  | 
| 527         $self->assertTokenValue($self->getToken(), "}", __LINE__); |  | 
| 528         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 529         applyMemberList($interface, $interfaceMembers); |  | 
| 530         applyExtendedAttributeList($interface, $extendedAttributeList); |  | 
| 531         return $interface; |  | 
| 532     } |  | 
| 533     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 534 } |  | 
| 535 |  | 
| 536 sub parsePartial |  | 
| 537 { |  | 
| 538     my $self = shift; |  | 
| 539     my $extendedAttributeList = shift; |  | 
| 540 |  | 
| 541     my $next = $self->nextToken(); |  | 
| 542     if ($next->value() eq "partial") { |  | 
| 543         $self->assertTokenValue($self->getToken(), "partial", __LINE__); |  | 
| 544         return $self->parsePartialDefinition($extendedAttributeList); |  | 
| 545     } |  | 
| 546     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 547 } |  | 
| 548 |  | 
| 549 sub parsePartialDefinition |  | 
| 550 { |  | 
| 551     my $self = shift; |  | 
| 552     my $extendedAttributeList = shift; |  | 
| 553 |  | 
| 554     my $next = $self->nextToken(); |  | 
| 555     if ($next->value() eq "interface") { |  | 
| 556         my $interface = $self->parseInterface($extendedAttributeList); |  | 
| 557         $interface->isPartial(1); |  | 
| 558         return $interface; |  | 
| 559     } |  | 
| 560     if ($next->value() eq "dictionary") { |  | 
| 561         return $self->parsePartialDictionary($extendedAttributeList); |  | 
| 562     } |  | 
| 563     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 564 } |  | 
| 565 |  | 
| 566 sub parsePartialInterface |  | 
| 567 { |  | 
| 568     my $self = shift; |  | 
| 569     my $extendedAttributeList = shift; |  | 
| 570 |  | 
| 571     my $next = $self->nextToken(); |  | 
| 572     if ($next->value() eq "interface") { |  | 
| 573         $self->assertTokenValue($self->getToken(), "interface", __LINE__); |  | 
| 574         $self->assertTokenType($self->getToken(), IdentifierToken); |  | 
| 575         $self->assertTokenValue($self->getToken(), "{", __LINE__); |  | 
| 576         $self->parseInterfaceMembers(); |  | 
| 577         $self->assertTokenValue($self->getToken(), "}", __LINE__); |  | 
| 578         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 579         return; |  | 
| 580     } |  | 
| 581     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 582 } |  | 
| 583 |  | 
| 584 sub parseInterfaceMembers |  | 
| 585 { |  | 
| 586     my $self = shift; |  | 
| 587     my @interfaceMembers = (); |  | 
| 588 |  | 
| 589     while (1) { |  | 
| 590         my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty(
      ); |  | 
| 591         my $next = $self->nextToken(); |  | 
| 592         my $interfaceMember; |  | 
| 593         if ($next->type() == IdentifierToken || $next->value() =~ /$nextInterfac
      eMembers_1/) { |  | 
| 594             $interfaceMember = $self->parseInterfaceMember($extendedAttributeLis
      t); |  | 
| 595         } else { |  | 
| 596             last; |  | 
| 597         } |  | 
| 598         if (defined $interfaceMember) { |  | 
| 599             push(@interfaceMembers, $interfaceMember); |  | 
| 600         } |  | 
| 601     } |  | 
| 602     return \@interfaceMembers; |  | 
| 603 } |  | 
| 604 |  | 
| 605 sub parseInterfaceMember |  | 
| 606 { |  | 
| 607     my $self = shift; |  | 
| 608     my $extendedAttributeList = shift; |  | 
| 609 |  | 
| 610     my $next = $self->nextToken(); |  | 
| 611     if ($next->value() eq "const") { |  | 
| 612         return $self->parseConst($extendedAttributeList); |  | 
| 613     } |  | 
| 614     if ($next->type() == IdentifierToken || $next->value() =~ /$nextInterfaceMem
      ber_1/) { |  | 
| 615         return $self->parseAttributeOrOperationOrIterator($extendedAttributeList
      ); |  | 
| 616     } |  | 
| 617     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 618 } |  | 
| 619 |  | 
| 620 sub parseDictionary |  | 
| 621 { |  | 
| 622     my $self = shift; |  | 
| 623     my $extendedAttributeList = shift; |  | 
| 624 |  | 
| 625     my $next = $self->nextToken(); |  | 
| 626     if ($next->value() eq "dictionary") { |  | 
| 627         $self->assertTokenValue($self->getToken(), "dictionary", __LINE__); |  | 
| 628         $self->assertTokenType($self->getToken(), IdentifierToken); |  | 
| 629         $self->parseInheritance(); |  | 
| 630         $self->assertTokenValue($self->getToken(), "{", __LINE__); |  | 
| 631         $self->parseDictionaryMembers(); |  | 
| 632         $self->assertTokenValue($self->getToken(), "}", __LINE__); |  | 
| 633         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 634         return; |  | 
| 635     } |  | 
| 636     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 637 } |  | 
| 638 |  | 
| 639 sub parseDictionaryMembers |  | 
| 640 { |  | 
| 641     my $self = shift; |  | 
| 642 |  | 
| 643     while (1) { |  | 
| 644         my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty(
      ); |  | 
| 645         my $next = $self->nextToken(); |  | 
| 646         if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptio
      nField_1/) { |  | 
| 647             $self->parseDictionaryMember($extendedAttributeList); |  | 
| 648         } else { |  | 
| 649             last; |  | 
| 650         } |  | 
| 651     } |  | 
| 652 } |  | 
| 653 |  | 
| 654 sub parseDictionaryMember |  | 
| 655 { |  | 
| 656     my $self = shift; |  | 
| 657     my $extendedAttributeList = shift; |  | 
| 658 |  | 
| 659     my $next = $self->nextToken(); |  | 
| 660     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionFie
      ld_1/) { |  | 
| 661         $self->parseType(); |  | 
| 662         $self->assertTokenType($self->getToken(), IdentifierToken); |  | 
| 663         $self->parseDefault(); |  | 
| 664         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 665         return; |  | 
| 666     } |  | 
| 667     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 668 } |  | 
| 669 |  | 
| 670 sub parsePartialDictionary |  | 
| 671 { |  | 
| 672     my $self = shift; |  | 
| 673     my $next = $self->nextToken(); |  | 
| 674     if ($next->value() eq "dictionary") { |  | 
| 675         $self->assertTokenValue($self->getToken(), "dictionary", __LINE__); |  | 
| 676         $self->assertTokenType($self->getToken(), IdentifierToken); |  | 
| 677         $self->assertTokenValue($self->getToken(), "{", __LINE__); |  | 
| 678         $self->parseDictionaryMembers(); |  | 
| 679         $self->assertTokenValue($self->getToken(), "}", __LINE__); |  | 
| 680         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 681         return; |  | 
| 682     } |  | 
| 683     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 684 } |  | 
| 685 |  | 
| 686 sub parseDefault |  | 
| 687 { |  | 
| 688     my $self = shift; |  | 
| 689     my $next = $self->nextToken(); |  | 
| 690     if ($next->value() eq "=") { |  | 
| 691         $self->assertTokenValue($self->getToken(), "=", __LINE__); |  | 
| 692         return $self->parseDefaultValue(); |  | 
| 693     } |  | 
| 694 } |  | 
| 695 |  | 
| 696 sub parseDefaultValue |  | 
| 697 { |  | 
| 698     my $self = shift; |  | 
| 699     my $next = $self->nextToken(); |  | 
| 700     if ($next->type() == FloatToken || $next->type() == IntegerToken || $next->v
      alue() =~ /$nextDefaultValue_1/) { |  | 
| 701         return $self->parseConstValue(); |  | 
| 702     } |  | 
| 703     if ($next->type() == StringToken) { |  | 
| 704         return $self->getToken()->value(); |  | 
| 705     } |  | 
| 706     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 707 } |  | 
| 708 |  | 
| 709 sub parseException |  | 
| 710 { |  | 
| 711     my $self = shift; |  | 
| 712     my $extendedAttributeList = shift; |  | 
| 713 |  | 
| 714     my $next = $self->nextToken(); |  | 
| 715     if ($next->value() eq "exception") { |  | 
| 716         my $interface = domInterface->new(); |  | 
| 717         $self->assertTokenValue($self->getToken(), "exception", __LINE__); |  | 
| 718         my $exceptionNameToken = $self->getToken(); |  | 
| 719         $self->assertTokenType($exceptionNameToken, IdentifierToken); |  | 
| 720         $interface->name($exceptionNameToken->value()); |  | 
| 721         $interface->isException(1); |  | 
| 722         $interface->parent($self->parseInheritance()); |  | 
| 723         $self->assertTokenValue($self->getToken(), "{", __LINE__); |  | 
| 724         my $exceptionMembers = $self->parseExceptionMembers(); |  | 
| 725         $self->assertTokenValue($self->getToken(), "}", __LINE__); |  | 
| 726         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 727         applyMemberList($interface, $exceptionMembers); |  | 
| 728         applyExtendedAttributeList($interface, $extendedAttributeList); |  | 
| 729         return $interface; |  | 
| 730     } |  | 
| 731     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 732 } |  | 
| 733 |  | 
| 734 sub parseExceptionMembers |  | 
| 735 { |  | 
| 736     my $self = shift; |  | 
| 737     my @members = (); |  | 
| 738 |  | 
| 739     while (1) { |  | 
| 740         my $next = $self->nextToken(); |  | 
| 741         if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptio
      nMembers_1/) { |  | 
| 742             my $extendedAttributeList = $self->parseExtendedAttributeListAllowEm
      pty(); |  | 
| 743             #my $member = $self->parseExceptionMember($extendedAttributeList); |  | 
| 744             my $member = $self->parseInterfaceMember($extendedAttributeList); |  | 
| 745             if (defined ($member)) { |  | 
| 746                 push(@members, $member); |  | 
| 747             } |  | 
| 748         } else { |  | 
| 749             last; |  | 
| 750         } |  | 
| 751     } |  | 
| 752     return \@members; |  | 
| 753 } |  | 
| 754 |  | 
| 755 sub parseInheritance |  | 
| 756 { |  | 
| 757     my $self = shift; |  | 
| 758     my $parent; |  | 
| 759 |  | 
| 760     my $next = $self->nextToken(); |  | 
| 761     if ($next->value() eq ":") { |  | 
| 762         $self->assertTokenValue($self->getToken(), ":", __LINE__); |  | 
| 763         $parent = $self->parseScopedName(); |  | 
| 764     } |  | 
| 765     return $parent; |  | 
| 766 } |  | 
| 767 |  | 
| 768 sub parseEnum |  | 
| 769 { |  | 
| 770     my $self = shift; |  | 
| 771     my $extendedAttributeList = shift; # ignored: Extended attributes are not ap
      plicable to enumerations |  | 
| 772 |  | 
| 773     my $next = $self->nextToken(); |  | 
| 774     if ($next->value() eq "enum") { |  | 
| 775         my $enum = domEnum->new(); |  | 
| 776         $self->assertTokenValue($self->getToken(), "enum", __LINE__); |  | 
| 777         my $enumNameToken = $self->getToken(); |  | 
| 778         $self->assertTokenType($enumNameToken, IdentifierToken); |  | 
| 779         $enum->name($enumNameToken->value()); |  | 
| 780         $self->assertTokenValue($self->getToken(), "{", __LINE__); |  | 
| 781         push(@{$enum->values}, @{$self->parseEnumValueList()}); |  | 
| 782         $self->assertTokenValue($self->getToken(), "}", __LINE__); |  | 
| 783         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 784         return $enum; |  | 
| 785     } |  | 
| 786     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 787 } |  | 
| 788 |  | 
| 789 sub parseEnumValueList |  | 
| 790 { |  | 
| 791     my $self = shift; |  | 
| 792     my @values = (); |  | 
| 793     my $next = $self->nextToken(); |  | 
| 794     if ($next->type() == StringToken) { |  | 
| 795         my $enumValueToken = $self->getToken(); |  | 
| 796         $self->assertTokenType($enumValueToken, StringToken); |  | 
| 797         my $enumValue = $self->unquoteString($enumValueToken->value()); |  | 
| 798         push(@values, $enumValue); |  | 
| 799         push(@values, @{$self->parseEnumValues()}); |  | 
| 800         return \@values; |  | 
| 801     } |  | 
| 802     # value list must be non-empty |  | 
| 803     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 804 } |  | 
| 805 |  | 
| 806 sub parseEnumValues |  | 
| 807 { |  | 
| 808     my $self = shift; |  | 
| 809     my @values = (); |  | 
| 810     my $next = $self->nextToken(); |  | 
| 811     if ($next->value() eq ",") { |  | 
| 812         $self->assertTokenValue($self->getToken(), ",", __LINE__); |  | 
| 813         my $enumValueToken = $self->getToken(); |  | 
| 814         $self->assertTokenType($enumValueToken, StringToken); |  | 
| 815         my $enumValue = $self->unquoteString($enumValueToken->value()); |  | 
| 816         push(@values, $enumValue); |  | 
| 817         push(@values, @{$self->parseEnumValues()}); |  | 
| 818         return \@values; |  | 
| 819     } |  | 
| 820     return \@values; # empty list (end of enumeration-values) |  | 
| 821 } |  | 
| 822 |  | 
| 823 sub parseCallbackRest |  | 
| 824 { |  | 
| 825     my $self = shift; |  | 
| 826     my $extendedAttributeList = shift; |  | 
| 827 |  | 
| 828     my $next = $self->nextToken(); |  | 
| 829     if ($next->type() == IdentifierToken) { |  | 
| 830         my $callback = callbackFunction->new(); |  | 
| 831         my $name = $self->getToken(); |  | 
| 832         $self->assertTokenType($name, IdentifierToken); |  | 
| 833         $callback->name($name->value()); |  | 
| 834         $self->assertTokenValue($self->getToken(), "=", __LINE__); |  | 
| 835         $callback->type($self->parseReturnType()); |  | 
| 836         $self->assertTokenValue($self->getToken(), "(", __LINE__); |  | 
| 837         $callback->parameters($self->parseArgumentList()); |  | 
| 838         $self->assertTokenValue($self->getToken(), ")", __LINE__); |  | 
| 839         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 840         return $callback; |  | 
| 841     } |  | 
| 842     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 843 } |  | 
| 844 |  | 
| 845 sub parseTypedef |  | 
| 846 { |  | 
| 847     my $self = shift; |  | 
| 848     my $extendedAttributeList = shift; |  | 
| 849     die "Extended attributes are not applicable to typedefs themselves: " . $sel
      f->{Line} if %{$extendedAttributeList}; |  | 
| 850 |  | 
| 851     my $next = $self->nextToken(); |  | 
| 852     if ($next->value() eq "typedef") { |  | 
| 853         $self->assertTokenValue($self->getToken(), "typedef", __LINE__); |  | 
| 854         my $typedef = Typedef->new(); |  | 
| 855         $typedef->extendedAttributes($self->parseExtendedAttributeListAllowEmpty
      ()); |  | 
| 856         $typedef->type($self->parseType()); |  | 
| 857         my $nameToken = $self->getToken(); |  | 
| 858         $self->assertTokenType($nameToken, IdentifierToken); |  | 
| 859         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 860         my $name = $nameToken->value(); |  | 
| 861         die "typedef redefinition for " . $name . " at " . $self->{Line} if (exi
      sts $typedefs{$name} && $typedef->type ne $typedefs{$name}->type); |  | 
| 862         $typedefs{$name} = $typedef; |  | 
| 863         return; |  | 
| 864     } |  | 
| 865     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 866 } |  | 
| 867 |  | 
| 868 sub parseImplementsStatement |  | 
| 869 { |  | 
| 870     my $self = shift; |  | 
| 871     my $extendedAttributeList = shift; |  | 
| 872 |  | 
| 873     my $next = $self->nextToken(); |  | 
| 874     if ($next->type() == IdentifierToken) { |  | 
| 875         $self->parseScopedName(); |  | 
| 876         $self->assertTokenValue($self->getToken(), "implements", __LINE__); |  | 
| 877         $self->parseScopedName(); |  | 
| 878         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 879         return; |  | 
| 880     } |  | 
| 881     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 882 } |  | 
| 883 |  | 
| 884 sub parseConst |  | 
| 885 { |  | 
| 886     my $self = shift; |  | 
| 887     my $extendedAttributeList = shift; |  | 
| 888 |  | 
| 889     my $next = $self->nextToken(); |  | 
| 890     if ($next->value() eq "const") { |  | 
| 891         my $newDataNode = domConstant->new(); |  | 
| 892         $self->assertTokenValue($self->getToken(), "const", __LINE__); |  | 
| 893         $newDataNode->type($self->parseConstType()); |  | 
| 894         my $constNameToken = $self->getToken(); |  | 
| 895         $self->assertTokenType($constNameToken, IdentifierToken); |  | 
| 896         $newDataNode->name($constNameToken->value()); |  | 
| 897         $self->assertTokenValue($self->getToken(), "=", __LINE__); |  | 
| 898         $newDataNode->value($self->parseConstValue()); |  | 
| 899         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 900         $newDataNode->extendedAttributes($extendedAttributeList); |  | 
| 901         return $newDataNode; |  | 
| 902     } |  | 
| 903     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 904 } |  | 
| 905 |  | 
| 906 sub parseConstValue |  | 
| 907 { |  | 
| 908     my $self = shift; |  | 
| 909     my $next = $self->nextToken(); |  | 
| 910     if ($next->value() =~ /$nextConstValue_1/) { |  | 
| 911         return $self->parseBooleanLiteral(); |  | 
| 912     } |  | 
| 913     if ($next->value() eq "null") { |  | 
| 914         $self->assertTokenValue($self->getToken(), "null", __LINE__); |  | 
| 915         return "null"; |  | 
| 916     } |  | 
| 917     if ($next->type() == FloatToken || $next->value() =~ /$nextConstValue_2/) { |  | 
| 918         return $self->parseFloatLiteral(); |  | 
| 919     } |  | 
| 920     # backward compatibility |  | 
| 921     if ($next->type() == StringToken) { |  | 
| 922         return $self->getToken()->value(); |  | 
| 923     } |  | 
| 924     if ($next->type() == IntegerToken) { |  | 
| 925         return $self->getToken()->value(); |  | 
| 926     } |  | 
| 927     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 928 } |  | 
| 929 |  | 
| 930 sub parseBooleanLiteral |  | 
| 931 { |  | 
| 932     my $self = shift; |  | 
| 933     my $next = $self->nextToken(); |  | 
| 934     if ($next->value() eq "true") { |  | 
| 935         $self->assertTokenValue($self->getToken(), "true", __LINE__); |  | 
| 936         return "true"; |  | 
| 937     } |  | 
| 938     if ($next->value() eq "false") { |  | 
| 939         $self->assertTokenValue($self->getToken(), "false", __LINE__); |  | 
| 940         return "false"; |  | 
| 941     } |  | 
| 942     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 943 } |  | 
| 944 |  | 
| 945 sub parseFloatLiteral |  | 
| 946 { |  | 
| 947     my $self = shift; |  | 
| 948     my $next = $self->nextToken(); |  | 
| 949     if ($next->value() eq "-") { |  | 
| 950         $self->assertTokenValue($self->getToken(), "-", __LINE__); |  | 
| 951         $self->assertTokenValue($self->getToken(), "Infinity", __LINE__); |  | 
| 952         return "-Infinity"; |  | 
| 953     } |  | 
| 954     if ($next->value() eq "Infinity") { |  | 
| 955         $self->assertTokenValue($self->getToken(), "Infinity", __LINE__); |  | 
| 956         return "Infinity"; |  | 
| 957     } |  | 
| 958     if ($next->value() eq "NaN") { |  | 
| 959         $self->assertTokenValue($self->getToken(), "NaN", __LINE__); |  | 
| 960         return "NaN"; |  | 
| 961     } |  | 
| 962     if ($next->type() == FloatToken) { |  | 
| 963         return $self->getToken()->value(); |  | 
| 964     } |  | 
| 965     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 966 } |  | 
| 967 |  | 
| 968 sub parseAttributeOrOperationOrIterator |  | 
| 969 { |  | 
| 970     my $self = shift; |  | 
| 971     my $extendedAttributeList = shift; |  | 
| 972 |  | 
| 973     my $next = $self->nextToken(); |  | 
| 974     if ($next->value() eq "serializer") { |  | 
| 975         return $self->parseSerializer($extendedAttributeList); |  | 
| 976     } |  | 
| 977     if ($next->value() =~ /$nextAttributeOrOperationOrIterator_1/) { |  | 
| 978         my $qualifier = $self->parseQualifier(); |  | 
| 979         my $newDataNode = $self->parseAttributeOrOperationRest($extendedAttribut
      eList); |  | 
| 980         if (defined($newDataNode) && $qualifier eq "static") { |  | 
| 981             $newDataNode->isStatic(1); |  | 
| 982         } |  | 
| 983         return $newDataNode; |  | 
| 984     } |  | 
| 985     if ($next->value() =~ /$nextAttribute_1/) { |  | 
| 986         return $self->parseAttribute($extendedAttributeList); |  | 
| 987     } |  | 
| 988     if ($next->type() == IdentifierToken || $next->value() =~ /$nextAttributeOrO
      perationOrIterator_2/) { |  | 
| 989         return $self->parseOperationOrIterator($extendedAttributeList); |  | 
| 990     } |  | 
| 991     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 992 } |  | 
| 993 |  | 
| 994 sub parseSerializer |  | 
| 995 { |  | 
| 996     my $self = shift; |  | 
| 997     my $extendedAttributeList = shift; |  | 
| 998 |  | 
| 999     my $next = $self->nextToken(); |  | 
| 1000     if ($next->value() eq "serializer") { |  | 
| 1001         $self->assertTokenValue($self->getToken(), "serializer", __LINE__); |  | 
| 1002         return $self->parseSerializerRest($extendedAttributeList); |  | 
| 1003     } |  | 
| 1004     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1005 } |  | 
| 1006 |  | 
| 1007 sub parseSerializerRest |  | 
| 1008 { |  | 
| 1009     my $self = shift; |  | 
| 1010     my $extendedAttributeList = shift; |  | 
| 1011 |  | 
| 1012     my $next = $self->nextToken(); |  | 
| 1013     if ($next->value() eq "=") { |  | 
| 1014         $self->assertTokenValue($self->getToken(), "=", __LINE__); |  | 
| 1015         return $self->parseSerializationPattern($extendedAttributeList); |  | 
| 1016     } |  | 
| 1017     if ($next->type() == IdentifierToken || $next->value() eq "(") { |  | 
| 1018         return $self->parseOperationRest($extendedAttributeList); |  | 
| 1019     } |  | 
| 1020 } |  | 
| 1021 |  | 
| 1022 sub parseSerializationPattern |  | 
| 1023 { |  | 
| 1024     my $self = shift; |  | 
| 1025     my $extendedAttributeList = shift; |  | 
| 1026 |  | 
| 1027     my $next = $self->nextToken(); |  | 
| 1028     if ($next->value() eq "{") { |  | 
| 1029         $self->assertTokenValue($self->getToken(), "{", __LINE__); |  | 
| 1030         $self->parseSerializationPatternMap(); |  | 
| 1031         $self->assertTokenValue($self->getToken(), "}", __LINE__); |  | 
| 1032         return; |  | 
| 1033     } |  | 
| 1034     if ($next->value() eq "[") { |  | 
| 1035         $self->assertTokenValue($self->getToken(), "[", __LINE__); |  | 
| 1036         $self->parseSerializationPatternList(); |  | 
| 1037         $self->assertTokenValue($self->getToken(), "]", __LINE__); |  | 
| 1038         return; |  | 
| 1039     } |  | 
| 1040     if ($next->type() == IdentifierToken) { |  | 
| 1041         $self->assertTokenType($self->getToken(), IdentifierToken); |  | 
| 1042         return; |  | 
| 1043     } |  | 
| 1044     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1045 } |  | 
| 1046 |  | 
| 1047 sub parseSerializationPatternMap |  | 
| 1048 { |  | 
| 1049     my $self = shift; |  | 
| 1050     my $next = $self->nextToken(); |  | 
| 1051     if ($next->value() eq "getter") { |  | 
| 1052         $self->assertTokenValue($self->getToken(), "getter", __LINE__); |  | 
| 1053         return; |  | 
| 1054     } |  | 
| 1055     if ($next->value() eq "inherit") { |  | 
| 1056         $self->assertTokenValue($self->getToken(), "inherit", __LINE__); |  | 
| 1057         $self->parseIdentifiers(); |  | 
| 1058         return; |  | 
| 1059     } |  | 
| 1060     if ($next->type() == IdentifierToken) { |  | 
| 1061         $self->assertTokenType($self->getToken(), IdentifierToken); |  | 
| 1062         $self->parseIdentifiers(); |  | 
| 1063     } |  | 
| 1064 } |  | 
| 1065 |  | 
| 1066 sub parseSerializationPatternList |  | 
| 1067 { |  | 
| 1068     my $self = shift; |  | 
| 1069     my $next = $self->nextToken(); |  | 
| 1070     if ($next->value() eq "getter") { |  | 
| 1071         $self->assertTokenValue($self->getToken(), "getter", __LINE__); |  | 
| 1072         return; |  | 
| 1073     } |  | 
| 1074     if ($next->type() == IdentifierToken) { |  | 
| 1075         $self->assertTokenType($self->getToken(), IdentifierToken); |  | 
| 1076         $self->parseIdentifiers(); |  | 
| 1077     } |  | 
| 1078 } |  | 
| 1079 |  | 
| 1080 sub parseIdentifiers |  | 
| 1081 { |  | 
| 1082     my $self = shift; |  | 
| 1083     my @idents = (); |  | 
| 1084 |  | 
| 1085     while (1) { |  | 
| 1086         my $next = $self->nextToken(); |  | 
| 1087         if ($next->value() eq ",") { |  | 
| 1088             $self->assertTokenValue($self->getToken(), ",", __LINE__); |  | 
| 1089             my $token = $self->getToken(); |  | 
| 1090             $self->assertTokenType($token, IdentifierToken); |  | 
| 1091             push(@idents, $token->value()); |  | 
| 1092         } else { |  | 
| 1093             last; |  | 
| 1094         } |  | 
| 1095     } |  | 
| 1096     return \@idents; |  | 
| 1097 } |  | 
| 1098 |  | 
| 1099 sub parseQualifier |  | 
| 1100 { |  | 
| 1101     my $self = shift; |  | 
| 1102 |  | 
| 1103     my $next = $self->nextToken(); |  | 
| 1104     if ($next->value() eq "static") { |  | 
| 1105         $self->assertTokenValue($self->getToken(), "static", __LINE__); |  | 
| 1106         return "static"; |  | 
| 1107     } |  | 
| 1108     if ($next->value() eq "stringifier") { |  | 
| 1109         $self->assertTokenValue($self->getToken(), "stringifier", __LINE__); |  | 
| 1110         return "stringifier"; |  | 
| 1111     } |  | 
| 1112     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1113 } |  | 
| 1114 |  | 
| 1115 sub parseAttributeOrOperationRest |  | 
| 1116 { |  | 
| 1117     my $self = shift; |  | 
| 1118     my $extendedAttributeList = shift; |  | 
| 1119 |  | 
| 1120     my $next = $self->nextToken(); |  | 
| 1121     if ($next->value() =~ /$nextAttributeRest_1/) { |  | 
| 1122         return $self->parseAttributeRest($extendedAttributeList); |  | 
| 1123     } |  | 
| 1124     if ($next->value() eq ";") { |  | 
| 1125         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 1126         return; |  | 
| 1127     } |  | 
| 1128     if ($next->type() == IdentifierToken || $next->value() =~ /$nextAttributeOrO
      perationRest_1/) { |  | 
| 1129         my $returnType = $self->parseReturnType(); |  | 
| 1130         my $function = $self->parseOperationRest($extendedAttributeList); |  | 
| 1131         if (defined ($function)) { |  | 
| 1132             $function->type($returnType); |  | 
| 1133         } |  | 
| 1134         return $function; |  | 
| 1135     } |  | 
| 1136     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1137 } |  | 
| 1138 |  | 
| 1139 sub parseAttribute |  | 
| 1140 { |  | 
| 1141     my $self = shift; |  | 
| 1142     my $extendedAttributeList = shift; |  | 
| 1143 |  | 
| 1144     my $next = $self->nextToken(); |  | 
| 1145     if ($next->value() =~ /$nextAttribute_1/) { |  | 
| 1146         $self->parseInherit(); |  | 
| 1147         return $self->parseAttributeRest($extendedAttributeList); |  | 
| 1148     } |  | 
| 1149     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1150 } |  | 
| 1151 |  | 
| 1152 sub parseAttributeRest |  | 
| 1153 { |  | 
| 1154     my $self = shift; |  | 
| 1155     my $extendedAttributeList = shift; |  | 
| 1156 |  | 
| 1157     my $next = $self->nextToken(); |  | 
| 1158     if ($next->value() =~ /$nextAttributeRest_1/) { |  | 
| 1159         my $newDataNode = domAttribute->new(); |  | 
| 1160         if ($self->parseReadOnly()) { |  | 
| 1161             $newDataNode->isReadOnly(1); |  | 
| 1162         } |  | 
| 1163         $self->assertTokenValue($self->getToken(), "attribute", __LINE__); |  | 
| 1164         my $type = $self->parseType(); |  | 
| 1165         $newDataNode->isNullable(typeHasNullableSuffix($type)); |  | 
| 1166         # Remove all "?" in the type declaration, e.g. "double?" -> "double". |  | 
| 1167         $newDataNode->type(typeRemoveNullableSuffix($type)); |  | 
| 1168         my $token = $self->getToken(); |  | 
| 1169         $self->assertTokenType($token, IdentifierToken); |  | 
| 1170         $newDataNode->name($token->value()); |  | 
| 1171         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 1172         # CustomConstructor may also be used on attributes. |  | 
| 1173         if (defined $extendedAttributeList->{"CustomConstructors"}) { |  | 
| 1174             delete $extendedAttributeList->{"CustomConstructors"}; |  | 
| 1175             $extendedAttributeList->{"CustomConstructor"} = "VALUE_IS_MISSING"; |  | 
| 1176         } |  | 
| 1177         $newDataNode->extendedAttributes($extendedAttributeList); |  | 
| 1178         return $newDataNode; |  | 
| 1179     } |  | 
| 1180     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1181 } |  | 
| 1182 |  | 
| 1183 sub parseInherit |  | 
| 1184 { |  | 
| 1185     my $self = shift; |  | 
| 1186     my $next = $self->nextToken(); |  | 
| 1187     if ($next->value() eq "inherit") { |  | 
| 1188         $self->assertTokenValue($self->getToken(), "inherit", __LINE__); |  | 
| 1189         return 1; |  | 
| 1190     } |  | 
| 1191     return 0; |  | 
| 1192 } |  | 
| 1193 |  | 
| 1194 sub parseReadOnly |  | 
| 1195 { |  | 
| 1196     my $self = shift; |  | 
| 1197     my $next = $self->nextToken(); |  | 
| 1198     if ($next->value() eq "readonly") { |  | 
| 1199         $self->assertTokenValue($self->getToken(), "readonly", __LINE__); |  | 
| 1200         return 1; |  | 
| 1201     } |  | 
| 1202     return 0; |  | 
| 1203 } |  | 
| 1204 |  | 
| 1205 sub parseOperationOrIterator |  | 
| 1206 { |  | 
| 1207     my $self = shift; |  | 
| 1208     my $extendedAttributeList = shift; |  | 
| 1209 |  | 
| 1210     my $next = $self->nextToken(); |  | 
| 1211     if ($next->value() =~ /$nextSpecials_1/) { |  | 
| 1212         return $self->parseSpecialOperation($extendedAttributeList); |  | 
| 1213     } |  | 
| 1214     if ($next->type() == IdentifierToken || $next->value() =~ /$nextAttributeOrO
      perationRest_1/) { |  | 
| 1215         my $returnType = $self->parseReturnType(); |  | 
| 1216         my $interface = $self->parseOperationOrIteratorRest($extendedAttributeLi
      st); |  | 
| 1217         if (defined ($interface)) { |  | 
| 1218             $interface->type($returnType); |  | 
| 1219         } |  | 
| 1220         return $interface; |  | 
| 1221     } |  | 
| 1222     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1223 } |  | 
| 1224 |  | 
| 1225 sub parseSpecialOperation |  | 
| 1226 { |  | 
| 1227     my $self = shift; |  | 
| 1228     my $extendedAttributeList = shift; |  | 
| 1229 |  | 
| 1230     my $next = $self->nextToken(); |  | 
| 1231     if ($next->value() =~ /$nextSpecials_1/) { |  | 
| 1232         my @specials = (); |  | 
| 1233         push(@specials, @{$self->parseSpecials()}); |  | 
| 1234         my $returnType = $self->parseReturnType(); |  | 
| 1235         my $function = $self->parseOperationRest($extendedAttributeList); |  | 
| 1236         if (defined ($function)) { |  | 
| 1237             $function->type($returnType); |  | 
| 1238             $function->specials(\@specials); |  | 
| 1239         } |  | 
| 1240         return $function; |  | 
| 1241     } |  | 
| 1242     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1243 } |  | 
| 1244 |  | 
| 1245 sub parseSpecials |  | 
| 1246 { |  | 
| 1247     my $self = shift; |  | 
| 1248     my @specials = (); |  | 
| 1249 |  | 
| 1250     while (1) { |  | 
| 1251         my $next = $self->nextToken(); |  | 
| 1252         if ($next->value() =~ /$nextSpecials_1/) { |  | 
| 1253             push(@specials, $self->parseSpecial()); |  | 
| 1254         } else { |  | 
| 1255             last; |  | 
| 1256         } |  | 
| 1257     } |  | 
| 1258     return \@specials; |  | 
| 1259 } |  | 
| 1260 |  | 
| 1261 sub parseSpecial |  | 
| 1262 { |  | 
| 1263     my $self = shift; |  | 
| 1264     my $next = $self->nextToken(); |  | 
| 1265     if ($next->value() eq "getter") { |  | 
| 1266         $self->assertTokenValue($self->getToken(), "getter", __LINE__); |  | 
| 1267         return "getter"; |  | 
| 1268     } |  | 
| 1269     if ($next->value() eq "setter") { |  | 
| 1270         $self->assertTokenValue($self->getToken(), "setter", __LINE__); |  | 
| 1271         return "setter"; |  | 
| 1272     } |  | 
| 1273     if ($next->value() eq "creator") { |  | 
| 1274         $self->assertTokenValue($self->getToken(), "creator", __LINE__); |  | 
| 1275         return "creator"; |  | 
| 1276     } |  | 
| 1277     if ($next->value() eq "deleter") { |  | 
| 1278         $self->assertTokenValue($self->getToken(), "deleter", __LINE__); |  | 
| 1279         return "deleter"; |  | 
| 1280     } |  | 
| 1281     if ($next->value() eq "legacycaller") { |  | 
| 1282         $self->assertTokenValue($self->getToken(), "legacycaller", __LINE__); |  | 
| 1283         return "legacycaller"; |  | 
| 1284     } |  | 
| 1285     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1286 } |  | 
| 1287 |  | 
| 1288 sub parseOperationOrIteratorRest |  | 
| 1289 { |  | 
| 1290     my $self = shift; |  | 
| 1291     my $extendedAttributeList = shift; |  | 
| 1292 |  | 
| 1293     my $next = $self->nextToken(); |  | 
| 1294     if ($next->value() eq "iterator") { |  | 
| 1295         return $self->parseIteratorRest($extendedAttributeList); |  | 
| 1296     } |  | 
| 1297     if ($next->type() == IdentifierToken || $next->value() eq "(") { |  | 
| 1298         return $self->parseOperationRest($extendedAttributeList); |  | 
| 1299     } |  | 
| 1300     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1301 } |  | 
| 1302 |  | 
| 1303 sub parseIteratorRest |  | 
| 1304 { |  | 
| 1305     my $self = shift; |  | 
| 1306     my $extendedAttributeList = shift; |  | 
| 1307 |  | 
| 1308     my $next = $self->nextToken(); |  | 
| 1309     if ($next->value() eq "iterator") { |  | 
| 1310         $self->assertTokenValue($self->getToken(), "iterator", __LINE__); |  | 
| 1311         $self->parseOptionalIteratorInterfaceOrObject($extendedAttributeList); |  | 
| 1312         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 1313         return; |  | 
| 1314     } |  | 
| 1315     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1316 } |  | 
| 1317 |  | 
| 1318 sub parseOptionalIteratorInterfaceOrObject |  | 
| 1319 { |  | 
| 1320     my $self = shift; |  | 
| 1321     my $extendedAttributeList = shift; |  | 
| 1322 |  | 
| 1323     my $next = $self->nextToken(); |  | 
| 1324     if ($next->value() =~ /$nextOptionalIteratorInterfaceOrObject_1/) { |  | 
| 1325         return $self->parseOptionalIteratorInterface($extendedAttributeList); |  | 
| 1326     } |  | 
| 1327     if ($next->value() eq "object") { |  | 
| 1328         $self->assertTokenValue($self->getToken(), "object", __LINE__); |  | 
| 1329         return; |  | 
| 1330     } |  | 
| 1331     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1332 } |  | 
| 1333 |  | 
| 1334 sub parseOptionalIteratorInterface |  | 
| 1335 { |  | 
| 1336     my $self = shift; |  | 
| 1337     my $extendedAttributeList = shift; |  | 
| 1338 |  | 
| 1339     my $next = $self->nextToken(); |  | 
| 1340     if ($next->value() eq "=") { |  | 
| 1341         $self->assertTokenValue($self->getToken(), "=", __LINE__); |  | 
| 1342         $self->assertTokenType($self->getToken(), IdentifierToken); |  | 
| 1343     } |  | 
| 1344 } |  | 
| 1345 |  | 
| 1346 sub parseOperationRest |  | 
| 1347 { |  | 
| 1348     my $self = shift; |  | 
| 1349     my $extendedAttributeList = shift; |  | 
| 1350 |  | 
| 1351     my $next = $self->nextToken(); |  | 
| 1352     if ($next->type() == IdentifierToken || $next->value() eq "(") { |  | 
| 1353         my $newDataNode = domFunction->new(); |  | 
| 1354         my $name = $self->parseOptionalIdentifier(); |  | 
| 1355         $newDataNode->name($name); |  | 
| 1356         $self->assertTokenValue($self->getToken(), "(", __LINE__); |  | 
| 1357         push(@{$newDataNode->parameters}, @{$self->parseArgumentList()}); |  | 
| 1358         $self->assertTokenValue($self->getToken(), ")", __LINE__); |  | 
| 1359         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 1360         $newDataNode->extendedAttributes($extendedAttributeList); |  | 
| 1361         return $newDataNode; |  | 
| 1362     } |  | 
| 1363     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1364 } |  | 
| 1365 |  | 
| 1366 sub parseOptionalIdentifier |  | 
| 1367 { |  | 
| 1368     my $self = shift; |  | 
| 1369     my $next = $self->nextToken(); |  | 
| 1370     if ($next->type() == IdentifierToken) { |  | 
| 1371         my $token = $self->getToken(); |  | 
| 1372         return $token->value(); |  | 
| 1373     } |  | 
| 1374     return ""; |  | 
| 1375 } |  | 
| 1376 |  | 
| 1377 sub parseArgumentList |  | 
| 1378 { |  | 
| 1379     my $self = shift; |  | 
| 1380     my @arguments = (); |  | 
| 1381 |  | 
| 1382     my $next = $self->nextToken(); |  | 
| 1383     if ($next->type() == IdentifierToken || $next->value() =~ /$nextArgumentList
      _1/) { |  | 
| 1384         push(@arguments, $self->parseArgument()); |  | 
| 1385         push(@arguments, @{$self->parseArguments()}); |  | 
| 1386     } |  | 
| 1387     return \@arguments; |  | 
| 1388 } |  | 
| 1389 |  | 
| 1390 sub parseArguments |  | 
| 1391 { |  | 
| 1392     my $self = shift; |  | 
| 1393     my @arguments = (); |  | 
| 1394 |  | 
| 1395     while (1) { |  | 
| 1396         my $next = $self->nextToken(); |  | 
| 1397         if ($next->value() eq ",") { |  | 
| 1398             $self->assertTokenValue($self->getToken(), ",", __LINE__); |  | 
| 1399             push(@arguments, $self->parseArgument()); |  | 
| 1400         } else { |  | 
| 1401             last; |  | 
| 1402         } |  | 
| 1403     } |  | 
| 1404     return \@arguments; |  | 
| 1405 } |  | 
| 1406 |  | 
| 1407 sub parseArgument |  | 
| 1408 { |  | 
| 1409     my $self = shift; |  | 
| 1410     my $next = $self->nextToken(); |  | 
| 1411     if ($next->type() == IdentifierToken || $next->value() =~ /$nextArgumentList
      _1/) { |  | 
| 1412         my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty(
      ); |  | 
| 1413         my $argument = $self->parseOptionalOrRequiredArgument($extendedAttribute
      List); |  | 
| 1414         return $argument; |  | 
| 1415     } |  | 
| 1416     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1417 } |  | 
| 1418 |  | 
| 1419 sub parseOptionalOrRequiredArgument |  | 
| 1420 { |  | 
| 1421     my $self = shift; |  | 
| 1422     my $extendedAttributeList = shift; |  | 
| 1423 |  | 
| 1424     my $paramDataNode = domParameter->new(); |  | 
| 1425     $paramDataNode->extendedAttributes($extendedAttributeList); |  | 
| 1426 |  | 
| 1427     my $next = $self->nextToken(); |  | 
| 1428     if ($next->value() eq "optional") { |  | 
| 1429         $self->assertTokenValue($self->getToken(), "optional", __LINE__); |  | 
| 1430         my $type = $self->parseType(); |  | 
| 1431         # domDataNode can only consider last "?". |  | 
| 1432         $paramDataNode->isNullable(typeHasNullableSuffix($type)); |  | 
| 1433         # Remove all "?" if exists, e.g. "object?[]?" -> "object[]". |  | 
| 1434         $paramDataNode->type(typeRemoveNullableSuffix($type)); |  | 
| 1435         $paramDataNode->isOptional(1); |  | 
| 1436         $paramDataNode->name($self->parseArgumentName()); |  | 
| 1437         $self->parseDefault(); |  | 
| 1438         return $paramDataNode; |  | 
| 1439     } |  | 
| 1440     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionFie
      ld_1/) { |  | 
| 1441         my $type = $self->parseType(); |  | 
| 1442         # domDataNode can only consider last "?". |  | 
| 1443         $paramDataNode->isNullable(typeHasNullableSuffix($type)); |  | 
| 1444         # Remove all "?" if exists, e.g. "object?[]?" -> "object[]". |  | 
| 1445         $paramDataNode->type(typeRemoveNullableSuffix($type)); |  | 
| 1446         $paramDataNode->isOptional(0); |  | 
| 1447         $paramDataNode->isVariadic($self->parseEllipsis()); |  | 
| 1448         $paramDataNode->name($self->parseArgumentName()); |  | 
| 1449         return $paramDataNode; |  | 
| 1450     } |  | 
| 1451     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1452 } |  | 
| 1453 |  | 
| 1454 sub parseArgumentName |  | 
| 1455 { |  | 
| 1456     my $self = shift; |  | 
| 1457     my $next = $self->nextToken(); |  | 
| 1458     if ($next->value() =~ /$nextArgumentName_1/) { |  | 
| 1459         return $self->parseArgumentNameKeyword(); |  | 
| 1460     } |  | 
| 1461     if ($next->type() == IdentifierToken) { |  | 
| 1462         return $self->getToken()->value(); |  | 
| 1463     } |  | 
| 1464     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1465 } |  | 
| 1466 |  | 
| 1467 sub parseEllipsis |  | 
| 1468 { |  | 
| 1469     my $self = shift; |  | 
| 1470     my $next = $self->nextToken(); |  | 
| 1471     if ($next->value() eq "...") { |  | 
| 1472         $self->assertTokenValue($self->getToken(), "...", __LINE__); |  | 
| 1473         return 1; |  | 
| 1474     } |  | 
| 1475     return 0; |  | 
| 1476 } |  | 
| 1477 |  | 
| 1478 sub parseExceptionMember |  | 
| 1479 { |  | 
| 1480     my $self = shift; |  | 
| 1481     my $extendedAttributeList = shift; |  | 
| 1482 |  | 
| 1483     my $next = $self->nextToken(); |  | 
| 1484     if ($next->value() eq "const") { |  | 
| 1485         return $self->parseConst($extendedAttributeList); |  | 
| 1486     } |  | 
| 1487     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionFie
      ld_1/) { |  | 
| 1488         return $self->parseExceptionField($extendedAttributeList); |  | 
| 1489     } |  | 
| 1490     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1491 } |  | 
| 1492 |  | 
| 1493 sub parseExceptionField |  | 
| 1494 { |  | 
| 1495     my $self = shift; |  | 
| 1496     my $extendedAttributeList = shift; |  | 
| 1497 |  | 
| 1498     my $next = $self->nextToken(); |  | 
| 1499     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionFie
      ld_1/) { |  | 
| 1500         my $newDataNode = domAttribute->new(); |  | 
| 1501         $newDataNode->type("attribute"); |  | 
| 1502         $newDataNode->isReadOnly(1); |  | 
| 1503         $newDataNode->type($self->parseType()); |  | 
| 1504         my $token = $self->getToken(); |  | 
| 1505         $self->assertTokenType($token, IdentifierToken); |  | 
| 1506         $newDataNode->name($token->value()); |  | 
| 1507         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 1508         $newDataNode->extendedAttributes($extendedAttributeList); |  | 
| 1509         return $newDataNode; |  | 
| 1510     } |  | 
| 1511     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1512 } |  | 
| 1513 |  | 
| 1514 sub parseExtendedAttributeListAllowEmpty |  | 
| 1515 { |  | 
| 1516     my $self = shift; |  | 
| 1517     my $next = $self->nextToken(); |  | 
| 1518     if ($next->value() eq "[") { |  | 
| 1519         return $self->parseExtendedAttributeList(); |  | 
| 1520     } |  | 
| 1521     return {}; |  | 
| 1522 } |  | 
| 1523 |  | 
| 1524 sub copyExtendedAttributes |  | 
| 1525 { |  | 
| 1526     my $extendedAttributeList = shift; |  | 
| 1527     my $attr = shift; |  | 
| 1528 |  | 
| 1529     for my $key (keys %{$attr}) { |  | 
| 1530         if ($key eq "Constructor") { |  | 
| 1531             push(@{$extendedAttributeList->{"Constructors"}}, $attr->{$key}); |  | 
| 1532         } elsif ($key eq "Constructors") { |  | 
| 1533             my @constructors = @{$attr->{$key}}; |  | 
| 1534             foreach my $constructor (@constructors) { |  | 
| 1535                 push(@{$extendedAttributeList->{"Constructors"}}, $constructor); |  | 
| 1536             } |  | 
| 1537         } elsif ($key eq "CustomConstructor") { |  | 
| 1538             push(@{$extendedAttributeList->{"CustomConstructors"}}, $attr->{$key
      }); |  | 
| 1539         } elsif ($key eq "CustomConstructors") { |  | 
| 1540            my @customConstructors = @{$attr->{$key}}; |  | 
| 1541             foreach my $customConstructor (@customConstructors) { |  | 
| 1542                 push(@{$extendedAttributeList->{"CustomConstructors"}}, $customC
      onstructor); |  | 
| 1543             } |  | 
| 1544         } else { |  | 
| 1545             $extendedAttributeList->{$key} = $attr->{$key}; |  | 
| 1546         } |  | 
| 1547     } |  | 
| 1548 } |  | 
| 1549 |  | 
| 1550 sub parseExtendedAttributeList |  | 
| 1551 { |  | 
| 1552     my $self = shift; |  | 
| 1553     my $next = $self->nextToken(); |  | 
| 1554     if ($next->value() eq "[") { |  | 
| 1555         $self->assertTokenValue($self->getToken(), "[", __LINE__); |  | 
| 1556         my $extendedAttributeList = {}; |  | 
| 1557         my $attr = $self->parseExtendedAttribute(); |  | 
| 1558         copyExtendedAttributes($extendedAttributeList, $attr); |  | 
| 1559         $attr = $self->parseExtendedAttributes(); |  | 
| 1560         copyExtendedAttributes($extendedAttributeList, $attr); |  | 
| 1561         $self->assertTokenValue($self->getToken(), "]", __LINE__); |  | 
| 1562         return $extendedAttributeList; |  | 
| 1563     } |  | 
| 1564     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1565 } |  | 
| 1566 |  | 
| 1567 sub parseExtendedAttributes |  | 
| 1568 { |  | 
| 1569     my $self = shift; |  | 
| 1570     my $extendedAttributeList = {}; |  | 
| 1571 |  | 
| 1572     while (1) { |  | 
| 1573         my $next = $self->nextToken(); |  | 
| 1574         if ($next->value() eq ",") { |  | 
| 1575             $self->assertTokenValue($self->getToken(), ",", __LINE__); |  | 
| 1576             my $attr = $self->parseExtendedAttribute2(); |  | 
| 1577             copyExtendedAttributes($extendedAttributeList, $attr); |  | 
| 1578         } else { |  | 
| 1579             last; |  | 
| 1580         } |  | 
| 1581     } |  | 
| 1582     return $extendedAttributeList; |  | 
| 1583 } |  | 
| 1584 |  | 
| 1585 sub parseExtendedAttribute |  | 
| 1586 { |  | 
| 1587     my $self = shift; |  | 
| 1588     my $next = $self->nextToken(); |  | 
| 1589     if ($next->type() == IdentifierToken || $next->value() eq "::") { |  | 
| 1590         my $scopedName = $self->parseScopedName(); |  | 
| 1591         return $self->parseExtendedAttributeRest($scopedName); |  | 
| 1592     } |  | 
| 1593     # backward compatibility. Spec doesn' allow "[]". But WebKit requires. |  | 
| 1594     if ($next->value() eq ']') { |  | 
| 1595         return {}; |  | 
| 1596     } |  | 
| 1597     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1598 } |  | 
| 1599 |  | 
| 1600 sub parseExtendedAttribute2 |  | 
| 1601 { |  | 
| 1602     my $self = shift; |  | 
| 1603     my $next = $self->nextToken(); |  | 
| 1604     if ($next->type() == IdentifierToken || $next->value() eq "::") { |  | 
| 1605         my $scopedName = $self->parseScopedName(); |  | 
| 1606         return $self->parseExtendedAttributeRest($scopedName); |  | 
| 1607     } |  | 
| 1608     return {}; |  | 
| 1609 } |  | 
| 1610 |  | 
| 1611 sub parseExtendedAttributeRest |  | 
| 1612 { |  | 
| 1613     my $self = shift; |  | 
| 1614     my $name = shift; |  | 
| 1615     my $attrs = {}; |  | 
| 1616 |  | 
| 1617     my $next = $self->nextToken(); |  | 
| 1618     if ($next->value() eq "(") { |  | 
| 1619         $self->assertTokenValue($self->getToken(), "(", __LINE__); |  | 
| 1620         $attrs->{$name} = $self->parseArgumentList(); |  | 
| 1621         $self->assertTokenValue($self->getToken(), ")", __LINE__); |  | 
| 1622         return $attrs; |  | 
| 1623     } |  | 
| 1624     if ($next->value() eq "=") { |  | 
| 1625         $self->assertTokenValue($self->getToken(), "=", __LINE__); |  | 
| 1626         $attrs->{$name} = $self->parseExtendedAttributeRest2(); |  | 
| 1627         return $attrs; |  | 
| 1628     } |  | 
| 1629 |  | 
| 1630     if ($name eq "Constructor" || $name eq "CustomConstructor") { |  | 
| 1631         $attrs->{$name} = []; |  | 
| 1632     } else { |  | 
| 1633         $attrs->{$name} = "VALUE_IS_MISSING"; |  | 
| 1634     } |  | 
| 1635     return $attrs; |  | 
| 1636 } |  | 
| 1637 |  | 
| 1638 sub parseExtendedAttributeRest2 |  | 
| 1639 { |  | 
| 1640     my $self = shift; |  | 
| 1641     my $next = $self->nextToken(); |  | 
| 1642     if ($next->type() == IdentifierToken || $next->value() eq "::") { |  | 
| 1643         my $scopedName = $self->parseScopedName(); |  | 
| 1644         return $self->parseExtendedAttributeRest3($scopedName); |  | 
| 1645     } |  | 
| 1646     if ($next->type() == IntegerToken) { |  | 
| 1647         my $token = $self->getToken(); |  | 
| 1648         return $token->value(); |  | 
| 1649     } |  | 
| 1650     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1651 } |  | 
| 1652 |  | 
| 1653 sub parseExtendedAttributeRest3 |  | 
| 1654 { |  | 
| 1655     my $self = shift; |  | 
| 1656     my $name = shift; |  | 
| 1657 |  | 
| 1658     my $next = $self->nextToken(); |  | 
| 1659     if ($next->value() eq "&") { |  | 
| 1660         $self->assertTokenValue($self->getToken(), "&", __LINE__); |  | 
| 1661         my $rightValue = $self->parseScopedName(); |  | 
| 1662         return $name . "&" . $rightValue; |  | 
| 1663     } |  | 
| 1664     if ($next->value() eq "|") { |  | 
| 1665         $self->assertTokenValue($self->getToken(), "|", __LINE__); |  | 
| 1666         my $rightValue = $self->parseScopedName(); |  | 
| 1667         return $name . "|" . $rightValue; |  | 
| 1668     } |  | 
| 1669     if ($next->value() eq "(") { |  | 
| 1670         my $attr = {}; |  | 
| 1671         $self->assertTokenValue($self->getToken(), "(", __LINE__); |  | 
| 1672         $attr->{$name} = $self->parseArgumentList(); |  | 
| 1673         $self->assertTokenValue($self->getToken(), ")", __LINE__); |  | 
| 1674         return $attr; |  | 
| 1675     } |  | 
| 1676     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExtendedAttr
      ibuteRest3_1/) { |  | 
| 1677         my @names = (); |  | 
| 1678         push(@names, $name); |  | 
| 1679         push(@names, @{$self->parseScopedNameListNoComma()}); |  | 
| 1680         return join(' ', @names); |  | 
| 1681     } |  | 
| 1682     $self->assertUnexpectedToken($next->value()); |  | 
| 1683 } |  | 
| 1684 |  | 
| 1685 sub parseScopedNameListNoComma |  | 
| 1686 { |  | 
| 1687     my $self = shift; |  | 
| 1688     my @names = (); |  | 
| 1689 |  | 
| 1690     while (1) { |  | 
| 1691         my $next = $self->nextToken(); |  | 
| 1692         if ($next->type() == IdentifierToken || $next->value() eq "::") { |  | 
| 1693             push(@names, $self->parseScopedName()); |  | 
| 1694         } else { |  | 
| 1695             last; |  | 
| 1696         } |  | 
| 1697     } |  | 
| 1698     return \@names; |  | 
| 1699 } |  | 
| 1700 |  | 
| 1701 sub parseArgumentNameKeyword |  | 
| 1702 { |  | 
| 1703     my $self = shift; |  | 
| 1704     my $next = $self->nextToken(); |  | 
| 1705     if ($next->value() eq "attribute") { |  | 
| 1706         return $self->getToken()->value(); |  | 
| 1707     } |  | 
| 1708     if ($next->value() eq "callback") { |  | 
| 1709         return $self->getToken()->value(); |  | 
| 1710     } |  | 
| 1711     if ($next->value() eq "const") { |  | 
| 1712         return $self->getToken()->value(); |  | 
| 1713     } |  | 
| 1714     if ($next->value() eq "creator") { |  | 
| 1715         return $self->getToken()->value(); |  | 
| 1716     } |  | 
| 1717     if ($next->value() eq "deleter") { |  | 
| 1718         return $self->getToken()->value(); |  | 
| 1719     } |  | 
| 1720     if ($next->value() eq "dictionary") { |  | 
| 1721         return $self->getToken()->value(); |  | 
| 1722     } |  | 
| 1723     if ($next->value() eq "enum") { |  | 
| 1724         return $self->getToken()->value(); |  | 
| 1725     } |  | 
| 1726     if ($next->value() eq "exception") { |  | 
| 1727         return $self->getToken()->value(); |  | 
| 1728     } |  | 
| 1729     if ($next->value() eq "getter") { |  | 
| 1730         return $self->getToken()->value(); |  | 
| 1731     } |  | 
| 1732     if ($next->value() eq "implements") { |  | 
| 1733         return $self->getToken()->value(); |  | 
| 1734     } |  | 
| 1735     if ($next->value() eq "inherit") { |  | 
| 1736         return $self->getToken()->value(); |  | 
| 1737     } |  | 
| 1738     if ($next->value() eq "interface") { |  | 
| 1739         return $self->getToken()->value(); |  | 
| 1740     } |  | 
| 1741     if ($next->value() eq "legacycaller") { |  | 
| 1742         return $self->getToken()->value(); |  | 
| 1743     } |  | 
| 1744     if ($next->value() eq "partial") { |  | 
| 1745         return $self->getToken()->value(); |  | 
| 1746     } |  | 
| 1747     if ($next->value() eq "serializer") { |  | 
| 1748         return $self->getToken()->value(); |  | 
| 1749     } |  | 
| 1750     if ($next->value() eq "setter") { |  | 
| 1751         return $self->getToken()->value(); |  | 
| 1752     } |  | 
| 1753     if ($next->value() eq "static") { |  | 
| 1754         return $self->getToken()->value(); |  | 
| 1755     } |  | 
| 1756     if ($next->value() eq "stringifier") { |  | 
| 1757         return $self->getToken()->value(); |  | 
| 1758     } |  | 
| 1759     if ($next->value() eq "typedef") { |  | 
| 1760         return $self->getToken()->value(); |  | 
| 1761     } |  | 
| 1762     if ($next->value() eq "unrestricted") { |  | 
| 1763         return $self->getToken()->value(); |  | 
| 1764     } |  | 
| 1765     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1766 } |  | 
| 1767 |  | 
| 1768 sub parseType |  | 
| 1769 { |  | 
| 1770     my $self = shift; |  | 
| 1771     my $next = $self->nextToken(); |  | 
| 1772     if ($next->value() eq "(") { |  | 
| 1773         my $unionType = $self->parseUnionType(); |  | 
| 1774         my $suffix = $self->parseTypeSuffix(); |  | 
| 1775         die "Suffix after UnionType is not supported." if $suffix ne ""; |  | 
| 1776         return $unionType; |  | 
| 1777     } |  | 
| 1778     if ($next->type() == IdentifierToken || $next->value() =~ /$nextType_1/) { |  | 
| 1779         return $self->parseSingleType(); |  | 
| 1780     } |  | 
| 1781     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1782 } |  | 
| 1783 |  | 
| 1784 sub parseSingleType |  | 
| 1785 { |  | 
| 1786     my $self = shift; |  | 
| 1787     my $next = $self->nextToken(); |  | 
| 1788     if ($next->value() eq "any") { |  | 
| 1789         $self->assertTokenValue($self->getToken(), "any", __LINE__); |  | 
| 1790         return "any" . $self->parseTypeSuffixStartingWithArray(); |  | 
| 1791     } |  | 
| 1792     if ($next->type() == IdentifierToken || $next->value() =~ /$nextSingleType_1
      /) { |  | 
| 1793         return $self->parseNonAnyType(); |  | 
| 1794     } |  | 
| 1795     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1796 } |  | 
| 1797 |  | 
| 1798 sub parseUnionType |  | 
| 1799 { |  | 
| 1800     my $self = shift; |  | 
| 1801     my $next = $self->nextToken(); |  | 
| 1802     if ($next->value() eq "(") { |  | 
| 1803         my $unionType = UnionType->new(); |  | 
| 1804         $self->assertTokenValue($self->getToken(), "(", __LINE__); |  | 
| 1805         push @{$unionType->unionMemberTypes}, $self->parseUnionMemberType(); |  | 
| 1806         $self->assertTokenValue($self->getToken(), "or", __LINE__); |  | 
| 1807         push @{$unionType->unionMemberTypes}, $self->parseUnionMemberType(); |  | 
| 1808         push @{$unionType->unionMemberTypes}, $self->parseUnionMemberTypes(); |  | 
| 1809         $self->assertTokenValue($self->getToken(), ")", __LINE__); |  | 
| 1810         return $unionType; |  | 
| 1811     } |  | 
| 1812     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1813 } |  | 
| 1814 |  | 
| 1815 # Returns UnionType or string |  | 
| 1816 sub parseUnionMemberType |  | 
| 1817 { |  | 
| 1818     my $self = shift; |  | 
| 1819     my $next = $self->nextToken(); |  | 
| 1820     if ($next->value() eq "(") { |  | 
| 1821         my $unionType = $self->parseUnionType(); |  | 
| 1822         my $suffix = $self->parseTypeSuffix(); |  | 
| 1823         die "Suffix after UnionType is not supported." if $suffix ne ""; |  | 
| 1824         return $unionType; |  | 
| 1825     } |  | 
| 1826     if ($next->value() eq "any") { |  | 
| 1827         my $type = $self->assertTokenValue($self->getToken(), "any", __LINE__); |  | 
| 1828         $type .= $self->assertTokenValue($self->getToken(), "[", __LINE__); |  | 
| 1829         $type .= $self->assertTokenValue($self->getToken(), "]", __LINE__); |  | 
| 1830         $type .= $self->parseTypeSuffix(); |  | 
| 1831         return $type; |  | 
| 1832     } |  | 
| 1833     if ($next->type() == IdentifierToken || $next->value() =~ /$nextSingleType_1
      /) { |  | 
| 1834         return $self->parseNonAnyType(); |  | 
| 1835     } |  | 
| 1836     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1837 } |  | 
| 1838 |  | 
| 1839 sub parseUnionMemberTypes |  | 
| 1840 { |  | 
| 1841     my $self = shift; |  | 
| 1842     my @types = (); |  | 
| 1843     my $next = $self->nextToken(); |  | 
| 1844     if ($next->value() eq "or") { |  | 
| 1845         $self->assertTokenValue($self->getToken(), "or", __LINE__); |  | 
| 1846         push @types, $self->parseUnionMemberType(); |  | 
| 1847         push @types, $self->parseUnionMemberTypes(); |  | 
| 1848     } |  | 
| 1849     return @types; |  | 
| 1850 } |  | 
| 1851 |  | 
| 1852 sub parseNonAnyType |  | 
| 1853 { |  | 
| 1854     my $self = shift; |  | 
| 1855     my $next = $self->nextToken(); |  | 
| 1856     if ($next->value() =~ /$nextNonAnyType_1/) { |  | 
| 1857         return $self->parsePrimitiveType() . $self->parseTypeSuffix(); |  | 
| 1858     } |  | 
| 1859     if ($next->value() eq "ByteString") { |  | 
| 1860         $self->assertTokenValue($self->getToken(), "ByteString", __LINE__); |  | 
| 1861         return "ByteString" . $self->parseTypeSuffix(); |  | 
| 1862     } |  | 
| 1863     if ($next->value() eq "DOMString") { |  | 
| 1864         $self->assertTokenValue($self->getToken(), "DOMString", __LINE__); |  | 
| 1865         return "DOMString" . $self->parseTypeSuffix(); |  | 
| 1866     } |  | 
| 1867     if ($next->value() eq "Promise") { |  | 
| 1868         $self->assertTokenValue($self->getToken(), "Promise", __LINE__); |  | 
| 1869         return "Promise" . $self->parseTypeSuffix(); |  | 
| 1870     } |  | 
| 1871     if ($next->value() eq "sequence") { |  | 
| 1872         $self->assertTokenValue($self->getToken(), "sequence", __LINE__); |  | 
| 1873         $self->assertTokenValue($self->getToken(), "<", __LINE__); |  | 
| 1874         my $type = $self->parseType(); |  | 
| 1875         $self->assertTokenValue($self->getToken(), ">", __LINE__); |  | 
| 1876         return "sequence<" . $type . ">" . $self->parseNull(); |  | 
| 1877     } |  | 
| 1878     if ($next->value() eq "object") { |  | 
| 1879         $self->assertTokenValue($self->getToken(), "object", __LINE__); |  | 
| 1880         return "object" . $self->parseTypeSuffix(); |  | 
| 1881     } |  | 
| 1882     if ($next->value() eq "Date") { |  | 
| 1883         $self->assertTokenValue($self->getToken(), "Date", __LINE__); |  | 
| 1884         return "Date" . $self->parseTypeSuffix(); |  | 
| 1885     } |  | 
| 1886     if ($next->type() == IdentifierToken || $next->value() eq "::") { |  | 
| 1887         my $name = $self->parseScopedName(); |  | 
| 1888         return $name . $self->parseTypeSuffix(); |  | 
| 1889     } |  | 
| 1890     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1891 } |  | 
| 1892 |  | 
| 1893 sub parseConstType |  | 
| 1894 { |  | 
| 1895     my $self = shift; |  | 
| 1896     my $next = $self->nextToken(); |  | 
| 1897     if ($next->value() =~ /$nextNonAnyType_1/) { |  | 
| 1898         return $self->parsePrimitiveType() . $self->parseNull(); |  | 
| 1899     } |  | 
| 1900     if ($next->type() == IdentifierToken) { |  | 
| 1901         my $token = $self->getToken(); |  | 
| 1902         return $token->value() . $self->parseNull(); |  | 
| 1903     } |  | 
| 1904     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1905 } |  | 
| 1906 |  | 
| 1907 sub parsePrimitiveType |  | 
| 1908 { |  | 
| 1909     my $self = shift; |  | 
| 1910     my $next = $self->nextToken(); |  | 
| 1911     if ($next->value() =~ /$nextPrimitiveType_1/) { |  | 
| 1912         return $self->parseUnsignedIntegerType(); |  | 
| 1913     } |  | 
| 1914     if ($next->value() =~ /$nextPrimitiveType_2/) { |  | 
| 1915         return $self->parseUnrestrictedFloatType(); |  | 
| 1916     } |  | 
| 1917     if ($next->value() eq "boolean") { |  | 
| 1918         $self->assertTokenValue($self->getToken(), "boolean", __LINE__); |  | 
| 1919         return "boolean"; |  | 
| 1920     } |  | 
| 1921     if ($next->value() eq "byte") { |  | 
| 1922         $self->assertTokenValue($self->getToken(), "byte", __LINE__); |  | 
| 1923         return "byte"; |  | 
| 1924     } |  | 
| 1925     if ($next->value() eq "octet") { |  | 
| 1926         $self->assertTokenValue($self->getToken(), "octet", __LINE__); |  | 
| 1927         return "octet"; |  | 
| 1928     } |  | 
| 1929     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1930 } |  | 
| 1931 |  | 
| 1932 sub parseUnrestrictedFloatType |  | 
| 1933 { |  | 
| 1934     my $self = shift; |  | 
| 1935     my $next = $self->nextToken(); |  | 
| 1936     if ($next->value() eq "unrestricted") { |  | 
| 1937         $self->assertTokenValue($self->getToken(), "unrestricted", __LINE__); |  | 
| 1938         return "unrestricted " . $self->parseFloatType(); |  | 
| 1939     } |  | 
| 1940     if ($next->value() =~ /$nextUnrestrictedFloatType_1/) { |  | 
| 1941         return $self->parseFloatType(); |  | 
| 1942     } |  | 
| 1943     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1944 } |  | 
| 1945 |  | 
| 1946 sub parseFloatType |  | 
| 1947 { |  | 
| 1948     my $self = shift; |  | 
| 1949     my $next = $self->nextToken(); |  | 
| 1950     if ($next->value() eq "float") { |  | 
| 1951         $self->assertTokenValue($self->getToken(), "float", __LINE__); |  | 
| 1952         return "float"; |  | 
| 1953     } |  | 
| 1954     if ($next->value() eq "double") { |  | 
| 1955         $self->assertTokenValue($self->getToken(), "double", __LINE__); |  | 
| 1956         return "double"; |  | 
| 1957     } |  | 
| 1958     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1959 } |  | 
| 1960 |  | 
| 1961 sub parseUnsignedIntegerType |  | 
| 1962 { |  | 
| 1963     my $self = shift; |  | 
| 1964     my $next = $self->nextToken(); |  | 
| 1965     if ($next->value() eq "unsigned") { |  | 
| 1966         $self->assertTokenValue($self->getToken(), "unsigned", __LINE__); |  | 
| 1967         return "unsigned " . $self->parseIntegerType(); |  | 
| 1968     } |  | 
| 1969     if ($next->value() =~ /$nextUnsignedIntegerType_1/) { |  | 
| 1970         return $self->parseIntegerType(); |  | 
| 1971     } |  | 
| 1972     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1973 } |  | 
| 1974 |  | 
| 1975 sub parseIntegerType |  | 
| 1976 { |  | 
| 1977     my $self = shift; |  | 
| 1978     my $next = $self->nextToken(); |  | 
| 1979     if ($next->value() eq "short") { |  | 
| 1980         $self->assertTokenValue($self->getToken(), "short", __LINE__); |  | 
| 1981         return "short"; |  | 
| 1982     } |  | 
| 1983     if ($next->value() eq "int") { |  | 
| 1984         $self->assertTokenValue($self->getToken(), "int", __LINE__); |  | 
| 1985         return "int"; |  | 
| 1986     } |  | 
| 1987     if ($next->value() eq "long") { |  | 
| 1988         $self->assertTokenValue($self->getToken(), "long", __LINE__); |  | 
| 1989         if ($self->parseOptionalLong()) { |  | 
| 1990             return "long long"; |  | 
| 1991         } |  | 
| 1992         return "long"; |  | 
| 1993     } |  | 
| 1994     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 1995 } |  | 
| 1996 |  | 
| 1997 sub parseOptionalLong |  | 
| 1998 { |  | 
| 1999     my $self = shift; |  | 
| 2000     my $next = $self->nextToken(); |  | 
| 2001     if ($next->value() eq "long") { |  | 
| 2002         $self->assertTokenValue($self->getToken(), "long", __LINE__); |  | 
| 2003         return 1; |  | 
| 2004     } |  | 
| 2005     return 0; |  | 
| 2006 } |  | 
| 2007 |  | 
| 2008 sub parseTypeSuffix |  | 
| 2009 { |  | 
| 2010     my $self = shift; |  | 
| 2011     my $next = $self->nextToken(); |  | 
| 2012     if ($next->value() eq "[") { |  | 
| 2013         $self->assertTokenValue($self->getToken(), "[", __LINE__); |  | 
| 2014         $self->assertTokenValue($self->getToken(), "]", __LINE__); |  | 
| 2015         return "[]" . $self->parseTypeSuffix(); |  | 
| 2016     } |  | 
| 2017     if ($next->value() eq "?") { |  | 
| 2018         $self->assertTokenValue($self->getToken(), "?", __LINE__); |  | 
| 2019         return "?" . $self->parseTypeSuffixStartingWithArray(); |  | 
| 2020     } |  | 
| 2021     return ""; |  | 
| 2022 } |  | 
| 2023 |  | 
| 2024 sub parseTypeSuffixStartingWithArray |  | 
| 2025 { |  | 
| 2026     my $self = shift; |  | 
| 2027     my $next = $self->nextToken(); |  | 
| 2028     if ($next->value() eq "[") { |  | 
| 2029         $self->assertTokenValue($self->getToken(), "[", __LINE__); |  | 
| 2030         $self->assertTokenValue($self->getToken(), "]", __LINE__); |  | 
| 2031         return "[]" . $self->parseTypeSuffix(); |  | 
| 2032     } |  | 
| 2033     return ""; |  | 
| 2034 } |  | 
| 2035 |  | 
| 2036 sub parseNull |  | 
| 2037 { |  | 
| 2038     my $self = shift; |  | 
| 2039     my $next = $self->nextToken(); |  | 
| 2040     if ($next->value() eq "?") { |  | 
| 2041         $self->assertTokenValue($self->getToken(), "?", __LINE__); |  | 
| 2042         return "?"; |  | 
| 2043     } |  | 
| 2044     return ""; |  | 
| 2045 } |  | 
| 2046 |  | 
| 2047 sub parseReturnType |  | 
| 2048 { |  | 
| 2049     my $self = shift; |  | 
| 2050     my $next = $self->nextToken(); |  | 
| 2051     if ($next->value() eq "void") { |  | 
| 2052         $self->assertTokenValue($self->getToken(), "void", __LINE__); |  | 
| 2053         return "void"; |  | 
| 2054     } |  | 
| 2055     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionFie
      ld_1/) { |  | 
| 2056         return $self->parseType(); |  | 
| 2057     } |  | 
| 2058     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 2059 } |  | 
| 2060 |  | 
| 2061 sub parseExceptionList |  | 
| 2062 { |  | 
| 2063     my $self = shift; |  | 
| 2064     my $next = $self->nextToken(); |  | 
| 2065     if ($next->value() eq "(") { |  | 
| 2066         my @exceptions = (); |  | 
| 2067         $self->assertTokenValue($self->getToken(), "(", __LINE__); |  | 
| 2068         push(@exceptions, @{$self->parseScopedNameList()}); |  | 
| 2069         $self->assertTokenValue($self->getToken(), ")", __LINE__); |  | 
| 2070         return \@exceptions; |  | 
| 2071     } |  | 
| 2072     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 2073 } |  | 
| 2074 |  | 
| 2075 sub parseRaises |  | 
| 2076 { |  | 
| 2077     my $self = shift; |  | 
| 2078     my $next = $self->nextToken(); |  | 
| 2079     if ($next->value() eq "raises") { |  | 
| 2080         $self->assertTokenValue($self->getToken(), "raises", __LINE__); |  | 
| 2081         return $self->parseExceptionList(); |  | 
| 2082     } |  | 
| 2083     return []; |  | 
| 2084 } |  | 
| 2085 |  | 
| 2086 sub parseOptionalSemicolon |  | 
| 2087 { |  | 
| 2088     my $self = shift; |  | 
| 2089     my $next = $self->nextToken(); |  | 
| 2090     if ($next->value() eq ";") { |  | 
| 2091         $self->assertTokenValue($self->getToken(), ";", __LINE__); |  | 
| 2092     } |  | 
| 2093 } |  | 
| 2094 |  | 
| 2095 sub parseScopedName |  | 
| 2096 { |  | 
| 2097     my $self = shift; |  | 
| 2098     my $next = $self->nextToken(); |  | 
| 2099     if ($next->value() eq "::") { |  | 
| 2100         return $self->parseAbsoluteScopedName(); |  | 
| 2101     } |  | 
| 2102     if ($next->type() == IdentifierToken) { |  | 
| 2103         return $self->parseRelativeScopedName(); |  | 
| 2104     } |  | 
| 2105     $self->assertUnexpectedToken($next->value()); |  | 
| 2106 } |  | 
| 2107 |  | 
| 2108 sub parseAbsoluteScopedName |  | 
| 2109 { |  | 
| 2110     my $self = shift; |  | 
| 2111     my $next = $self->nextToken(); |  | 
| 2112     if ($next->value() eq "::") { |  | 
| 2113         $self->assertTokenValue($self->getToken(), "::"); |  | 
| 2114         my $token = $self->getToken(); |  | 
| 2115         $self->assertTokenType($token, IdentifierToken); |  | 
| 2116         return "::" . $token->value() . $self->parseScopedNameParts(); |  | 
| 2117     } |  | 
| 2118     $self->assertUnexpectedToken($next->value()); |  | 
| 2119 } |  | 
| 2120 |  | 
| 2121 sub parseRelativeScopedName |  | 
| 2122 { |  | 
| 2123     my $self = shift; |  | 
| 2124     my $next = $self->nextToken(); |  | 
| 2125     if ($next->type() == IdentifierToken) { |  | 
| 2126         my $token = $self->getToken(); |  | 
| 2127         return $token->value() . $self->parseScopedNameParts(); |  | 
| 2128     } |  | 
| 2129     $self->assertUnexpectedToken($next->value()); |  | 
| 2130 } |  | 
| 2131 |  | 
| 2132 sub parseScopedNameParts |  | 
| 2133 { |  | 
| 2134     my $self = shift; |  | 
| 2135     my @names = (); |  | 
| 2136 |  | 
| 2137     while (1) { |  | 
| 2138         my $next = $self->nextToken(); |  | 
| 2139         if ($next->value() eq "::") { |  | 
| 2140             $self->assertTokenValue($self->getToken(), "::"); |  | 
| 2141             push(@names, "::"); |  | 
| 2142             my $token = $self->getToken(); |  | 
| 2143             $self->assertTokenType($token, IdentifierToken); |  | 
| 2144             push(@names, $token->value()); |  | 
| 2145         } else { |  | 
| 2146             last; |  | 
| 2147         } |  | 
| 2148     } |  | 
| 2149     return join("", @names); |  | 
| 2150 } |  | 
| 2151 |  | 
| 2152 sub parseScopedNameList |  | 
| 2153 { |  | 
| 2154     my $self = shift; |  | 
| 2155     my $next = $self->nextToken(); |  | 
| 2156     if ($next->type() == IdentifierToken || $next->value() eq "::") { |  | 
| 2157         my @names = (); |  | 
| 2158         push(@names, $self->parseScopedName()); |  | 
| 2159         push(@names, @{$self->parseScopedNames()}); |  | 
| 2160         return \@names; |  | 
| 2161     } |  | 
| 2162     $self->assertUnexpectedToken($next->value(), __LINE__); |  | 
| 2163 } |  | 
| 2164 |  | 
| 2165 sub parseScopedNames |  | 
| 2166 { |  | 
| 2167     my $self = shift; |  | 
| 2168     my @names = (); |  | 
| 2169 |  | 
| 2170     while (1) { |  | 
| 2171         my $next = $self->nextToken(); |  | 
| 2172         if ($next->value() eq ",") { |  | 
| 2173             $self->assertTokenValue($self->getToken(), ","); |  | 
| 2174             push(@names, $self->parseScopedName()); |  | 
| 2175         } else { |  | 
| 2176             last; |  | 
| 2177         } |  | 
| 2178     } |  | 
| 2179     return \@names; |  | 
| 2180 } |  | 
| 2181 |  | 
| 2182 sub applyMemberList |  | 
| 2183 { |  | 
| 2184     my $interface = shift; |  | 
| 2185     my $members = shift; |  | 
| 2186 |  | 
| 2187     for my $item (@{$members}) { |  | 
| 2188         if (ref($item) eq "domAttribute") { |  | 
| 2189             push(@{$interface->attributes}, $item); |  | 
| 2190             next; |  | 
| 2191         } |  | 
| 2192         if (ref($item) eq "domConstant") { |  | 
| 2193             push(@{$interface->constants}, $item); |  | 
| 2194             next; |  | 
| 2195         } |  | 
| 2196         if (ref($item) eq "domFunction") { |  | 
| 2197             push(@{$interface->functions}, $item); |  | 
| 2198             next; |  | 
| 2199         } |  | 
| 2200     } |  | 
| 2201 } |  | 
| 2202 |  | 
| 2203 sub applyExtendedAttributeList |  | 
| 2204 { |  | 
| 2205     my $interface = shift; |  | 
| 2206     my $extendedAttributeList = shift; |  | 
| 2207 |  | 
| 2208     if (defined $extendedAttributeList->{"Constructors"}) { |  | 
| 2209         my @constructorParams = @{$extendedAttributeList->{"Constructors"}}; |  | 
| 2210         my $index = (@constructorParams == 1) ? 0 : 1; |  | 
| 2211         foreach my $param (@constructorParams) { |  | 
| 2212             my $constructor = domFunction->new(); |  | 
| 2213             $constructor->name("Constructor"); |  | 
| 2214             $constructor->extendedAttributes($extendedAttributeList); |  | 
| 2215             $constructor->parameters($param); |  | 
| 2216             $constructor->overloadedIndex($index++); |  | 
| 2217             push(@{$interface->constructors}, $constructor); |  | 
| 2218         } |  | 
| 2219         delete $extendedAttributeList->{"Constructors"}; |  | 
| 2220         $extendedAttributeList->{"Constructor"} = "VALUE_IS_MISSING"; |  | 
| 2221     } elsif (defined $extendedAttributeList->{"NamedConstructor"}) { |  | 
| 2222         my $newDataNode = domFunction->new(); |  | 
| 2223         $newDataNode->name("NamedConstructor"); |  | 
| 2224         $newDataNode->extendedAttributes($extendedAttributeList); |  | 
| 2225         my %attributes = %{$extendedAttributeList->{"NamedConstructor"}}; |  | 
| 2226         my @attributeKeys = keys (%attributes); |  | 
| 2227         my $constructorName = $attributeKeys[0]; |  | 
| 2228         push(@{$newDataNode->parameters}, @{$attributes{$constructorName}}); |  | 
| 2229         $extendedAttributeList->{"NamedConstructor"} = $constructorName; |  | 
| 2230         push(@{$interface->constructors}, $newDataNode); |  | 
| 2231     } |  | 
| 2232     if (defined $extendedAttributeList->{"CustomConstructors"}) { |  | 
| 2233         my @customConstructorParams = @{$extendedAttributeList->{"CustomConstruc
      tors"}}; |  | 
| 2234         my $index = (@customConstructorParams == 1) ? 0 : 1; |  | 
| 2235         foreach my $param (@customConstructorParams) { |  | 
| 2236             my $customConstructor = domFunction->new(); |  | 
| 2237             $customConstructor->name("CustomConstructor"); |  | 
| 2238             $customConstructor->extendedAttributes($extendedAttributeList); |  | 
| 2239             $customConstructor->parameters($param); |  | 
| 2240             $customConstructor->overloadedIndex($index++); |  | 
| 2241             push(@{$interface->customConstructors}, $customConstructor); |  | 
| 2242         } |  | 
| 2243         delete $extendedAttributeList->{"CustomConstructors"}; |  | 
| 2244         $extendedAttributeList->{"CustomConstructor"} = "VALUE_IS_MISSING"; |  | 
| 2245     } |  | 
| 2246     $interface->extendedAttributes($extendedAttributeList); |  | 
| 2247 } |  | 
| 2248 |  | 
| 2249 1; |  | 
| OLD | NEW | 
|---|