| 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 |