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