| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright 2015 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """Usage: collect_idls_into_json.py path_file.txt json_file.json | |
| 7 This script collects and organizes interface information and that information du
mps into json file. | |
| 8 """ | |
| 9 | |
| 10 import json | |
| 11 import os | |
| 12 import sys | |
| 13 import utilities | |
| 14 | |
| 15 | |
| 16 from blink_idl_parser import parse_file, BlinkIDLParser | |
| 17 | |
| 18 _INTERFACE = 'Interface' | |
| 19 _IMPLEMENT = 'Implements' | |
| 20 _PARTIAL = 'Partial' | |
| 21 _NAME = 'Name' | |
| 22 _TYPE = 'Type' | |
| 23 _UNIONTYPE = 'UnionType' | |
| 24 _ARRAY = 'Array' | |
| 25 _ANY = 'Any' | |
| 26 _SEQUENCE = 'Sequence' | |
| 27 _PROP_VALUE = 'VALUE' | |
| 28 _VALUE = 'Value' | |
| 29 _PARENT = 'Parent' | |
| 30 _FILEPATH = 'FilePath' | |
| 31 _PROP_FILENAME = 'FILENAME' | |
| 32 _PROP_READONLY = 'READONLY' | |
| 33 _READONLY = 'Readonly' | |
| 34 _PROP_STATIC = 'STATIC' | |
| 35 _STATIC = 'Static' | |
| 36 _CONSTS = 'Consts' | |
| 37 _CONST = 'Const' | |
| 38 _ATTRIBUTES = 'Attributes' | |
| 39 _ATTRIBUTE = 'Attribute' | |
| 40 _OPERATIONS = 'Operations' | |
| 41 _OPERATION = 'Operation' | |
| 42 _PROP_GETTER = 'GETTER' | |
| 43 _NAMED_GETTER = '__getter__' | |
| 44 _PROP_SETTER = 'SETTER' | |
| 45 _NAMED_SETTER = '__setter__' | |
| 46 _PROP_DELETER = 'DELETER' | |
| 47 _NAMED_DELETER = '__deleter__' | |
| 48 _ARGUMENTS = 'Arguments' | |
| 49 _ARGUMENT = 'Argument' | |
| 50 _EXTATTRIBUTES = 'ExtAttributes' | |
| 51 _EXTATTRIBUTE = 'ExtAttribute' | |
| 52 _INHERIT = 'Inherit' | |
| 53 _PROP_REFERENCE = 'REFERENCE' | |
| 54 _PARTIAL_FILEPATH = 'Partial_FilePaths' | |
| 55 _MEMBERS = [_CONSTS, _ATTRIBUTES, _OPERATIONS] | |
| 56 | |
| 57 | |
| 58 def get_definitions(paths): | |
| 59 """Returns a generator of IDL node. | |
| 60 Args: | |
| 61 paths: list of IDL file path | |
| 62 Returns: | |
| 63 a generator which yields IDL node objects | |
| 64 """ | |
| 65 parser = BlinkIDLParser() | |
| 66 for path in paths: | |
| 67 definitions = parse_file(parser, path) | |
| 68 for definition in definitions.GetChildren(): | |
| 69 yield definition | |
| 70 | |
| 71 | |
| 72 def is_implements(definition): | |
| 73 """Returns True if class of |definition| is Implements, otherwise False. | |
| 74 Args: | |
| 75 definition: IDL node | |
| 76 Returns: | |
| 77 True if class of |definition| is Implements, otherwise False. | |
| 78 """ | |
| 79 return definition.GetClass() == _IMPLEMENT | |
| 80 | |
| 81 | |
| 82 def is_partial(definition): | |
| 83 """Returns True if |definition| is 'partial interface' class, otherwise Fals
e. | |
| 84 Args: | |
| 85 definition: IDL node | |
| 86 Return: | |
| 87 True if |definition| is 'partial interface' class, otherwise False. | |
| 88 """ | |
| 89 return definition.GetClass() == _INTERFACE and definition.GetProperty(_PARTI
AL) | |
| 90 | |
| 91 | |
| 92 def get_filepath(interface_node): | |
| 93 """Returns relative path to the IDL in which |interface_node| is defined. | |
| 94 Args: | |
| 95 interface_node: IDL interface | |
| 96 Returns: | |
| 97 str which is |interface_node|'s file path | |
| 98 """ | |
| 99 filename = interface_node.GetProperty(_PROP_FILENAME) | |
| 100 return os.path.relpath(filename) | |
| 101 | |
| 102 | |
| 103 def get_const_node_list(interface_node): | |
| 104 """Returns a list of Const node. | |
| 105 Args: | |
| 106 interface_node: interface node | |
| 107 Returns: | |
| 108 A list of const node | |
| 109 """ | |
| 110 return interface_node.GetListOf(_CONST) | |
| 111 | |
| 112 | |
| 113 def get_const_type(const_node): | |
| 114 """Returns const's type. | |
| 115 Args: | |
| 116 const_node: const node | |
| 117 Returns: | |
| 118 str which is constant type. | |
| 119 """ | |
| 120 return const_node.GetChildren()[0].GetName() | |
| 121 | |
| 122 | |
| 123 def get_const_value(const_node): | |
| 124 """Returns const's value. | |
| 125 This function only supports primitive types. | |
| 126 | |
| 127 Args: | |
| 128 const_node: const node | |
| 129 Returns: | |
| 130 str which is name of constant's value. | |
| 131 """ | |
| 132 if const_node.GetChildren()[1].GetName(): | |
| 133 return const_node.GetChildren()[1].GetName() | |
| 134 else: | |
| 135 for const_child in const_node.GetChildren(): | |
| 136 if const_child.GetClass() == _VALUE and not const_child.GetName(): | |
| 137 return const_child.GetProperty(_PROP_VALUE) | |
| 138 raise Exception('Constant value is empty') | |
| 139 | |
| 140 | |
| 141 def const_node_to_dict(const_node): | |
| 142 """Returns dictionary of const's information. | |
| 143 Args: | |
| 144 const_node: const node | |
| 145 Returns: | |
| 146 dictionary of const's information | |
| 147 """ | |
| 148 return { | |
| 149 _NAME: const_node.GetName(), | |
| 150 _TYPE: get_const_type(const_node), | |
| 151 _VALUE: get_const_value(const_node), | |
| 152 _EXTATTRIBUTES: [extattr_node_to_dict(extattr) for extattr in get_extatt
ribute_node_list(const_node)], | |
| 153 } | |
| 154 | |
| 155 | |
| 156 def get_attribute_node_list(interface_node): | |
| 157 """Returns list of Attribute if the interface have one. | |
| 158 Args: | |
| 159 interface_node: interface node | |
| 160 Returns: | |
| 161 list of attribute node | |
| 162 """ | |
| 163 return interface_node.GetListOf(_ATTRIBUTE) | |
| 164 | |
| 165 | |
| 166 def get_attribute_type(attribute_node): | |
| 167 """Returns type of attribute. | |
| 168 Args: | |
| 169 attribute_node: attribute node | |
| 170 Returns: | |
| 171 name of attribute's type | |
| 172 """ | |
| 173 attr_type = attribute_node.GetOneOf(_TYPE).GetChildren()[0] | |
| 174 type_list = [] | |
| 175 if attr_type.GetClass() == _UNIONTYPE: | |
| 176 union_member_list = attr_type.GetListOf(_TYPE) | |
| 177 for union_member in union_member_list: | |
| 178 for type_component in union_member.GetChildren(): | |
| 179 if type_component.GetClass() == _ARRAY: | |
| 180 type_list[-1] += '[]' | |
| 181 elif type_component.GetClass() == _SEQUENCE: | |
| 182 for seq_type in type_component.GetOneOf(_TYPE).GetChildren()
: | |
| 183 type_list.append('<' + seq_type.GetName() + '>') | |
| 184 else: | |
| 185 type_list.append(type_component.GetName()) | |
| 186 return type_list | |
| 187 elif attr_type.GetClass() == _SEQUENCE: | |
| 188 union_member_types = [] | |
| 189 if attr_type.GetOneOf(_TYPE).GetChildren()[0].GetClass() == _UNIONTYPE: | |
| 190 for union_member in attr_type.GetOneOf(_TYPE).GetOneOf(_UNIONTYPE).G
etListOf(_TYPE): | |
| 191 if len(union_member.GetChildren()) != 1: | |
| 192 raise Exception('Complex type in a union in a sequence is no
t yet supported') | |
| 193 type_component = union_member.GetChildren()[0] | |
| 194 union_member_types.append(type_component.GetName()) | |
| 195 return '<' + str(union_member_types) + '>' | |
| 196 else: | |
| 197 for type_component in attr_type.GetOneOf(_TYPE).GetChildren(): | |
| 198 if type_component.GetClass() == _SEQUENCE: | |
| 199 raise Exception('Sequence in another sequence is not yet sup
ported') | |
| 200 else: | |
| 201 if type_component.GetClass() == _ARRAY: | |
| 202 type_list[-1] += [] | |
| 203 else: | |
| 204 type_list.append(type_component.GetName()) | |
| 205 return '<' + type_list[0] + '>' | |
| 206 elif attr_type.GetClass() == _ANY: | |
| 207 return _ANY | |
| 208 else: | |
| 209 for type_component in attribute_node.GetOneOf(_TYPE).GetChildren(): | |
| 210 if type_component.GetClass() == _ARRAY: | |
| 211 type_list[-1] += '[]' | |
| 212 else: | |
| 213 type_list.append(type_component.GetName()) | |
| 214 return type_list[0] | |
| 215 | |
| 216 | |
| 217 get_operation_type = get_attribute_type | |
| 218 get_argument_type = get_attribute_type | |
| 219 | |
| 220 | |
| 221 def attribute_node_to_dict(attribute_node): | |
| 222 """Returns dictioary of attribute's information. | |
| 223 Args: | |
| 224 attribute_node: attribute node | |
| 225 Returns: | |
| 226 dictionary of attribute's information | |
| 227 """ | |
| 228 return { | |
| 229 _NAME: attribute_node.GetName(), | |
| 230 _TYPE: get_attribute_type(attribute_node), | |
| 231 _EXTATTRIBUTES: [extattr_node_to_dict(extattr) for extattr in get_extatt
ribute_node_list(attribute_node)], | |
| 232 _READONLY: attribute_node.GetProperty(_PROP_READONLY, default=False), | |
| 233 _STATIC: attribute_node.GetProperty(_PROP_STATIC, default=False), | |
| 234 } | |
| 235 | |
| 236 | |
| 237 def get_operation_node_list(interface_node): | |
| 238 """Returns operations node list. | |
| 239 Args: | |
| 240 interface_node: interface node | |
| 241 Returns: | |
| 242 list of oparation node | |
| 243 """ | |
| 244 return interface_node.GetListOf(_OPERATION) | |
| 245 | |
| 246 | |
| 247 def get_argument_node_list(operation_node): | |
| 248 """Returns list of argument. | |
| 249 Args: | |
| 250 operation_node: operation node | |
| 251 Returns: | |
| 252 list of argument node | |
| 253 """ | |
| 254 return operation_node.GetOneOf(_ARGUMENTS).GetListOf(_ARGUMENT) | |
| 255 | |
| 256 | |
| 257 def argument_node_to_dict(argument_node): | |
| 258 """Returns dictionary of argument's information. | |
| 259 Args: | |
| 260 argument_node: argument node | |
| 261 Returns: | |
| 262 dictionary of argument's information | |
| 263 """ | |
| 264 return { | |
| 265 _NAME: argument_node.GetName(), | |
| 266 _TYPE: get_argument_type(argument_node), | |
| 267 } | |
| 268 | |
| 269 | |
| 270 def get_operation_name(operation_node): | |
| 271 """Returns openration's name. | |
| 272 Args: | |
| 273 operation_node: operation node | |
| 274 Returns: | |
| 275 name of operation | |
| 276 """ | |
| 277 if operation_node.GetProperty(_PROP_GETTER): | |
| 278 return _NAMED_GETTER | |
| 279 elif operation_node.GetProperty(_PROP_SETTER): | |
| 280 return _NAMED_SETTER | |
| 281 elif operation_node.GetProperty(_PROP_DELETER): | |
| 282 return _NAMED_DELETER | |
| 283 else: | |
| 284 return operation_node.GetName() | |
| 285 | |
| 286 | |
| 287 def operation_node_to_dict(operation_node): | |
| 288 """Returns dictionary of operation's information. | |
| 289 Args: | |
| 290 operation_node: operation node | |
| 291 Returns: | |
| 292 dictionary of operation's informantion | |
| 293 """ | |
| 294 return { | |
| 295 _NAME: get_operation_name(operation_node), | |
| 296 _ARGUMENTS: [argument_node_to_dict(argument) for argument in get_argumen
t_node_list(operation_node) if argument_node_to_dict(argument)], | |
| 297 _TYPE: get_operation_type(operation_node), | |
| 298 _EXTATTRIBUTES: [extattr_node_to_dict(extattr) for extattr in get_extatt
ribute_node_list(operation_node)], | |
| 299 _STATIC: operation_node.GetProperty(_PROP_STATIC, default=False), | |
| 300 } | |
| 301 | |
| 302 | |
| 303 def get_extattribute_node_list(node): | |
| 304 """Returns list of ExtAttribute. | |
| 305 Args: | |
| 306 node: IDL node | |
| 307 Returns: | |
| 308 list of ExtAttrbute | |
| 309 """ | |
| 310 if node.GetOneOf(_EXTATTRIBUTES): | |
| 311 return node.GetOneOf(_EXTATTRIBUTES).GetListOf(_EXTATTRIBUTE) | |
| 312 else: | |
| 313 return [] | |
| 314 | |
| 315 | |
| 316 def extattr_node_to_dict(extattr): | |
| 317 """Returns dictionary of ExtAttribute's information. | |
| 318 Args: | |
| 319 extattr: ExtAttribute node | |
| 320 Returns: | |
| 321 dictionary of ExtAttribute's information | |
| 322 """ | |
| 323 return { | |
| 324 _NAME: extattr.GetName(), | |
| 325 } | |
| 326 | |
| 327 | |
| 328 def inherit_node_to_dict(interface_node): | |
| 329 """Returns a dictionary of inheritance information. | |
| 330 Args: | |
| 331 interface_node: interface node | |
| 332 Returns: | |
| 333 A dictioanry of inheritance information. | |
| 334 """ | |
| 335 inherit = interface_node.GetOneOf(_INHERIT) | |
| 336 if inherit: | |
| 337 return {_PARENT: inherit.GetName()} | |
| 338 else: | |
| 339 return {_PARENT: None} | |
| 340 | |
| 341 | |
| 342 def interface_node_to_dict(interface_node): | |
| 343 """Returns a dictioary of interface information. | |
| 344 Args: | |
| 345 interface_node: interface node | |
| 346 Returns: | |
| 347 A dictionary of the interface information. | |
| 348 """ | |
| 349 return { | |
| 350 _NAME: interface_node.GetName(), | |
| 351 _FILEPATH: get_filepath(interface_node), | |
| 352 _CONSTS: [const_node_to_dict(const) for const in get_const_node_list(int
erface_node)], | |
| 353 _ATTRIBUTES: [attribute_node_to_dict(attr) for attr in get_attribute_nod
e_list(interface_node) if attr], | |
| 354 _OPERATIONS: [operation_node_to_dict(operation) for operation in get_ope
ration_node_list(interface_node) if operation], | |
| 355 _EXTATTRIBUTES: [extattr_node_to_dict(extattr) for extattr in get_extatt
ribute_node_list(interface_node)], | |
| 356 _INHERIT: inherit_node_to_dict(interface_node) | |
| 357 } | |
| 358 | |
| 359 | |
| 360 def merge_partial_dicts(interfaces_dict, partials_dict): | |
| 361 """Merges partial interface into non-partial interface. | |
| 362 Args: | |
| 363 interfaces_dict: A dict of the non-partial interfaces. | |
| 364 partial_dict: A dict of partial interfaces. | |
| 365 Returns: | |
| 366 A merged dictionary of |interface_dict| with |partial_dict|. | |
| 367 """ | |
| 368 for interface_name, partial in partials_dict.iteritems(): | |
| 369 interface = interfaces_dict.get(interface_name) | |
| 370 if not interface: | |
| 371 raise Exception('There is a partial interface, but the corresponding
non-partial interface was not found.') | |
| 372 for member in _MEMBERS: | |
| 373 interface[member].extend(partial.get(member)) | |
| 374 interface.setdefault(_PARTIAL_FILEPATH, []).append(partial[_FILEPATH
]) | |
| 375 return interfaces_dict | |
| 376 | |
| 377 | |
| 378 def merge_implement_nodes(interfaces_dict, implement_node_list): | |
| 379 """Combines a dict of interface information with referenced interface inform
ation. | |
| 380 Args: | |
| 381 interfaces_dict: dict of interface information | |
| 382 implement_nodes: list of implemented interface node | |
| 383 Returns: | |
| 384 A dict of interface information combined with implements nodes. | |
| 385 """ | |
| 386 for implement in implement_node_list: | |
| 387 reference = implement.GetProperty(_PROP_REFERENCE) | |
| 388 implement = implement.GetName() | |
| 389 if reference not in interfaces_dict.keys() or implement not in interface
s_dict.keys(): | |
| 390 raise Exception('There is not corresponding implement or reference i
nterface.') | |
| 391 for member in _MEMBERS: | |
| 392 interfaces_dict[implement][member].extend(interfaces_dict[reference]
.get(member)) | |
| 393 return interfaces_dict | |
| 394 | |
| 395 | |
| 396 def export_to_jsonfile(dictionary, json_file): | |
| 397 """Writes a Python dict into a JSON file. | |
| 398 Args: | |
| 399 dictioary: interface dictionary | |
| 400 json_file: json file for output | |
| 401 """ | |
| 402 with open(json_file, 'w') as f: | |
| 403 json.dump(dictionary, f, sort_keys=True) | |
| 404 | |
| 405 | |
| 406 def usage(): | |
| 407 sys.stdout.write('Usage: collect_idls_into_json.py <path_file.txt> <output_f
ile.json>\n') | |
| 408 | |
| 409 | |
| 410 def main(args): | |
| 411 if len(args) != 2: | |
| 412 usage() | |
| 413 exit(1) | |
| 414 path_file = args[0] | |
| 415 json_file = args[1] | |
| 416 path_list = utilities.read_file_to_list(path_file) | |
| 417 implement_node_list = [definition | |
| 418 for definition in get_definitions(path_list) | |
| 419 if is_implements(definition)] | |
| 420 interfaces_dict = {definition.GetName(): interface_node_to_dict(definition) | |
| 421 for definition in get_definitions(path_list) | |
| 422 if not is_partial(definition)} | |
| 423 partials_dict = {definition.GetName(): interface_node_to_dict(definition) | |
| 424 for definition in get_definitions(path_list) | |
| 425 if is_partial(definition)} | |
| 426 dictionary = merge_partial_dicts(interfaces_dict, partials_dict) | |
| 427 interfaces_dict = merge_implement_nodes(interfaces_dict, implement_node_list
) | |
| 428 export_to_jsonfile(dictionary, json_file) | |
| 429 | |
| 430 | |
| 431 if __name__ == '__main__': | |
| 432 main(sys.argv[1:]) | |
| OLD | NEW |