Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: Source/bindings/scripts/deprecated_idl_parser.pm

Issue 24156003: Revert IDL compiler build flow to Perl, rename 'deprecated' (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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;
OLDNEW
« no previous file with comments | « Source/bindings/scripts/deprecated_generate_bindings.pl ('k') | Source/bindings/scripts/deprecated_idl_serializer.pm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698