OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
3 # for details. All rights reserved. Use of this source code is governed by a | 3 # for details. All rights reserved. Use of this source code is governed by a |
4 # BSD-style license that can be found in the LICENSE file. | 4 # BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 import os | 6 import os |
7 import sys | 7 import sys |
8 | 8 |
9 import idl_definitions | |
10 from idl_types import IdlType, IdlUnionType | |
11 | |
12 from compute_interfaces_info_overall import interfaces_info | |
13 | |
14 | |
15 new_asts = {} | |
16 | |
17 | 9 |
18 _operation_suffix_map = { | 10 _operation_suffix_map = { |
19 '__getter__': "Getter", | 11 '__getter__': "Getter", |
20 '__setter__': "Setter", | 12 '__setter__': "Setter", |
21 '__delete__': "Deleter", | 13 '__delete__': "Deleter", |
22 } | 14 } |
23 | 15 |
24 class IDLNode(object): | 16 class IDLNode(object): |
25 """Base class for all IDL elements. | 17 """Base class for all IDL elements. |
26 IDLNode may contain various child nodes, and have properties. Examples | 18 IDLNode may contain various child nodes, and have properties. Examples |
27 of IDLNode are interfaces, interface members, function arguments, | 19 of IDLNode are interfaces, interface members, function arguments, |
28 etc. | 20 etc. |
29 """ | 21 """ |
30 | 22 |
31 def __init__(self, ast): | 23 def __init__(self, ast): |
32 """Initializes an IDLNode from a PegParser AST output.""" | 24 """Initializes an IDLNode from a PegParser AST output.""" |
33 self.id = self._find_first(ast, 'Id') if ast is not None else None | 25 self.id = self._find_first(ast, 'Id') if ast is not None else None |
34 | 26 |
35 | |
36 def __repr__(self): | 27 def __repr__(self): |
37 """Generates string of the form <class id extra extra ... 0x12345678>.""" | 28 """Generates string of the form <class id extra extra ... 0x12345678>.""" |
38 extras = self._extra_repr() | 29 extras = self._extra_repr() |
39 if isinstance(extras, list): | 30 if isinstance(extras, list): |
40 extras = ' '.join([str(e) for e in extras]) | 31 extras = ' '.join([str(e) for e in extras]) |
41 try: | 32 try: |
42 if self.id: | 33 if self.id: |
43 return '<%s %s 0x%x>' % ( | 34 return '<%s %s 0x%x>' % ( |
44 type(self).__name__, | 35 type(self).__name__, |
45 ('%s %s' % (self.id, extras)).strip(), | 36 ('%s %s' % (self.id, extras)).strip(), |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 label -- the label to look for. | 121 label -- the label to look for. |
131 res -- results are put into this list. | 122 res -- results are put into this list. |
132 max_results -- maximum number of results. | 123 max_results -- maximum number of results. |
133 """ | 124 """ |
134 res = [] | 125 res = [] |
135 if max_results <= 0: | 126 if max_results <= 0: |
136 return res | 127 return res |
137 | 128 |
138 if isinstance(ast, list): | 129 if isinstance(ast, list): |
139 for childAst in ast: | 130 for childAst in ast: |
140 if childAst and \ | 131 sub_res = self._find_all(childAst, label, |
141 not(isinstance(childAst, dict)) and \ | 132 max_results - len(res)) |
142 not(isinstance(childAst, str)) and \ | 133 res.extend(sub_res) |
143 not(isinstance(childAst, tuple)) and \ | |
144 childAst.__module__ == "idl_definitions": | |
145 field_name = self._convert_label_to_field(label) | |
146 if hasattr(childAst, field_name): | |
147 field_value = getattr(childAst, field_name) | |
148 # It's an IdlType we need the string name of the type. | |
149 if field_name == 'idl_type': | |
150 field_value = getattr(field_value, 'base_type') | |
151 res.append(field_value) | |
152 else: | |
153 sub_res = self._find_all(childAst, label, | |
154 max_results - len(res)) | |
155 res.extend(sub_res) | |
156 elif isinstance(ast, tuple): | 134 elif isinstance(ast, tuple): |
157 (nodeLabel, value) = ast | 135 (nodeLabel, value) = ast |
158 if nodeLabel == label: | 136 if nodeLabel == label: |
159 res.append(value) | 137 res.append(value) |
160 # TODO(terry): Seems bogus to check for so many things probably better to ju
st | |
161 # pass in blink_compile and drive it off from that... | |
162 elif (ast and not(isinstance(ast, dict)) and | |
163 not(isinstance(ast, str)) and ast.__module__ == "idl_definitions"): | |
164 field_name = self._convert_label_to_field(label) | |
165 if hasattr(ast, field_name): | |
166 field_value = getattr(ast, field_name) | |
167 if field_value: | |
168 if label == 'Interface' or label == 'Enum': | |
169 for key in field_value: | |
170 value = field_value[key] | |
171 res.append(value) | |
172 elif isinstance(field_value, list): | |
173 for item in field_value: | |
174 res.append(item) | |
175 elif label == 'ParentInterface' or label == 'InterfaceType': | |
176 # Fetch the AST for the parent interface. | |
177 parent_idlnode = new_asts[field_value] | |
178 res.append(parent_idlnode.interfaces[field_value]) | |
179 else: | |
180 res.append(field_value) | |
181 | |
182 return res | 138 return res |
183 | 139 |
184 def _convert_from_blink(self, object, label): | |
185 field_name = self._convert_label_to_field(label) | |
186 if hasattr(object, field_name): | |
187 field_value = getattr(object, field_name) | |
188 if field_value: | |
189 if label == 'Interface' or label == 'Enum': | |
190 for key in field_value: | |
191 value = field_value[key] | |
192 res.append(value) | |
193 elif isinstance(field_value, list): | |
194 for item in field_value: | |
195 res.append(item) | |
196 elif label == 'ParentInterface' or label == 'InterfaceType': | |
197 # Fetch the AST for the parent interface. | |
198 parent_idlnode = new_asts[field_value] | |
199 res.append(parent_idlnode.interfaces[field_value]) | |
200 else: | |
201 res.append(field_value) | |
202 | |
203 def _find_first(self, ast, label): | 140 def _find_first(self, ast, label): |
204 """Convenience method for _find_all(..., max_results=1). | 141 """Convenience method for _find_all(..., max_results=1). |
205 Returns a single element instead of a list, or None if nothing | 142 Returns a single element instead of a list, or None if nothing |
206 is found.""" | 143 is found.""" |
207 res = self._find_all(ast, label, max_results=1) | 144 res = self._find_all(ast, label, max_results=1) |
208 if len(res): | 145 if len(res): |
209 return res[0] | 146 return res[0] |
210 return None | 147 return None |
211 | 148 |
212 def _has(self, ast, label): | 149 def _has(self, ast, label): |
213 """Returns true if an element with the given label is | 150 """Returns true if an element with the given label is |
214 in the AST by searching for it.""" | 151 in the AST by searching for it.""" |
215 return len(self._find_all(ast, label, max_results=1)) == 1 | 152 return len(self._find_all(ast, label, max_results=1)) == 1 |
216 | 153 |
217 # Mapping from original AST tuple names to new AST field names idl_definitions
.Idl*. | |
218 def _convert_label_to_field(self, label): | |
219 label_field = { | |
220 # Keys old AST names, Values Blink IdlInterface names. | |
221 'ParentInterface': 'parent', | |
222 'Id': 'name', | |
223 'Interface': 'interfaces', | |
224 'Callback': 'is_callback', | |
225 'Partial': 'is_partial', | |
226 'Operation': 'operations', | |
227 'Attribute': 'attributes', | |
228 'Const': 'constants', | |
229 'Type': 'idl_type', | |
230 'ExtAttrs': 'extended_attributes', | |
231 'Special': 'specials', | |
232 'ReturnType': 'idl_type', | |
233 'Argument': 'arguments', | |
234 'InterfaceType': 'name', | |
235 'ConstExpr': 'value', | |
236 'Static': 'is_static', | |
237 'ReadOnly': 'is_read_only', | |
238 'Optional': 'is_optional', | |
239 'Nullable': 'is_nullable', | |
240 'Enum': 'enumerations', | |
241 'Annotation': '', # TODO(terry): Ignore annotation used for databa
se cache. | |
242 'TypeDef': '', # typedef in an IDL are already resolved. | |
243 } | |
244 result = label_field.get(label) | |
245 if result != '' and not(result): | |
246 print 'FATAL ERROR: AST mapping name not found %s.' % label | |
247 return result if result else '' | |
248 | |
249 def _convert_all(self, ast, label, idlnode_ctor): | 154 def _convert_all(self, ast, label, idlnode_ctor): |
250 """Converts AST elements into IDLNode elements. | 155 """Converts AST elements into IDLNode elements. |
251 Uses _find_all to find elements with a given label and converts | 156 Uses _find_all to find elements with a given label and converts |
252 them into IDLNodes with a given constructor. | 157 them into IDLNodes with a given constructor. |
253 Returns: | 158 Returns: |
254 A list of the converted nodes. | 159 A list of the converted nodes. |
255 Args: | 160 Args: |
256 ast -- the ast element to start a search at. | 161 ast -- the ast element to start a search at. |
257 label -- the element label to look for. | 162 label -- the element label to look for. |
258 idlnode_ctor -- a constructor function of one of the IDLNode | 163 idlnode_ctor -- a constructor function of one of the IDLNode |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 return res | 250 return res |
346 | 251 |
347 def _all_subnodes(self): | 252 def _all_subnodes(self): |
348 # Usually an IDLDictNode does not contain further IDLNodes. | 253 # Usually an IDLDictNode does not contain further IDLNodes. |
349 return [] | 254 return [] |
350 | 255 |
351 | 256 |
352 class IDLFile(IDLNode): | 257 class IDLFile(IDLNode): |
353 """IDLFile is the top-level node in each IDL file. It may contain interfaces."
"" | 258 """IDLFile is the top-level node in each IDL file. It may contain interfaces."
"" |
354 | 259 |
355 DART_IDL = 'dart.idl' | |
356 | |
357 def __init__(self, ast, filename=None): | 260 def __init__(self, ast, filename=None): |
358 IDLNode.__init__(self, ast) | 261 IDLNode.__init__(self, ast) |
359 self.filename = filename | 262 self.filename = filename |
360 | |
361 filename_basename = os.path.basename(filename) | |
362 | |
363 self.interfaces = self._convert_all(ast, 'Interface', IDLInterface) | 263 self.interfaces = self._convert_all(ast, 'Interface', IDLInterface) |
364 | 264 modules = self._convert_all(ast, 'Module', IDLModule) |
365 is_blink = not(isinstance(ast, list)) and ast.__module__ == 'idl_definitions
' | 265 self.implementsStatements = self._convert_all(ast, 'ImplStmt', |
366 | 266 IDLImplementsStatement) |
367 if is_blink: | 267 self.typeDefs = self._convert_all(ast, 'TypeDef', IDLTypeDef) |
368 # implements is handled by the interface merging step (see the function | |
369 # merge_interface_dependencies). | |
370 for interface in self.interfaces: | |
371 blink_interface = ast.interfaces.get(interface.id) | |
372 if filename_basename == self.DART_IDL: | |
373 # TODO(terry): Does this seem right? | |
374 self.implementsStatements = [] | |
375 else: | |
376 interface_info = interfaces_info[interface.id] | |
377 | |
378 implements = interface_info['implements_interfaces'] | |
379 if not(blink_interface.is_partial) and len(implements) > 0: | |
380 implementor = new_asts[interface.id].interfaces.get(interface.id) | |
381 | |
382 self.implementsStatements = [] | |
383 | |
384 # TODO(terry): Need to handle more than one implements. | |
385 for implemented_name in implements: | |
386 implemented = new_asts[implemented_name].interfaces.get(implemente
d_name) | |
387 | |
388 implement_statement = IDLImplementsStatement(implemented) | |
389 | |
390 implement_statement.implementor = IDLType(implementor) | |
391 implement_statement.implemented = IDLType(implemented) | |
392 | |
393 self.implementsStatements.append(implement_statement) | |
394 else: | |
395 self.implementsStatements = [] | |
396 else: | |
397 self.implementsStatements = self._convert_all(ast, 'ImplStmt', | |
398 IDLImplementsStatement) | |
399 | |
400 # No reason to handle typedef they're already aliased in Blink's AST. | |
401 self.typeDefs = [] if is_blink else self._convert_all(ast, 'TypeDef', IDLTyp
eDef) | |
402 | |
403 self.enums = self._convert_all(ast, 'Enum', IDLEnum) | 268 self.enums = self._convert_all(ast, 'Enum', IDLEnum) |
| 269 for module in modules: |
| 270 self.interfaces.extend(module.interfaces) |
| 271 self.implementsStatements.extend(module.implementsStatements) |
| 272 self.typeDefs.extend(module.typeDefs) |
404 | 273 |
405 | 274 |
406 class IDLModule(IDLNode): | 275 class IDLModule(IDLNode): |
407 """IDLModule has an id, and may contain interfaces, type defs and | 276 """IDLModule has an id, and may contain interfaces, type defs and |
408 implements statements.""" | 277 implements statements.""" |
409 def __init__(self, ast): | 278 def __init__(self, ast): |
410 IDLNode.__init__(self, ast) | 279 IDLNode.__init__(self, ast) |
411 self._convert_ext_attrs(ast) | 280 self._convert_ext_attrs(ast) |
412 self._convert_annotations(ast) | 281 self._convert_annotations(ast) |
413 self.interfaces = self._convert_all(ast, 'Interface', IDLInterface) | 282 self.interfaces = self._convert_all(ast, 'Interface', IDLInterface) |
414 | 283 self.typeDefs = self._convert_all(ast, 'TypeDef', IDLTypeDef) |
415 is_blink = ast.__module__ == 'idl_definitions' | |
416 | |
417 # No reason to handle typedef they're already aliased in Blink's AST. | |
418 self.typeDefs = [] if is_blink else self._convert_all(ast, 'TypeDef', IDLTyp
eDef) | |
419 | |
420 self.enums = self._convert_all(ast, 'Enum', IDLNode) | 284 self.enums = self._convert_all(ast, 'Enum', IDLNode) |
421 | 285 self.implementsStatements = self._convert_all(ast, 'ImplStmt', |
422 if is_blink: | 286 IDLImplementsStatement) |
423 # implements is handled by the interface merging step (see the function | |
424 # merge_interface_dependencies). | |
425 for interface in self.interfaces: | |
426 interface_info = interfaces_info[interface.id] | |
427 # TODO(terry): Same handling for implementsStatements as in IDLFile? | |
428 self.implementsStatements = interface_info['implements_interfaces'] | |
429 else: | |
430 self.implementsStatements = self._convert_all(ast, 'ImplStmt', | |
431 IDLImplementsStatement) | |
432 | 287 |
433 | 288 |
434 class IDLExtAttrs(IDLDictNode): | 289 class IDLExtAttrs(IDLDictNode): |
435 """IDLExtAttrs is an IDLDictNode that stores IDL Extended Attributes. | 290 """IDLExtAttrs is an IDLDictNode that stores IDL Extended Attributes. |
436 Modules, interfaces, members and arguments can all own IDLExtAttrs.""" | 291 Modules, interfaces, members and arguments can all own IDLExtAttrs.""" |
437 def __init__(self, ast=None): | 292 def __init__(self, ast=None): |
438 IDLDictNode.__init__(self, None) | 293 IDLDictNode.__init__(self, None) |
439 if not ast: | 294 if not ast: |
440 return | 295 return |
441 if not(isinstance(ast, list)) and ast.__module__ == "idl_definitions": | 296 ext_attrs_ast = self._find_first(ast, 'ExtAttrs') |
442 # Pull out extended attributes from Blink AST. | 297 if not ext_attrs_ast: |
443 for name, value in ast.extended_attributes.items(): | 298 return |
444 # TODO(terry): Handle constructors... | 299 for ext_attr in self._find_all(ext_attrs_ast, 'ExtAttr'): |
445 if name == 'NamedConstructor' or name == 'Constructor': | 300 name = self._find_first(ext_attr, 'Id') |
446 for constructor in ast.constructors: | 301 value = self._find_first(ext_attr, 'ExtAttrValue') |
447 if constructor.name == 'NamedConstructor': | |
448 constructor_name = ast.extended_attributes['NamedConstructor'] | |
449 else: | |
450 constructor_name = None | |
451 func_value = IDLExtAttrFunctionValue(constructor_name, constructor.a
rguments, True) | |
452 if name == 'Constructor': | |
453 self.setdefault('Constructor', []).append(func_value) | |
454 else: | |
455 self[name] = func_value | |
456 else: | |
457 self[name] = value | |
458 else: | |
459 ext_attrs_ast = self._find_first(ast, 'ExtAttrs') | |
460 if not ext_attrs_ast: | |
461 return | |
462 for ext_attr in self._find_all(ext_attrs_ast, 'ExtAttr'): | |
463 name = self._find_first(ext_attr, 'Id') | |
464 value = self._find_first(ext_attr, 'ExtAttrValue') | |
465 | 302 |
466 if name == 'Constructor': | 303 if name == 'Constructor': |
467 # There might be multiple constructor attributes, collect them | 304 # There might be multiple constructor attributes, collect them |
468 # as a list. Represent plain Constructor attribute | 305 # as a list. Represent plain Constructor attribute |
469 # (without any signature) as None. | 306 # (without any signature) as None. |
470 assert value is None | 307 assert value is None |
471 func_value = None | 308 func_value = None |
472 ctor_args = self._find_first(ext_attr, 'ExtAttrArgList') | 309 ctor_args = self._find_first(ext_attr, 'ExtAttrArgList') |
473 if ctor_args: | 310 if ctor_args: |
474 func_value = IDLExtAttrFunctionValue(None, ctor_args) | 311 func_value = IDLExtAttrFunctionValue(None, ctor_args) |
475 self.setdefault('Constructor', []).append(func_value) | 312 self.setdefault('Constructor', []).append(func_value) |
476 continue | 313 continue |
477 | |
478 func_value = self._find_first(value, 'ExtAttrFunctionValue') | |
479 if func_value: | |
480 # E.g. NamedConstructor=Audio(optional DOMString src) | |
481 self[name] = IDLExtAttrFunctionValue( | |
482 func_value, | |
483 self._find_first(func_value, 'ExtAttrArgList')) | |
484 continue | |
485 | 314 |
486 self[name] = value | 315 func_value = self._find_first(value, 'ExtAttrFunctionValue') |
| 316 if func_value: |
| 317 # E.g. NamedConstructor=Audio(optional DOMString src) |
| 318 self[name] = IDLExtAttrFunctionValue( |
| 319 func_value, |
| 320 self._find_first(func_value, 'ExtAttrArgList')) |
| 321 continue |
| 322 |
| 323 self[name] = value |
487 | 324 |
488 def _all_subnodes(self): | 325 def _all_subnodes(self): |
489 # Extended attributes may contain IDLNodes, e.g. IDLExtAttrFunctionValue | 326 # Extended attributes may contain IDLNodes, e.g. IDLExtAttrFunctionValue |
490 return self.values() | 327 return self.values() |
491 | 328 |
492 | 329 |
493 class IDLExtAttrFunctionValue(IDLNode): | 330 class IDLExtAttrFunctionValue(IDLNode): |
494 """IDLExtAttrFunctionValue.""" | 331 """IDLExtAttrFunctionValue.""" |
495 def __init__(self, func_value_ast, arg_list_ast, is_blink=False): | 332 def __init__(self, func_value_ast, arg_list_ast): |
496 IDLNode.__init__(self, func_value_ast) | 333 IDLNode.__init__(self, func_value_ast) |
497 if is_blink: | 334 self.arguments = self._convert_all(arg_list_ast, 'Argument', IDLArgument) |
498 # Blink path | |
499 self.id = func_value_ast # func_value_ast is the function name for Blink
. | |
500 self.arguments = [] | |
501 for argument in arg_list_ast: | |
502 self.arguments.append(IDLArgument(argument)) | |
503 else: | |
504 self.arguments = self._convert_all(arg_list_ast, 'Argument', IDLArgument) | |
505 | 335 |
506 | 336 |
507 class IDLType(IDLNode): | 337 class IDLType(IDLNode): |
508 """IDLType is used to describe constants, attributes and operations' | 338 """IDLType is used to describe constants, attributes and operations' |
509 return and input types. IDLType matches AST labels such as ScopedName, | 339 return and input types. IDLType matches AST labels such as ScopedName, |
510 StringType, VoidType, IntegerType, etc.""" | 340 StringType, VoidType, IntegerType, etc.""" |
511 | 341 |
512 def __init__(self, ast): | 342 def __init__(self, ast): |
513 IDLNode.__init__(self, ast) | 343 IDLNode.__init__(self, ast) |
514 | |
515 self.nullable = self._has(ast, 'Nullable') | 344 self.nullable = self._has(ast, 'Nullable') |
516 # Search for a 'ScopedName' or any label ending with 'Type'. | 345 # Search for a 'ScopedName' or any label ending with 'Type'. |
517 if isinstance(ast, list): | 346 if isinstance(ast, list): |
518 self.id = self._find_first(ast, 'ScopedName') | 347 self.id = self._find_first(ast, 'ScopedName') |
519 if not self.id: | 348 if not self.id: |
520 # FIXME: use regexp search instead | 349 # FIXME: use regexp search instead |
521 def findType(ast): | 350 def findType(ast): |
522 for label, childAst in ast: | 351 for label, childAst in ast: |
523 if label.endswith('Type'): | 352 if label.endswith('Type'): |
524 type = self._label_to_type(label, ast) | 353 type = self._label_to_type(label, ast) |
525 if type != 'sequence': | 354 if type != 'sequence': |
526 return type | 355 return type |
527 type_ast = self._find_first(childAst, 'Type') | 356 type_ast = self._find_first(childAst, 'Type') |
528 if not type_ast: | 357 if not type_ast: |
529 return type | 358 return type |
530 return 'sequence<%s>' % findType(type_ast) | 359 return 'sequence<%s>' % findType(type_ast) |
531 raise Exception('No type declaration found in %s' % ast) | 360 raise Exception('No type declaration found in %s' % ast) |
532 self.id = findType(ast) | 361 self.id = findType(ast) |
533 # TODO(terry): Remove array_modifiers id has [] appended, keep for old | |
534 # parsing. | |
535 array_modifiers = self._find_first(ast, 'ArrayModifiers') | 362 array_modifiers = self._find_first(ast, 'ArrayModifiers') |
536 if array_modifiers: | 363 if array_modifiers: |
537 self.id += array_modifiers | 364 self.id += array_modifiers |
538 elif isinstance(ast, tuple): | 365 elif isinstance(ast, tuple): |
539 (label, value) = ast | 366 (label, value) = ast |
540 if label == 'ScopedName': | 367 if label == 'ScopedName': |
541 self.id = value | 368 self.id = value |
542 else: | 369 else: |
543 self.id = self._label_to_type(label, ast) | 370 self.id = self._label_to_type(label, ast) |
544 elif isinstance(ast, str): | 371 elif isinstance(ast, str): |
545 self.id = ast | 372 self.id = ast |
546 # New blink handling. | |
547 elif ast.__module__ == "idl_types": | |
548 if isinstance(ast, IdlType): | |
549 type_name = str(ast) | |
550 | |
551 # TODO(terry): For now don't handle unrestricted types see | |
552 # https://code.google.com/p/chromium/issues/detail?id=35429
8 | |
553 type_name = type_name.replace('unrestricted ', '', 1); | |
554 | |
555 # TODO(terry): Handled ScalarValueString as a DOMString. | |
556 type_name = type_name.replace('ScalarValueString', 'DOMString', 1) | |
557 | |
558 self.id = type_name | |
559 else: | |
560 # IdlUnionType | |
561 assert ast.is_union_type | |
562 self.id = self._label_to_type('UnionType', ast) | |
563 if not self.id: | 373 if not self.id: |
564 print '>>>> __module__ %s' % ast.__module__ | |
565 raise SyntaxError('Could not parse type %s' % (ast)) | 374 raise SyntaxError('Could not parse type %s' % (ast)) |
566 | 375 |
567 def _label_to_type(self, label, ast): | 376 def _label_to_type(self, label, ast): |
568 if label == 'LongLongType': | 377 if label == 'LongLongType': |
569 label = 'long long' | 378 label = 'long long' |
570 elif label.endswith('Type'): | 379 elif label.endswith('Type'): |
571 # Omit 'Type' suffix and lowercase the rest. | 380 # Omit 'Type' suffix and lowercase the rest. |
572 label = '%s%s' % (label[0].lower(), label[1:-4]) | 381 label = '%s%s' % (label[0].lower(), label[1:-4]) |
573 | 382 |
574 # Add unsigned qualifier. | 383 # Add unsigned qualifier. |
575 if self._has(ast, 'Unsigned'): | 384 if self._has(ast, 'Unsigned'): |
576 label = 'unsigned %s' % label | 385 label = 'unsigned %s' % label |
577 return label | 386 return label |
578 | 387 |
579 | 388 |
580 class IDLEnum(IDLNode): | 389 class IDLEnum(IDLNode): |
581 """IDLNode for 'enum [id] { [string]+ }'""" | 390 """IDLNode for 'enum [id] { [string]+ }'""" |
582 def __init__(self, ast): | 391 def __init__(self, ast): |
583 IDLNode.__init__(self, ast) | 392 IDLNode.__init__(self, ast) |
584 self._convert_annotations(ast) | 393 self._convert_annotations(ast) |
585 if not(isinstance(ast, list)) and ast.__module__ == "idl_definitions": | 394 # TODO(antonm): save enum values. |
586 # Blink AST | |
587 self.values = ast.values | |
588 else: | |
589 self.values = self._find_all(ast, 'StringLiteral') | |
590 | |
591 # TODO(terry): Need to handle emitting of enums for dart:html | |
592 | 395 |
593 | 396 |
594 class IDLTypeDef(IDLNode): | 397 class IDLTypeDef(IDLNode): |
595 """IDLNode for 'typedef [type] [id]' declarations.""" | 398 """IDLNode for 'typedef [type] [id]' declarations.""" |
596 def __init__(self, ast): | 399 def __init__(self, ast): |
597 IDLNode.__init__(self, ast) | 400 IDLNode.__init__(self, ast) |
598 self._convert_annotations(ast) | 401 self._convert_annotations(ast) |
599 self.type = self._convert_first(ast, 'Type', IDLType) | 402 self.type = self._convert_first(ast, 'Type', IDLType) |
600 | 403 |
601 | 404 |
602 class IDLInterface(IDLNode): | 405 class IDLInterface(IDLNode): |
603 """IDLInterface node contains operations, attributes, constants, | 406 """IDLInterface node contains operations, attributes, constants, |
604 as well as parent references.""" | 407 as well as parent references.""" |
605 | 408 |
606 def __init__(self, ast): | 409 def __init__(self, ast): |
607 IDLNode.__init__(self, ast) | 410 IDLNode.__init__(self, ast) |
608 self._convert_ext_attrs(ast) | 411 self._convert_ext_attrs(ast) |
609 self._convert_annotations(ast) | 412 self._convert_annotations(ast) |
610 | |
611 self.parents = self._convert_all(ast, 'ParentInterface', | 413 self.parents = self._convert_all(ast, 'ParentInterface', |
612 IDLParentInterface) | 414 IDLParentInterface) |
613 | |
614 javascript_interface_name = self.ext_attrs.get('InterfaceName', self.id) | 415 javascript_interface_name = self.ext_attrs.get('InterfaceName', self.id) |
615 self.javascript_binding_name = javascript_interface_name | 416 self.javascript_binding_name = javascript_interface_name |
616 self.doc_js_name = javascript_interface_name | 417 self.doc_js_name = javascript_interface_name |
617 | 418 |
618 if not (self._find_first(ast, 'Callback') is None): | 419 if not (self._find_first(ast, 'Callback') is None): |
619 self.ext_attrs['Callback'] = None | 420 self.ext_attrs['Callback'] = None |
620 if not (self._find_first(ast, 'Partial') is None): | 421 if not (self._find_first(ast, 'Partial') is None): |
621 self.is_supplemental = True | 422 self.is_supplemental = True |
622 self.ext_attrs['Supplemental'] = None | 423 self.ext_attrs['Supplemental'] = None |
623 | 424 |
624 self.operations = self._convert_all(ast, 'Operation', | 425 self.operations = self._convert_all(ast, 'Operation', |
625 lambda ast: IDLOperation(ast, self.doc_js_name)) | 426 lambda ast: IDLOperation(ast, self.doc_js_name)) |
626 self.attributes = self._convert_all(ast, 'Attribute', | 427 self.attributes = self._convert_all(ast, 'Attribute', |
627 lambda ast: IDLAttribute(ast, self.doc_js_name)) | 428 lambda ast: IDLAttribute(ast, self.doc_js_name)) |
628 self.constants = self._convert_all(ast, 'Const', | 429 self.constants = self._convert_all(ast, 'Const', |
629 lambda ast: IDLConstant(ast, self.doc_js_name)) | 430 lambda ast: IDLConstant(ast, self.doc_js_name)) |
630 self.is_supplemental = 'Supplemental' in self.ext_attrs | 431 self.is_supplemental = 'Supplemental' in self.ext_attrs |
631 self.is_no_interface_object = 'NoInterfaceObject' in self.ext_attrs | 432 self.is_no_interface_object = 'NoInterfaceObject' in self.ext_attrs |
632 # TODO(terry): Can eliminate Suppressed when we're only using blink parser. | 433 self.is_fc_suppressed = 'Suppressed' in self.ext_attrs |
633 self.is_fc_suppressed = 'Suppressed' in self.ext_attrs or \ | |
634 'DartSuppress' in self.ext_attrs | |
635 | 434 |
636 | 435 |
637 def reset_id(self, new_id): | 436 def reset_id(self, new_id): |
638 """Reset the id of the Interface and corresponding the JS names.""" | 437 """Reset the id of the Interface and corresponding the JS names.""" |
639 if self.id != new_id: | 438 if self.id != new_id: |
640 self.id = new_id | 439 self.id = new_id |
641 self.doc_js_name = new_id | 440 self.doc_js_name = new_id |
642 self.javascript_binding_name = new_id | 441 self.javascript_binding_name = new_id |
643 for member in self.operations: | 442 for member in self.operations: |
644 member.doc_js_interface_name = new_id | 443 member.doc_js_interface_name = new_id |
(...skipping 17 matching lines...) Expand all Loading... |
662 IDLNode.__init__(self, ast) | 461 IDLNode.__init__(self, ast) |
663 self._convert_annotations(ast) | 462 self._convert_annotations(ast) |
664 self.type = self._convert_first(ast, 'InterfaceType', IDLType) | 463 self.type = self._convert_first(ast, 'InterfaceType', IDLType) |
665 | 464 |
666 | 465 |
667 class IDLMember(IDLNode): | 466 class IDLMember(IDLNode): |
668 """A base class for constants, attributes and operations.""" | 467 """A base class for constants, attributes and operations.""" |
669 | 468 |
670 def __init__(self, ast, doc_js_interface_name): | 469 def __init__(self, ast, doc_js_interface_name): |
671 IDLNode.__init__(self, ast) | 470 IDLNode.__init__(self, ast) |
672 | |
673 self.type = self._convert_first(ast, 'Type', IDLType) | 471 self.type = self._convert_first(ast, 'Type', IDLType) |
674 self._convert_ext_attrs(ast) | 472 self._convert_ext_attrs(ast) |
675 self._convert_annotations(ast) | 473 self._convert_annotations(ast) |
676 self.doc_js_interface_name = doc_js_interface_name | 474 self.doc_js_interface_name = doc_js_interface_name |
677 # TODO(terry): Can eliminate Suppressed when we're only using blink parser. | 475 self.is_fc_suppressed = 'Suppressed' in self.ext_attrs |
678 self.is_fc_suppressed = 'Suppressed' in self.ext_attrs or \ | |
679 'DartSuppress' in self.ext_attrs | |
680 self.is_static = self._has(ast, 'Static') | 476 self.is_static = self._has(ast, 'Static') |
681 | 477 |
682 | 478 |
683 class IDLOperation(IDLMember): | 479 class IDLOperation(IDLMember): |
684 """IDLNode specialization for 'type name(args)' declarations.""" | 480 """IDLNode specialization for 'type name(args)' declarations.""" |
685 def __init__(self, ast, doc_js_interface_name): | 481 def __init__(self, ast, doc_js_interface_name): |
686 IDLMember.__init__(self, ast, doc_js_interface_name) | 482 IDLMember.__init__(self, ast, doc_js_interface_name) |
687 | |
688 self.type = self._convert_first(ast, 'ReturnType', IDLType) | 483 self.type = self._convert_first(ast, 'ReturnType', IDLType) |
689 self.arguments = self._convert_all(ast, 'Argument', IDLArgument) | 484 self.arguments = self._convert_all(ast, 'Argument', IDLArgument) |
690 self.specials = self._find_all(ast, 'Special') | 485 self.specials = self._find_all(ast, 'Special') |
| 486 self.is_stringifier = self._has(ast, 'Stringifier') |
691 # Special case: there are getters of the form | 487 # Special case: there are getters of the form |
692 # getter <ReturnType>(args). For now force the name to be __getter__, | 488 # getter <ReturnType>(args). For now force the name to be __getter__, |
693 # but it should be operator[] later. | 489 # but it should be operator[] later. |
694 if self.id is None: | 490 if self.id is None: |
695 if self.specials == ['getter']: | 491 if self.specials == ['getter']: |
696 if self.ext_attrs.get('Custom') == 'PropertyQuery': | 492 self.id = '__getter__' |
697 # Handling __propertyQuery__ the extended attribute is: | |
698 # [Custom=PropertyQuery] legacycaller boolean (DOMString name); | |
699 self.id = '__propertyQuery__' | |
700 else: | |
701 self.id = '__getter__' | |
702 elif self.specials == ['setter']: | 493 elif self.specials == ['setter']: |
703 self.id = '__setter__' | 494 self.id = '__setter__' |
704 # Special case: if it's a setter, ignore 'declared' return type | 495 # Special case: if it's a setter, ignore 'declared' return type |
705 self.type = IDLType([('VoidType', None)]) | 496 self.type = IDLType([('VoidType', None)]) |
706 elif self.specials == ['deleter']: | 497 elif self.specials == ['deleter']: |
707 self.id = '__delete__' | 498 self.id = '__delete__' |
708 else: | 499 else: |
709 raise Exception('Cannot handle %s: operation has no id' % ast) | 500 raise Exception('Cannot handle %s: operation has no id' % ast) |
710 | 501 |
711 if len(self.arguments) >= 1 and (self.id in _operation_suffix_map) and not
self.ext_attrs.get('ImplementedAs'): | 502 if len(self.arguments) >= 1 and (self.id in _operation_suffix_map) and not
self.ext_attrs.get('ImplementedAs'): |
712 arg = self.arguments[0] | 503 arg = self.arguments[0] |
713 operation_category = 'Named' if arg.type.id == 'DOMString' else 'Indexed
' | 504 operation_category = 'Named' if arg.type.id == 'DOMString' else 'Indexed
' |
714 self.ext_attrs.setdefault('ImplementedAs', 'anonymous%s%s' % (operation_
category, _operation_suffix_map[self.id])) | 505 self.ext_attrs.setdefault('ImplementedAs', 'anonymous%s%s' % (operation_
category, _operation_suffix_map[self.id])) |
715 | 506 |
716 def _extra_repr(self): | 507 def _extra_repr(self): |
717 return [self.arguments] | 508 return [self.arguments] |
718 | 509 |
719 def SameSignatureAs(self, operation): | 510 def SameSignatureAs(self, operation): |
720 if self.type != operation.type: | 511 if self.type != operation.type: |
721 return False | 512 return False |
722 return [a.type for a in self.arguments] == [a.type for a in operation.argume
nts] | 513 return [a.type for a in self.arguments] == [a.type for a in operation.argume
nts] |
723 | 514 |
724 class IDLAttribute(IDLMember): | 515 class IDLAttribute(IDLMember): |
725 """IDLNode specialization for 'attribute type name' declarations.""" | 516 """IDLNode specialization for 'attribute type name' declarations.""" |
726 def __init__(self, ast, doc_js_interface_name): | 517 def __init__(self, ast, doc_js_interface_name): |
727 IDLMember.__init__(self, ast, doc_js_interface_name) | 518 IDLMember.__init__(self, ast, doc_js_interface_name) |
728 self.is_read_only = self._has(ast, 'ReadOnly') | 519 self.is_read_only = self._has(ast, 'ReadOnly') |
729 # There are various ways to define exceptions for attributes: | 520 # There are various ways to define exceptions for attributes: |
730 | |
731 def _extra_repr(self): | 521 def _extra_repr(self): |
732 extra = [] | 522 extra = [] |
733 if self.is_read_only: extra.append('readonly') | 523 if self.is_read_only: extra.append('readonly') |
734 return extra | 524 return extra |
735 | 525 |
736 | |
737 class IDLConstant(IDLMember): | 526 class IDLConstant(IDLMember): |
738 """IDLNode specialization for 'const type name = value' declarations.""" | 527 """IDLNode specialization for 'const type name = value' declarations.""" |
739 def __init__(self, ast, doc_js_interface_name): | 528 def __init__(self, ast, doc_js_interface_name): |
740 IDLMember.__init__(self, ast, doc_js_interface_name) | 529 IDLMember.__init__(self, ast, doc_js_interface_name) |
741 self.value = self._find_first(ast, 'ConstExpr') | 530 self.value = self._find_first(ast, 'ConstExpr') |
742 | 531 |
743 | 532 |
744 class IDLArgument(IDLNode): | 533 class IDLArgument(IDLNode): |
745 """IDLNode specialization for operation arguments.""" | 534 """IDLNode specialization for operation arguments.""" |
746 def __init__(self, ast): | 535 def __init__(self, ast): |
747 IDLNode.__init__(self, ast) | 536 IDLNode.__init__(self, ast) |
748 self.type = self._convert_first(ast, 'Type', IDLType) | 537 self.type = self._convert_first(ast, 'Type', IDLType) |
749 self.optional = self._has(ast, 'Optional') | 538 self.optional = self._has(ast, 'Optional') |
750 self._convert_ext_attrs(ast) | 539 self._convert_ext_attrs(ast) |
751 # TODO(vsm): Recover this from the type instead. | 540 # TODO(vsm): Recover this from the type instead. |
752 if 'Callback' in self.type.id: | 541 if 'Callback' in self.type.id: |
753 self.ext_attrs['Callback'] = None | 542 self.ext_attrs['Callback'] = None |
754 | 543 |
755 def __repr__(self): | 544 def __repr__(self): |
756 return '<IDLArgument(type = %s, id = %s)>' % (self.type, self.id) | 545 return '<IDLArgument(type = %s, id = %s)>' % (self.type, self.id) |
757 | 546 |
758 | 547 |
759 class IDLImplementsStatement(IDLNode): | 548 class IDLImplementsStatement(IDLNode): |
760 """IDLNode specialization for 'IMPLEMENTOR implements IMPLEMENTED' declaration
s.""" | 549 """IDLNode specialization for 'X implements Y' declarations.""" |
761 def __init__(self, ast): | 550 def __init__(self, ast): |
762 IDLNode.__init__(self, ast) | 551 IDLNode.__init__(self, ast) |
763 if isinstance(ast, list) or ast.__module__ != 'idl_definitions': | 552 self.implementor = self._convert_first(ast, 'ImplStmtImplementor', |
764 self.implementor = self._convert_first(ast, 'ImplStmtImplementor', IDLType
) | 553 IDLType) |
765 self.implemented = self._convert_first(ast, 'ImplStmtImplemented', IDLType
) | 554 self.implemented = self._convert_first(ast, 'ImplStmtImplemented', |
| 555 IDLType) |
766 | 556 |
767 | 557 |
768 class IDLAnnotations(IDLDictNode): | 558 class IDLAnnotations(IDLDictNode): |
769 """IDLDictNode specialization for a list of FremontCut annotations.""" | 559 """IDLDictNode specialization for a list of FremontCut annotations.""" |
770 def __init__(self, ast=None): | 560 def __init__(self, ast=None): |
771 IDLDictNode.__init__(self, ast) | 561 IDLDictNode.__init__(self, ast) |
772 self.id = None | 562 self.id = None |
773 if not ast: | 563 if not ast: |
774 return | 564 return |
775 for annotation in self._find_all(ast, 'Annotation'): | 565 for annotation in self._find_all(ast, 'Annotation'): |
776 name = self._find_first(annotation, 'Id') | 566 name = self._find_first(annotation, 'Id') |
777 value = IDLAnnotation(annotation) | 567 value = IDLAnnotation(annotation) |
778 self[name] = value | 568 self[name] = value |
779 | 569 |
780 | 570 |
781 class IDLAnnotation(IDLDictNode): | 571 class IDLAnnotation(IDLDictNode): |
782 """IDLDictNode specialization for one annotation.""" | 572 """IDLDictNode specialization for one annotation.""" |
783 def __init__(self, ast=None): | 573 def __init__(self, ast=None): |
784 IDLDictNode.__init__(self, ast) | 574 IDLDictNode.__init__(self, ast) |
785 self.id = None | 575 self.id = None |
786 if not ast: | 576 if not ast: |
787 return | 577 return |
788 for arg in self._find_all(ast, 'AnnotationArg'): | 578 for arg in self._find_all(ast, 'AnnotationArg'): |
789 name = self._find_first(arg, 'Id') | 579 name = self._find_first(arg, 'Id') |
790 value = self._find_first(arg, 'AnnotationArgValue') | 580 value = self._find_first(arg, 'AnnotationArgValue') |
791 self[name] = value | 581 self[name] = value |
OLD | NEW |