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 |