nsgenbind
Loading...
Searching...
No Matches
webidl-ast.c
Go to the documentation of this file.
1/* AST generator for the WEB IDL parser
2 *
3 * This file is part of nsgenbind.
4 * Licensed under the MIT License,
5 * http://www.opensource.org/licenses/mit-license.php
6 * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
7 */
8
9#include <stdbool.h>
10#include <stdlib.h>
11#include <stdio.h>
12#include <string.h>
13#include <errno.h>
14#include <stdarg.h>
15
16#include "utils.h"
17#include "webidl-ast.h"
18#include "options.h"
19
23static FILE *webidl_parsetracef;
24
25extern int webidl_debug;
26extern int webidl__flex_debug;
27extern void webidl_restart(FILE*);
28extern int webidl_parse(struct webidl_node **webidl_ast);
29
31 enum webidl_node_type type; /* the type of the node */
32 struct webidl_node *l; /* link to the next sibling node */
33 union {
34 void *value;
35 struct webidl_node *node; /* node has a list of nodes */
36 char *text; /* node data is text */
37 float *flt;
38 int number; /* node data is an integer */
39 } r;
40};
41
42/* insert node(s) at beginning of a list */
43struct webidl_node *
44webidl_node_prepend(struct webidl_node *list, struct webidl_node *inst)
45{
46 struct webidl_node *end = inst;
47
48 if (inst == NULL) {
49 return list; /* no node to prepend - return existing list */
50 }
51
52 /* find end of inserted node list */
53 while (end->l != NULL) {
54 end = end->l;
55 }
56
57 end->l = list;
58
59 return inst;
60}
61
62/* append node at end of a list */
63struct webidl_node *
65{
66 struct webidl_node *cur = list;
67
68 if (cur == NULL) {
69 return node; /* no existing list so just return node */
70 }
71
72 while (cur->l != NULL) {
73 cur = cur->l;
74 }
75 cur->l = node;
76
77 return list;
78}
79
80/* prepend list to a nodes list
81 *
82 * inserts a list into the beginning of a nodes r list
83 *
84 * CAUTION: if the \a node element is not a node type the node will not be added
85 */
86struct webidl_node *
88{
89 if (node == NULL) {
90 return list;
91 }
92
93 /* this does not use webidl_node_getnode() as it cannot
94 * determine between an empty node and a node which is not a
95 * list type
96 */
97 switch (node->type) {
109 break;
110
111 default:
112 /* not a node type node */
113 return list;
114 }
115
117
118 return node;
119}
120
121
122struct webidl_node *
123/* exported interface documented in webidl-ast.h */
125 struct webidl_node *l,
126 void *r)
127{
128 struct webidl_node *nn;
129 nn = calloc(1, sizeof(struct webidl_node));
130 nn->type = type;
131 nn->l = l;
132 nn->r.value = r;
133 return nn;
134}
135
136/* exported interface documented in webidl-ast.h */
137struct webidl_node *
139 struct webidl_node *l,
140 int number)
141{
142 struct webidl_node *nn;
143 nn = calloc(1, sizeof(struct webidl_node));
144 nn->type = type;
145 nn->l = l;
146 nn->r.number = number;
147 return nn;
148}
149
150
151int
155 void *ctx)
156{
157 int ret;
158
159 if (node == NULL) {
160 return -1;
161 }
162 if (node->l != NULL) {
163 ret = webidl_node_for_each_type(node->l, type, cb, ctx);
164 if (ret != 0) {
165 return ret;
166 }
167 }
168 if (node->type == type) {
169 return cb(node, ctx);
170 }
171
172 return 0;
173}
174
175/* exported interface defined in webidl-ast.h */
176int webidl_cmp_node_type(struct webidl_node *node, void *ctx)
177{
178 if (node->type == (enum webidl_node_type)ctx)
179 return 1;
180 return 0;
181}
182
183static int webidl_enumerate_node(struct webidl_node *node, void *ctx)
184{
185 UNUSED(node);
186 (*((int *)ctx))++;
187 return 0;
188}
189
190/* exported interface defined in nsgenbind-ast.h */
191int
194{
195 int count = 0;
197 type,
198 webidl_enumerate_node,
199 &count);
200 return count;
201}
202
203/* exported interface defined in webidl-ast.h */
204struct webidl_node *
206 struct webidl_node *prev,
208 void *ctx)
209{
210 struct webidl_node *ret;
211
212 if ((node == NULL) || (node == prev)) {
213 return NULL;
214 }
215
216 if (node->l != prev) {
217 ret = webidl_node_find(node->l, prev, cb, ctx);
218 if (ret != NULL) {
219 return ret;
220 }
221 }
222
223 if (cb(node, ctx) != 0) {
224 return node;
225 }
226
227 return NULL;
228}
229
230
231/* exported interface defined in webidl-ast.h */
232struct webidl_node *
234 struct webidl_node *prev,
236{
237 return webidl_node_find(node,
238 prev,
240 (void *)type);
241}
242
243
244/* exported interface defined in webidl-ast.h */
245struct webidl_node *
248 const char *ident)
249{
250 struct webidl_node *node;
251 struct webidl_node *ident_node;
252
253 node = webidl_node_find_type(root_node, NULL, type);
254
255 while (node != NULL) {
256
258 NULL,
260 if (ident_node != NULL) {
261 if (strcmp(ident_node->r.text, ident) == 0)
262 break;
263 }
264
265 node = webidl_node_find_type(root_node, node, type);
266
267 }
268 return node;
269}
270
271
272/* exported interface defined in webidl-ast.h */
274{
275 if (node != NULL) {
276
277 switch(node->type) {
282 return node->r.text;
283
284 default:
285 break;
286 }
287 }
288 return NULL;
289}
290
291/* exported interface defined in webidl-ast.h */
292int *
294{
295 if (node != NULL) {
296 switch(node->type) {
302 return &node->r.number;
303
304 default:
305 break;
306 }
307 }
308 return NULL;
309}
310
311/* exported interface defined in webidl-ast.h */
312float *
314{
315 if (node != NULL) {
316 switch(node->type) {
318 return node->r.flt;
319
320 default:
321 break;
322 }
323 }
324 return NULL;
325}
326
327/* exported interface defined in webidl-ast.h */
329{
330 return node->type;
331}
332
333
334/* exported interface defined in webidl-ast.h */
336{
337 if (node != NULL) {
338 switch (node->type) {
350 return node->r.node;
351 default:
352 break;
353 }
354 }
355 return NULL;
356
357}
358
359/* exported interface defined in webidl-ast.h */
360static const char *webidl_node_type_to_str(enum webidl_node_type type)
361{
362 switch(type) {
364 return "root";
365
367 return "Ident";
368
370 return "Inherit";
371
373 return "Implements";
374
376 return "Interface";
377
379 return "Dictionary";
380
382 return "List";
383
385 return "Attribute";
386
388 return "Operation";
389
391 return "Optional";
392
394 return "Argument";
395
397 return "Ellipsis";
398
400 return "Type";
401
403 return "Base";
404
406 return "Nullable";
407
409 return "Array";
410
412 return "Modifier";
413
415 return "Const";
416
418 return "Literal (null)";
419
421 return "Literal (int)";
422
424 return "Literal (bool)";
425
427 return "Literal (float)";
428
430 return "Literal (string)";
431
433 return "Extended Attribute";
434
436 return "Special";
437
438 default:
439 return "Unknown";
440 }
441
442}
443
447static int
448webidl_ast_dump_int(FILE *dumpf, struct webidl_node *node)
449{
450 switch(node->type) {
452 switch (node->r.number) {
454 fprintf(dumpf, ": none\n");
455 break;
456
458 fprintf(dumpf, ": unsigned\n");
459 break;
460
462 fprintf(dumpf, ": unrestricted\n");
463 break;
464
466 fprintf(dumpf, ": readonly\n");
467 break;
468
470 fprintf(dumpf, ": static\n");
471 break;
472
474 fprintf(dumpf, ": inherit\n");
475 break;
476
477 default:
478 fprintf(dumpf, ": %d\n", node->r.number);
479 break;
480 }
481 break;
482
484 fprintf(dumpf, ": %s\n",
486 node->r.number));
487 break;
488
490 switch (node->r.number) {
492 fprintf(dumpf, ": getter\n");
493 break;
494
496 fprintf(dumpf, ": setter\n");
497 break;
498
500 fprintf(dumpf, ": creator\n");
501 break;
502
504 fprintf(dumpf, ": deleter\n");
505 break;
506
508 fprintf(dumpf, ": legacy caller\n");
509 break;
510
511 default:
512 fprintf(dumpf, ": %d\n", node->r.number);
513 break;
514 }
515 break;
516
518 if (node->r.number == 0) {
519 fprintf(dumpf, ": false\n");
520 } else {
521 fprintf(dumpf, ": true\n");
522 }
523 break;
524
526 fprintf(dumpf, ": %d\n", node->r.number);
527 break;
528
529 default:
530 /* no value */
531 fprintf(dumpf, "\n");
532 break;
533 }
534
535 return 0;
536}
537
541static int webidl_ast_dump(FILE *dumpf, struct webidl_node *node, int indent)
542{
543 const char *SPACES=" ";
544 char *txt;
545 while (node != NULL) {
546 fprintf(dumpf, "%.*s%s", indent, SPACES,
547 webidl_node_type_to_str(node->type));
548
550 if (txt == NULL) {
551 struct webidl_node *next;
552
554
555 if (next != NULL) {
556 fprintf(dumpf, "\n");
557 webidl_ast_dump(dumpf, next, indent + 2);
558 } else {
559 /* not txt or node try an int */
560 webidl_ast_dump_int(dumpf, node);
561 }
562 } else {
563 fprintf(dumpf, ": \"%s\"\n", txt);
564 }
565 node = node->l;
566 }
567 return 0;
568}
569
570/* exported interface documented in webidl-ast.h */
572{
573 FILE *dumpf;
574
575 /* only dump AST to file if required */
576 if (!options->debug) {
577 return 0;
578 }
579
580 dumpf = genb_fopen("webidl-ast", "w");
581 if (dumpf == NULL) {
582 return 2;
583 }
584
585 webidl_ast_dump(dumpf, node, 0);
586
587 fclose(dumpf);
588
589 return 0;
590}
591
592/* exported interface defined in webidl-ast.h */
593static FILE *idlopen(const char *filename)
594{
595 FILE *idlfile;
596 char *fullname;
597 int fulllen;
598
599 if (options->idlpath == NULL) {
600 if (options->verbose) {
601 printf("Opening IDL file %s\n", filename);
602 }
603 return fopen(filename, "r");
604 }
605
606 fulllen = strlen(options->idlpath) + strlen(filename) + 2;
607 fullname = malloc(fulllen);
608 snprintf(fullname, fulllen, "%s/%s", options->idlpath, filename);
609 if (options->verbose) {
610 printf("Opening IDL file %s\n", fullname);
611 }
612 idlfile = fopen(fullname, "r");
613 free(fullname);
614
615 return idlfile;
616}
617
618/* exported interface defined in webidl-ast.h */
619int webidl_parsefile(char *filename, struct webidl_node **webidl_ast)
620{
621 FILE *idlfile;
622 int ret;
623
624 idlfile = idlopen(filename);
625 if (!idlfile) {
626 fprintf(stderr, "Error opening %s: %s\n",
627 filename,
628 strerror(errno));
629 return 2;
630 }
631
632 /* if debugging enabled enable parser tracing and send to file */
633 if (options->debug) {
634 char *tracename;
635 int tracenamelen;
636 webidl_debug = 1;
638
639 tracenamelen = SLEN("webidl--trace") + strlen(filename) + 1;
640 tracename = malloc(tracenamelen);
641 snprintf(tracename, tracenamelen,"webidl-%s-trace", filename);
642 webidl_parsetracef = genb_fopen(tracename, "w");
643 free(tracename);
644 } else {
645 webidl_parsetracef = NULL;
646 }
647
648 /* set flex to read from file */
649 webidl_restart(idlfile);
650
651 /* parse the file */
652 ret = webidl_parse(webidl_ast);
653
654 /* close tracefile if open */
655 if (webidl_parsetracef != NULL) {
656 fclose(webidl_parsetracef);
657 }
658 return ret;
659}
660
661/* exported interface defined in webidl-ast.h */
662int webidl_fprintf(FILE *stream, const char *format, ...)
663{
664 va_list ap;
665 int ret;
666
667 va_start(ap, format);
668
669 if (webidl_parsetracef == NULL) {
670 ret = vfprintf(stream, format, ap);
671 } else {
672 ret = vfprintf(webidl_parsetracef, format, ap);
673 }
674 va_end(ap);
675
676 return ret;
677}
678
679/* unlink a child node from a parent */
680static int
681webidl_unlink(struct webidl_node *parent, struct webidl_node *node)
682{
683 struct webidl_node *child;
684
685 child = webidl_node_getnode(parent);
686 if (child == NULL) {
687 /* parent does not have children to remove node from */
688 return -1;
689 }
690
691 if (child == node) {
692 /* parent is pointing at the node we want to remove */
693 parent->r.node = node->l; /* point parent at next sibing */
694 node->l = NULL;
695 return 0;
696 }
697
698 while (child->l != NULL) {
699 if (child->l == node) {
700 /* found node, unlink from list */
701 child->l = node->l;
702 node->l = NULL;
703 return 0;
704 }
705 child = child->l;
706 }
707 return -1; /* failed to remove node */
708}
709
710static int implements_copy_nodes(struct webidl_node *src_node,
711 struct webidl_node *dst_node)
712{
713 struct webidl_node *src;
714 struct webidl_node *dst;
715
716 src = webidl_node_getnode(src_node);
717 dst = webidl_node_getnode(dst_node);
718
719 while (src != NULL) {
720 if (src->type == WEBIDL_NODE_TYPE_LIST) {
722 dst = webidl_node_new(src->type, dst, src->r.text);
723 }
724 src = src->l;
725 }
726
727 dst_node->r.node = dst;
728
729 return 0;
730}
731
732static int
733intercalate_implements(struct webidl_node *interface_node, void *ctx)
734{
735 struct webidl_node *implements_node;
736 struct webidl_node *implements_interface_node;
737 struct webidl_node *webidl_ast = ctx;
738
739 implements_node = webidl_node_find_type(
740 webidl_node_getnode(interface_node),
741 NULL,
743 while (implements_node != NULL) {
744
745 implements_interface_node = webidl_node_find_type_ident(
746 webidl_ast,
748 webidl_node_gettext(implements_node));
749
750 /* recurse, ensuring all subordinate interfaces have
751 * their implements intercalated first
752 */
753 intercalate_implements(implements_interface_node, webidl_ast);
754
755 implements_copy_nodes(implements_interface_node, interface_node);
756
757 /* once we have copied the implemntation remove entry */
758 webidl_unlink(interface_node, implements_node);
759
760 implements_node = webidl_node_find_type(
761 webidl_node_getnode(interface_node),
762 implements_node,
764 }
765 return 0;
766}
767
768/* exported interface defined in webidl-ast.h */
770{
771 int res = 0;
772 if (webidl_ast != NULL) {
773 /* for each interface:
774 * for each implements entry:
775 * find interface from implemets
776 * recusrse into that interface
777 * copy the interface into this one
778 */
779 res = webidl_node_for_each_type(webidl_ast,
781 intercalate_implements,
782 webidl_ast);
783 }
784 return res;
785}
786
787/* exported interface defined in webidl-ast.h */
789{
790 switch (t) {
791 case WEBIDL_TYPE_ANY:
792 return "any";
793
794 case WEBIDL_TYPE_USER:
795 return "user";
796
797 case WEBIDL_TYPE_BOOL:
798 return "boolean";
799
800 case WEBIDL_TYPE_BYTE:
801 return "byte";
802
803 case WEBIDL_TYPE_OCTET:
804 return "octet";
805
806 case WEBIDL_TYPE_FLOAT:
807 return "float";
808
809 case WEBIDL_TYPE_DOUBLE:
810 return "double";
811
812 case WEBIDL_TYPE_SHORT:
814 return "unsigned short";
815 } else {
816 return "short";
817 }
818
819 case WEBIDL_TYPE_LONG:
821 return "unsigned long";
822 } else {
823 return "long";
824 }
825
827 return "long long";
828
829 case WEBIDL_TYPE_STRING:
830 return "string";
831
833 return "sequence";
834
835 case WEBIDL_TYPE_OBJECT:
836 return "object";
837
838 case WEBIDL_TYPE_DATE:
839 return "date";
840
841 case WEBIDL_TYPE_VOID:
842 return "void";
843 }
844 return "Unknown";
845}
@ end
Definition html.idl:1035
DOMString filename
Definition html.idl:1561
void * malloc(YYSIZE_T)
void free(void *)
bool debug
Definition options.h:19
char * idlpath
Definition options.h:16
bool verbose
Definition options.h:18
char * text
Definition webidl-ast.c:36
struct webidl_node * node
Definition webidl-ast.c:35
union webidl_node::@4 r
void * value
Definition webidl-ast.c:34
struct webidl_node * l
Definition webidl-ast.c:32
enum webidl_node_type type
Definition webidl-ast.c:31
float * flt
Definition webidl-ast.c:37
FILE * genb_fopen(const char *fname, const char *mode)
Definition utils.c:46
#define UNUSED(x)
Definition utils.h:50
#define SLEN(s)
Definition utils.h:46
int webidl_parse(struct webidl_node **webidl_ast)
struct webidl_node * webidl_node_getnode(struct webidl_node *node)
Definition webidl-ast.c:335
int webidl_debug
struct webidl_node * webidl_node_new(enum webidl_node_type type, struct webidl_node *l, void *r)
Definition webidl-ast.c:124
int webidl_node_enumerate_type(struct webidl_node *node, enum webidl_node_type type)
Definition webidl-ast.c:192
struct webidl_node * webidl_node_find_type_ident(struct webidl_node *root_node, enum webidl_node_type type, const char *ident)
Definition webidl-ast.c:246
int webidl_cmp_node_type(struct webidl_node *node, void *ctx)
Definition webidl-ast.c:176
int webidl_intercalate_implements(struct webidl_node *webidl_ast)
Definition webidl-ast.c:769
struct webidl_node * webidl_node_append(struct webidl_node *list, struct webidl_node *node)
Definition webidl-ast.c:64
struct webidl_node * webidl_node_prepend(struct webidl_node *list, struct webidl_node *inst)
Definition webidl-ast.c:44
struct webidl_node * webidl_node_add(struct webidl_node *node, struct webidl_node *list)
Definition webidl-ast.c:87
struct webidl_node * webidl_new_number_node(enum webidl_node_type type, struct webidl_node *l, int number)
Definition webidl-ast.c:138
char * webidl_node_gettext(struct webidl_node *node)
Definition webidl-ast.c:273
struct webidl_node * webidl_node_find(struct webidl_node *node, struct webidl_node *prev, webidl_callback_t *cb, void *ctx)
Definition webidl-ast.c:205
int webidl_dump_ast(struct webidl_node *node)
Definition webidl-ast.c:571
int webidl_node_for_each_type(struct webidl_node *node, enum webidl_node_type type, webidl_callback_t *cb, void *ctx)
Definition webidl-ast.c:152
int webidl__flex_debug
const char * webidl_type_to_str(enum webidl_type_modifier m, enum webidl_type t)
Definition webidl-ast.c:788
int * webidl_node_getint(struct webidl_node *node)
Definition webidl-ast.c:293
int webidl_parsefile(char *filename, struct webidl_node **webidl_ast)
Definition webidl-ast.c:619
float * webidl_node_getfloat(struct webidl_node *node)
Definition webidl-ast.c:313
enum webidl_node_type webidl_node_gettype(struct webidl_node *node)
Definition webidl-ast.c:328
int webidl_fprintf(FILE *stream, const char *format,...)
Definition webidl-ast.c:662
struct webidl_node * webidl_node_find_type(struct webidl_node *node, struct webidl_node *prev, enum webidl_node_type type)
Definition webidl-ast.c:233
void webidl_restart(FILE *)
int() webidl_callback_t(struct webidl_node *node, void *ctx)
Definition webidl-ast.h:91
webidl_type
Definition webidl-ast.h:51
@ WEBIDL_TYPE_DOUBLE
Definition webidl-ast.h:58
@ WEBIDL_TYPE_SHORT
Definition webidl-ast.h:59
@ WEBIDL_TYPE_STRING
Definition webidl-ast.h:62
@ WEBIDL_TYPE_ANY
Definition webidl-ast.h:52
@ WEBIDL_TYPE_BOOL
Definition webidl-ast.h:54
@ WEBIDL_TYPE_OBJECT
Definition webidl-ast.h:64
@ WEBIDL_TYPE_DATE
Definition webidl-ast.h:65
@ WEBIDL_TYPE_OCTET
Definition webidl-ast.h:56
@ WEBIDL_TYPE_SEQUENCE
Definition webidl-ast.h:63
@ WEBIDL_TYPE_LONGLONG
Definition webidl-ast.h:61
@ WEBIDL_TYPE_USER
Definition webidl-ast.h:53
@ WEBIDL_TYPE_VOID
Definition webidl-ast.h:66
@ WEBIDL_TYPE_BYTE
Definition webidl-ast.h:55
@ WEBIDL_TYPE_LONG
Definition webidl-ast.h:60
@ WEBIDL_TYPE_FLOAT
Definition webidl-ast.h:57
@ WEBIDL_TYPE_SPECIAL_CREATOR
Definition webidl-ast.h:83
@ WEBIDL_TYPE_SPECIAL_SETTER
Definition webidl-ast.h:82
@ WEBIDL_TYPE_SPECIAL_DELETER
Definition webidl-ast.h:84
@ WEBIDL_TYPE_SPECIAL_GETTER
Definition webidl-ast.h:81
@ WEBIDL_TYPE_SPECIAL_LEGACYCALLER
Definition webidl-ast.h:85
webidl_node_type
Definition webidl-ast.h:12
@ WEBIDL_NODE_TYPE_TYPE_ARRAY
Definition webidl-ast.h:39
@ WEBIDL_NODE_TYPE_LITERAL_STRING
Definition webidl-ast.h:45
@ WEBIDL_NODE_TYPE_IDENT
Definition webidl-ast.h:15
@ WEBIDL_NODE_TYPE_ROOT
Definition webidl-ast.h:14
@ WEBIDL_NODE_TYPE_CONST
Definition webidl-ast.h:27
@ WEBIDL_NODE_TYPE_DICTIONARY
Definition webidl-ast.h:29
@ WEBIDL_NODE_TYPE_LIST
Definition webidl-ast.h:19
@ WEBIDL_NODE_TYPE_TYPE_BASE
Definition webidl-ast.h:37
@ WEBIDL_NODE_TYPE_LITERAL_NULL
Definition webidl-ast.h:41
@ WEBIDL_NODE_TYPE_OPERATION
Definition webidl-ast.h:26
@ WEBIDL_NODE_TYPE_INTERFACE
Definition webidl-ast.h:22
@ WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE
Definition webidl-ast.h:47
@ WEBIDL_NODE_TYPE_TYPE
Definition webidl-ast.h:36
@ WEBIDL_NODE_TYPE_SPECIAL
Definition webidl-ast.h:32
@ WEBIDL_NODE_TYPE_TYPE_NULLABLE
Definition webidl-ast.h:38
@ WEBIDL_NODE_TYPE_INHERITANCE
Definition webidl-ast.h:31
@ WEBIDL_NODE_TYPE_ATTRIBUTE
Definition webidl-ast.h:25
@ WEBIDL_NODE_TYPE_MODIFIER
Definition webidl-ast.h:17
@ WEBIDL_NODE_TYPE_OPTIONAL
Definition webidl-ast.h:34
@ WEBIDL_NODE_TYPE_LITERAL_BOOL
Definition webidl-ast.h:43
@ WEBIDL_NODE_TYPE_ARGUMENT
Definition webidl-ast.h:33
@ WEBIDL_NODE_TYPE_ELLIPSIS
Definition webidl-ast.h:35
@ WEBIDL_NODE_TYPE_LITERAL_INT
Definition webidl-ast.h:42
@ WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS
Definition webidl-ast.h:23
@ WEBIDL_NODE_TYPE_LITERAL_FLOAT
Definition webidl-ast.h:44
webidl_type_modifier
Definition webidl-ast.h:70
@ WEBIDL_TYPE_MODIFIER_INHERIT
Definition webidl-ast.h:76
@ WEBIDL_TYPE_MODIFIER_UNSIGNED
Definition webidl-ast.h:72
@ WEBIDL_TYPE_MODIFIER_NONE
Definition webidl-ast.h:71
@ WEBIDL_TYPE_MODIFIER_STATIC
Definition webidl-ast.h:75
@ WEBIDL_TYPE_MODIFIER_UNRESTRICTED
Definition webidl-ast.h:73
@ WEBIDL_TYPE_MODIFIER_READONLY
Definition webidl-ast.h:74