| OLD | NEW |
| (Empty) | |
| 1 # Copyright (C) 2013 Google Inc. All rights reserved. |
| 2 # |
| 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are |
| 5 # met: |
| 6 # |
| 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer |
| 11 # in the documentation and/or other materials provided with the |
| 12 # distribution. |
| 13 # * Neither the name of Google Inc. nor the names of its |
| 14 # contributors may be used to endorse or promote products derived from |
| 15 # this software without specific prior written permission. |
| 16 # |
| 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 |
| 29 """Blink IDL Intermediate Representation (IR) classes |
| 30 |
| 31 Also JSON export (and partial import) methods, |
| 32 for use by json_import_export.py. |
| 33 """ |
| 34 |
| 35 import json |
| 36 import os.path |
| 37 |
| 38 # from blink_idl_parser import BlinkIDLParser |
| 39 |
| 40 |
| 41 def none_to_value_is_missing(extended_attributes): |
| 42 # Perl IDL Parser uses 'VALUE_IS_MISSING' for null values in |
| 43 # extended attributes, so add this as a filter when exporting to JSON. |
| 44 new_extended_attributes = {} |
| 45 for key, value in extended_attributes.iteritems(): |
| 46 if value is None: |
| 47 new_extended_attributes[key] = 'VALUE_IS_MISSING' |
| 48 else: |
| 49 new_extended_attributes[key] = value |
| 50 return new_extended_attributes |
| 51 |
| 52 |
| 53 def value_is_missing_to_none(extended_attributes): |
| 54 # Perl IDL Parser uses 'VALUE_IS_MISSING' for null values in |
| 55 # extended attributes, so add this as a filter when importing from JSON. |
| 56 new_extended_attributes = {} |
| 57 for key, value in extended_attributes.iteritems(): |
| 58 if value == 'VALUE_IS_MISSING': |
| 59 new_extended_attributes[key] = None |
| 60 else: |
| 61 new_extended_attributes[key] = value |
| 62 return new_extended_attributes |
| 63 |
| 64 |
| 65 def boolean_to_perl(value): |
| 66 # Perl stores booleans as 1, 0, or undefined (JSON null); |
| 67 # convert to this format |
| 68 if value is None: |
| 69 return None |
| 70 return int(value) |
| 71 |
| 72 |
| 73 def perl_to_boolean(value): |
| 74 # Perl stores booleans as 1, 0, or undefined (JSON null); |
| 75 # convert from this format |
| 76 if value is None: |
| 77 return None |
| 78 return bool(value) |
| 79 |
| 80 |
| 81 class IdlBase(): |
| 82 pass |
| 83 |
| 84 |
| 85 class IdlDocument(IdlBase): |
| 86 def __init__(self, callback_functions=None, enumerations=None, file_name=Non
e, interfaces=None, typedefs=None): |
| 87 interfaces = interfaces or [] |
| 88 if typedefs: |
| 89 for interface in interfaces: |
| 90 interface.apply_typedefs(typedefs) |
| 91 |
| 92 self.callback_functions = callback_functions or [] |
| 93 self.enumerations = enumerations or [] |
| 94 if file_name: |
| 95 self.file_name = os.path.abspath(file_name) |
| 96 self.interfaces = interfaces |
| 97 |
| 98 def to_json(self): |
| 99 return { |
| 100 'idlDocument::callbackFunctions': self.callback_functions, |
| 101 'idlDocument::enumerations': self.enumerations, |
| 102 'idlDocument::fileName': self.file_name, |
| 103 'idlDocument::interfaces': self.interfaces, |
| 104 } |
| 105 |
| 106 def from_json(self, json_dict): |
| 107 callback_functions = [] |
| 108 callback_function_list_json = json_dict['callbackFunctions'] or [] |
| 109 for callback_function_json in callback_function_list_json: |
| 110 # FIXME: how are these handled? |
| 111 pass |
| 112 # callback_function = DomFunction() |
| 113 # callback_function.from_json(callback_function_json) |
| 114 # callback_functions.append(callback_function) |
| 115 self.callback_functions = callback_functions |
| 116 |
| 117 enumerations = [] |
| 118 enumeration_list_json = json_dict['enumerations'] or [] |
| 119 for enumeration_json in enumeration_list_json: |
| 120 enumeration = DomEnum() |
| 121 enumeration.from_json(enumeration_json) |
| 122 enumerations.append(enumeration) |
| 123 self.enumerations = enumerations |
| 124 |
| 125 self.file_name = json_dict['fileName'] |
| 126 |
| 127 interfaces = [] |
| 128 interface_list_json = json_dict['interfaces'] or [] |
| 129 for interface_json in interface_list_json: |
| 130 interface = DomInterface() |
| 131 interface.from_json(interface_json) |
| 132 interfaces.append(interface) |
| 133 self.interfaces = interfaces |
| 134 |
| 135 |
| 136 class DomInterface(IdlBase): |
| 137 def __init__(self, name=None, parents=None, constants=None, functions=None,
attributes=None, extended_attributes=None, constructors=None, custom_constructor
s=None, is_exception=None, is_callback=None, is_partial=None): |
| 138 """ |
| 139 parents: list of strings |
| 140 constants: list of DomConstants |
| 141 functions: list of DomFunctions |
| 142 attributes: list of DomAttributes |
| 143 constructors: list of DomFunctions |
| 144 custom_constructors: list of DomFunctions |
| 145 is_exception: used for exceptions |
| 146 """ |
| 147 self.name = name |
| 148 self.parents = parents or [] |
| 149 self.constants = constants or [] |
| 150 self.functions = functions or [] |
| 151 self.attributes = attributes or [] |
| 152 self.extended_attributes = extended_attributes or {} |
| 153 self.constructors = constructors or [] |
| 154 self.custom_constructors = custom_constructors or [] |
| 155 self.is_exception = is_exception |
| 156 self.is_callback = is_callback |
| 157 self.is_partial = is_partial |
| 158 |
| 159 def apply_typedefs(self, typedefs): |
| 160 for constant in self.constants: |
| 161 constant.apply_typedefs(typedefs) |
| 162 for attribute in self.attributes: |
| 163 attribute.apply_typedefs(typedefs) |
| 164 for function in self.functions: |
| 165 function.apply_typedefs(typedefs) |
| 166 |
| 167 def to_json(self): |
| 168 return { |
| 169 'domInterface::name': self.name, |
| 170 'domInterface::parents': self.parents, |
| 171 'domInterface::constants': self.constants, |
| 172 'domInterface::functions': self.functions, |
| 173 'domInterface::attributes': self.attributes, |
| 174 'domInterface::extendedAttributes': none_to_value_is_missing(self.ex
tended_attributes), |
| 175 'domInterface::constructors': self.constructors, |
| 176 'domInterface::customConstructors': self.custom_constructors, |
| 177 'domInterface::isException': boolean_to_perl(self.is_exception), |
| 178 'domInterface::isCallback': boolean_to_perl(self.is_callback), |
| 179 'domInterface::isPartial': self.is_partial, |
| 180 } |
| 181 |
| 182 def from_json(self, json_dict): |
| 183 self.name = json_dict['name'] |
| 184 self.parents = json_dict['parents'] or [] |
| 185 self.constants = json_dict['constants'] or [] |
| 186 |
| 187 functions = [] |
| 188 function_list_json = json_dict['functions'] or [] |
| 189 for function_json in function_list_json: |
| 190 function = DomFunction() |
| 191 function.from_json(function_json) |
| 192 functions.append(function) |
| 193 self.functions = functions |
| 194 |
| 195 attributes = [] |
| 196 attribute_list_json = json_dict['attributes'] or [] |
| 197 for attribute_json in attribute_list_json: |
| 198 attribute = DomAttribute() |
| 199 attribute.from_json(attribute_json) |
| 200 attributes.append(attribute) |
| 201 self.attributes = attributes |
| 202 |
| 203 self.extended_attributes = value_is_missing_to_none(json_dict['extendedA
ttributes']) |
| 204 |
| 205 constructors = [] |
| 206 constructor_list_json = json_dict['constructors'] or [] |
| 207 for constructor_json in constructor_list_json: |
| 208 constructor = DomFunction() |
| 209 constructor.from_json(constructor_json) |
| 210 constructors.append(constructors) |
| 211 self.constructors = constructors |
| 212 |
| 213 custom_constructors = [] |
| 214 custom_constructor_list_json = json_dict['customConstructors'] or [] |
| 215 for custom_constructor_json in custom_constructor_list_json: |
| 216 custom_constructor = DomFunction() |
| 217 custom_constructor.from_json(custom_constructor_json) |
| 218 custom_constructors.append(custom_constructors) |
| 219 self.custom_constructors = custom_constructors |
| 220 |
| 221 self.is_exception = perl_to_boolean(json_dict['isException']) |
| 222 self.is_callback = perl_to_boolean(json_dict['isCallback']) |
| 223 self.is_partial = json_dict['isPartial'] |
| 224 |
| 225 |
| 226 class DomFunction(IdlBase): |
| 227 def __init__(self, is_static=None, name=None, data_type=None, extended_attri
butes=None, specials=None, parameters=None, overloaded_index=None): |
| 228 """parameters: List of DomParameters""" |
| 229 self.is_static = is_static |
| 230 self.name = name or "" |
| 231 self.data_type = data_type |
| 232 self.extended_attributes = extended_attributes or {} |
| 233 self.specials = specials or [] |
| 234 self.parameters = parameters or [] |
| 235 self.overloaded_index = overloaded_index |
| 236 |
| 237 def apply_typedefs(self, typedefs): |
| 238 # FIXME: apply! |
| 239 print 'Typedef in function!' |
| 240 |
| 241 def to_json(self): |
| 242 return { |
| 243 'domFunction::isStatic': self.is_static, |
| 244 'domFunction::name': self.name, |
| 245 'domFunction::type': self.data_type, |
| 246 'domFunction::extendedAttributes': none_to_value_is_missing(self.ext
ended_attributes), |
| 247 'domFunction::specials': self.specials, |
| 248 'domFunction::parameters': self.parameters, |
| 249 'domFunction::overloadedIndex': self.overloaded_index, |
| 250 } |
| 251 |
| 252 def from_json(self, json_dict): |
| 253 # FIXME |
| 254 return DomFunction() |
| 255 |
| 256 |
| 257 class DomParameter(IdlBase): |
| 258 def __init__(self, name=None, data_type=None, extended_attributes=None, is_o
ptional=False, is_nullable=None, is_variadic=False): |
| 259 """Used to represent a map of 'variable name' <-> 'variable type' |
| 260 |
| 261 data_type: string or UnionType |
| 262 is_optional: (optional T) |
| 263 is_nullable: (T?) |
| 264 is_variadic: (long... numbers) |
| 265 """ |
| 266 # FIXME: boolean values are inconsistent (due to Perl), |
| 267 # being sometimes True, False, or None (Perl: 1, 0, undef) |
| 268 # Should all default to False, and be either True or False |
| 269 self.name = name |
| 270 self.data_type = data_type |
| 271 self.extended_attributes = extended_attributes or {} |
| 272 if is_optional is None: |
| 273 is_optional = False |
| 274 if is_variadic is None: |
| 275 is_variadic = False |
| 276 self.is_optional = boolean_to_perl(is_optional) |
| 277 self.is_nullable = is_nullable |
| 278 self.is_variadic = boolean_to_perl(is_variadic) |
| 279 |
| 280 def to_json(self): |
| 281 return { |
| 282 'domParameter::name': self.name, |
| 283 'domParameter::type': self.data_type, |
| 284 'domParameter::extendedAttributes': none_to_value_is_missing(self.ex
tended_attributes), |
| 285 'domParameter::isOptional': self.is_optional, |
| 286 'domParameter::isNullable': self.is_nullable, |
| 287 'domParameter::isVariadic': self.is_variadic, |
| 288 } |
| 289 |
| 290 |
| 291 class DomAttribute(IdlBase): |
| 292 def __init__(self, data_type=None, name=None, is_nullable=None, is_static=No
ne, is_read_only=None, getter_exceptions=None, setter_exceptions=None, extended_
attributes=None): |
| 293 """data_type: Attribute type (including namespace), string or UnionType |
| 294 is_nullable: (T?) |
| 295 getter_exceptions: Possibly raised exceptions |
| 296 setter_exceptions: Possibly raised exceptions |
| 297 """ |
| 298 self.data_type = data_type |
| 299 self.name = name |
| 300 self.is_nullable = is_nullable |
| 301 self.is_static = is_static |
| 302 self.is_read_only = is_read_only |
| 303 self.getter_exceptions = getter_exceptions or [] |
| 304 self.setter_exceptions = setter_exceptions or [] |
| 305 self.extended_attributes = extended_attributes or {} |
| 306 |
| 307 def apply_typedefs(self, typedefs): |
| 308 # FIXME: apply! |
| 309 print 'Typedef in attribute!' |
| 310 |
| 311 def to_json(self): |
| 312 return { |
| 313 'domAttribute::extendedAttributes': none_to_value_is_missing(self.ex
tended_attributes), |
| 314 'domAttribute::getterExceptions': self.getter_exceptions, |
| 315 'domAttribute::isNullable': self.is_nullable, |
| 316 'domAttribute::isReadOnly': self.is_read_only, |
| 317 'domAttribute::isStatic': self.is_static, |
| 318 'domAttribute::name': self.name, |
| 319 'domAttribute::setterExceptions': self.setter_exceptions, |
| 320 'domAttribute::type': self.data_type, |
| 321 } |
| 322 |
| 323 def from_json(self, json_dict): |
| 324 self.data_type = json_dict['type'] |
| 325 self.extended_attributes = value_is_missing_to_none(json_dict['extendedA
ttributes']) or {} |
| 326 self.getter_exceptions = json_dict['getterExceptions'] or [] |
| 327 self.is_nullable = json_dict['isNullable'] |
| 328 self.is_read_only = json_dict['isReadOnly'] |
| 329 self.is_static = json_dict['isStatic'] |
| 330 self.name = json_dict['name'] |
| 331 self.setter_exceptions = json_dict['setterExceptions'] or [] |
| 332 |
| 333 |
| 334 class DomConstant(IdlBase): |
| 335 def __init__(self, name=None, data_type=None, value=None, extended_attribute
s=None): |
| 336 self.name = name |
| 337 self.data_type = data_type |
| 338 self.value = value |
| 339 self.extended_attributes = extended_attributes or {} |
| 340 |
| 341 def apply_typedefs(self, typedefs): |
| 342 data_type = self.data_type |
| 343 if data_type in typedefs: |
| 344 typedef = typedefs[data_type] |
| 345 if typedef.extended_attributes: |
| 346 # FIXME: why this restriction? |
| 347 raise ValueError('Extended attributes cannot be used in a typede
f used in a constant, but typedef %s used in constant %s has extended attributes
' % (data_type, self.name)) |
| 348 self.data_type = typedef.data_type |
| 349 |
| 350 def to_json(self): |
| 351 return { |
| 352 'domConstant::name': self.name, |
| 353 'domConstant::type': self.data_type, |
| 354 'domConstant::value': self.value, |
| 355 'domConstant::extendedAttributes': none_to_value_is_missing(self.ext
ended_attributes), |
| 356 } |
| 357 |
| 358 |
| 359 class DomEnum(IdlBase): |
| 360 def __init__(self, name=None, values=None): |
| 361 """name: enumeration identifier |
| 362 values: enumeration values, list of unique strings |
| 363 """ |
| 364 self.name = name |
| 365 self.values = values or [] |
| 366 |
| 367 def from_json(self, json_dict): |
| 368 # FIXME |
| 369 return DomEnum() |
| 370 |
| 371 |
| 372 class Typedef(): |
| 373 # Not exposed in bindings, internal to IDL parsing |
| 374 def __init__(self, extended_attributes=None, data_type=None): |
| 375 self.extended_attributes = extended_attributes or {} |
| 376 self.data_type = data_type |
| 377 |
| 378 |
| 379 class UnionType(IdlBase): |
| 380 def __init__(self, union_member_types=None): |
| 381 """union_member_types: list of string or UnionType""" |
| 382 self.union_member_types = union_member_types or [] |
| OLD | NEW |