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 """Convert generic Web IDL AST to Blink IR |
| 30 |
| 31 Last phase of frontend, after lexer and parser. |
| 32 IR then consumed by code_generator_v8.py to produce .cpp/.h files. |
| 33 Currently contains legacy code for compatibility with Perl format. |
| 34 Ideally parser would generate IR directly, rather then requiring another phase. |
| 35 """ |
| 36 |
| 37 from ir import IdlDocument, DomInterface, DomFunction, CallbackFunction, DomPara
meter, DomAttribute, DomConstant, DomEnum, Typedef, UnionType |
| 38 |
| 39 |
| 40 SPECIAL_KEYWORD_LIST = ['GETTER', 'SETTER', 'CREATOR', 'DELETER', 'LEGACYCALLER'
] |
| 41 |
| 42 # Generic Web IDL AST to Blink IR |
| 43 |
| 44 |
| 45 def web_idl_ast_to_blink_ir(node): |
| 46 if node is None: |
| 47 return None |
| 48 node_class = node.GetClass() |
| 49 if node_class == 'File': |
| 50 return file_node_to_idl_document(node) |
| 51 raise ValueError('Unrecognized node class: %s' % node_class) |
| 52 |
| 53 |
| 54 def file_node_to_idl_document(node): |
| 55 callback_functions = [] |
| 56 enumerations = [] |
| 57 file_name = node.GetName() |
| 58 interfaces = [] |
| 59 typedefs = {} |
| 60 |
| 61 children = node.GetChildren() |
| 62 for child in children: |
| 63 child_class = child.GetClass() |
| 64 if child_class == 'Interface': |
| 65 interfaces.append(interface_node_to_dom_interface(child)) |
| 66 elif child_class == 'Exception': |
| 67 interfaces.append(exception_node_to_dom_interface(child)) |
| 68 elif child_class == 'Typedef': |
| 69 type_name = child.GetName() |
| 70 typedefs[type_name] = typedef_node_to_typedef(child) |
| 71 elif child_class == 'Enum': |
| 72 enumerations.append(enum_node_to_dom_enum(child)) |
| 73 elif child_class == 'Callback': |
| 74 callback_functions.append(callback_node_to_callback_function(child)) |
| 75 else: |
| 76 raise ValueError('Unrecognized node class: %s' % child_class) |
| 77 |
| 78 return IdlDocument(callback_functions=callback_functions, enumerations=enume
rations, file_name=file_name, interfaces=interfaces, typedefs=typedefs) |
| 79 |
| 80 # Interface |
| 81 |
| 82 |
| 83 def interface_node_to_dom_interface(node, is_exception=None): |
| 84 def multiple_inherit_node_to_parents(node): |
| 85 parents = [] |
| 86 for child in node.GetChildren(): |
| 87 parents.append(child.GetName()) |
| 88 return parents |
| 89 |
| 90 attributes = [] |
| 91 constants = [] |
| 92 extended_attributes = {} |
| 93 functions = [] |
| 94 is_callback = node.GetProperty('Callback') |
| 95 name = node.GetName() |
| 96 parents = [] |
| 97 |
| 98 children = node.GetChildren() |
| 99 for child in children: |
| 100 child_class = child.GetClass() |
| 101 if child_class == 'Attribute': |
| 102 attributes.append(attribute_node_to_dom_attribute(child)) |
| 103 elif child_class == 'MultipleInherit': |
| 104 parents = multiple_inherit_node_to_parents(child) |
| 105 elif child_class == 'Const': |
| 106 constants.append(constant_node_to_dom_constant(child)) |
| 107 elif child_class == 'Operation': |
| 108 functions.append(operation_node_to_dom_function(child)) |
| 109 elif child_class == 'OperationOrIterator': |
| 110 functions.append(operation_or_iterator_node_to_dom_function(child)) |
| 111 elif child_class == 'ExtAttributes': |
| 112 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) |
| 113 elif child_class == 'ExceptionFieldToString': |
| 114 functions.append(exception_field_to_string_node_to_dom_function(chil
d)) |
| 115 else: |
| 116 raise ValueError('Unrecognized node class: %s' % child_class) |
| 117 constructors, custom_constructors = extended_attributes_to_constructors(exte
nded_attributes) |
| 118 |
| 119 return DomInterface(name=name, attributes=attributes, constants=constants, c
onstructors=constructors, custom_constructors=custom_constructors, extended_attr
ibutes=extended_attributes, functions=functions, is_callback=is_callback, is_exc
eption=is_exception, parents=parents) |
| 120 |
| 121 |
| 122 def attribute_node_to_dom_attribute(node): |
| 123 data_type = None |
| 124 extended_attributes = {} |
| 125 is_nullable = None |
| 126 property_dictionary = node.GetProperties() |
| 127 is_read_only = get_property('READONLY', property_dictionary) |
| 128 name = node.GetName() |
| 129 |
| 130 children = node.GetChildren() |
| 131 for child in children: |
| 132 child_class = child.GetClass() |
| 133 if child_class == 'Type': |
| 134 data_type = type_node_to_type(child) |
| 135 type_property_dictionary = child.GetProperties() |
| 136 is_nullable = get_quoted_property('NULLABLE', type_property_dictiona
ry) |
| 137 elif child_class == 'ExtAttributes': |
| 138 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) |
| 139 else: |
| 140 raise ValueError('Unrecognized node class: %s' % child_class) |
| 141 |
| 142 return DomAttribute(data_type=data_type, extended_attributes=extended_attrib
utes, is_read_only=is_read_only, is_nullable=is_nullable, name=name) |
| 143 |
| 144 |
| 145 def constant_node_to_dom_constant(node): |
| 146 name = node.GetName() |
| 147 |
| 148 children = node.GetChildren() |
| 149 num_children = len(children) |
| 150 if num_children > 3: |
| 151 raise ValueError('Expected at most 3 children, got %s' % num_children) |
| 152 |
| 153 type_node = children[0] |
| 154 # FIXME: use inner get type function |
| 155 data_type = type_node.GetName() |
| 156 |
| 157 value_node = children[1] |
| 158 value_node_class = value_node.GetClass() |
| 159 if value_node_class != 'Value': |
| 160 raise ValueError('Expected Value node, got %s' % value_node_class) |
| 161 value = value_node.GetName() |
| 162 |
| 163 extended_attributes = None |
| 164 if num_children == 3: |
| 165 ext_attributes_node = children[2] |
| 166 extended_attributes = ext_attributes_node_to_extended_attributes(ext_att
ributes_node) |
| 167 |
| 168 return DomConstant(data_type=data_type, extended_attributes=extended_attribu
tes, name=name, value=value) |
| 169 |
| 170 |
| 171 def operation_node_to_dom_function(node): |
| 172 # FIXME: make Operation, and OperationOrIterator have |
| 173 # same tree structure so can merge these |
| 174 |
| 175 name = node.GetName() |
| 176 # FIXME: AST should use None internally |
| 177 if name == '_unnamed_': |
| 178 name = None |
| 179 |
| 180 property_dictionary = node.GetProperties() |
| 181 is_static = None |
| 182 if 'STATIC' in property_dictionary: |
| 183 is_static = property_dictionary['STATIC'] |
| 184 specials = [] |
| 185 for special_keyword in SPECIAL_KEYWORD_LIST: |
| 186 if special_keyword in property_dictionary: |
| 187 specials.append(special_keyword.lower()) |
| 188 |
| 189 extended_attributes = None |
| 190 parameters = [] |
| 191 return_type = None |
| 192 children = node.GetChildren() |
| 193 for child in children: |
| 194 child_class = child.GetClass() |
| 195 if child_class == 'Arguments': |
| 196 parameters = argument_list_node_to_parameters(child) |
| 197 elif child_class == 'Type': |
| 198 return_type = type_node_to_type(child) |
| 199 elif child_class == 'ExtAttributes': |
| 200 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) |
| 201 else: |
| 202 raise ValueError('Unrecognized node class: %s' % child_class) |
| 203 |
| 204 return DomFunction(name=name, data_type=return_type, extended_attributes=ext
ended_attributes, is_static=is_static, parameters=parameters, specials=specials) |
| 205 |
| 206 |
| 207 def operation_or_iterator_node_to_dom_function(node): |
| 208 extended_attributes = {} |
| 209 name = None |
| 210 parameters = [] |
| 211 return_type = None |
| 212 children = node.GetChildren() |
| 213 for child in children: |
| 214 child_class = child.GetClass() |
| 215 if child_class == 'Type': |
| 216 return_type = type_node_to_type(child) |
| 217 elif child_class == 'Operation': |
| 218 name = child.GetName() |
| 219 # FIXME: this nesting is really ugly |
| 220 grandchildren = child.GetChildren() |
| 221 for grandchild in grandchildren: |
| 222 grandchild_class = grandchild.GetClass() |
| 223 if grandchild_class == 'Arguments': |
| 224 parameters = argument_list_node_to_parameters(grandchild) |
| 225 elif grandchild_class == 'ExtAttributes': |
| 226 extended_attributes = ext_attributes_node_to_extended_attrib
utes(grandchild) |
| 227 else: |
| 228 raise ValueError('Unrecognized node class: %s' % grandchild_
class) |
| 229 elif child_class == 'ExtAttributes': |
| 230 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) |
| 231 else: |
| 232 raise ValueError('Unrecognized node class: %s' % child_class) |
| 233 |
| 234 return DomFunction(name=name, data_type=return_type, extended_attributes=ext
ended_attributes, parameters=parameters) |
| 235 |
| 236 |
| 237 def argument_list_node_to_parameters(argument_list_node): |
| 238 # FIXME: is this check necessary? |
| 239 if argument_list_node is None: |
| 240 return [] |
| 241 parameters = [] |
| 242 argument_list = argument_list_node.GetChildren() |
| 243 for argument_node in argument_list: |
| 244 parameters.append(argument_node_to_dom_parameter(argument_node)) |
| 245 return parameters |
| 246 |
| 247 |
| 248 def argument_node_to_dom_parameter(node): |
| 249 name = node.GetName() |
| 250 is_optional = node.GetProperty('OPTIONAL') |
| 251 |
| 252 data_type = None |
| 253 extended_attributes = {} |
| 254 is_nullable = False |
| 255 is_variadic = None |
| 256 children = node.GetChildren() |
| 257 for child in children: |
| 258 child_class = child.GetClass() |
| 259 if child_class == 'Type': |
| 260 data_type = type_node_to_type(child) |
| 261 type_property_dictionary = child.GetProperties() |
| 262 is_nullable = get_quoted_property('NULLABLE', type_property_dictiona
ry) |
| 263 elif child_class == 'ExtAttributes': |
| 264 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) |
| 265 elif child_class == 'Argument': |
| 266 child_name = child.GetName() |
| 267 if child_name != '...': |
| 268 raise ValueError('Unrecognized Argument node; expected "...", go
t "%s"' % child_name) |
| 269 is_variadic = child.GetProperty('ELLIPSIS') |
| 270 else: |
| 271 raise ValueError('Unrecognized node class: %s' % child_class) |
| 272 |
| 273 return DomParameter(name=name, data_type=data_type, extended_attributes=exte
nded_attributes, is_nullable=is_nullable, is_optional=is_optional, is_variadic=i
s_variadic) |
| 274 |
| 275 # Minor definitions |
| 276 |
| 277 |
| 278 def callback_node_to_callback_function(node): |
| 279 name = node.GetName() |
| 280 children = node.GetChildren() |
| 281 num_children = len(children) |
| 282 if num_children != 2: |
| 283 raise ValueError('Expected 2 children, got %s' % num_children) |
| 284 |
| 285 type_node = children[0] |
| 286 data_type = type_node_to_type(type_node) |
| 287 |
| 288 arguments_node = children[1] |
| 289 arguments_node_class = arguments_node.GetClass() |
| 290 if arguments_node_class != 'Arguments': |
| 291 raise ValueError('Expected Value node, got %s' % arguments_node_class) |
| 292 parameters = argument_list_node_to_parameters(arguments_node) |
| 293 |
| 294 return CallbackFunction(name=name, data_type=data_type, parameters=parameter
s) |
| 295 |
| 296 |
| 297 def enum_node_to_dom_enum(node): |
| 298 name = node.GetName() |
| 299 values = [] |
| 300 for child in node.GetChildren(): |
| 301 values.append(child.GetName()) |
| 302 return DomEnum(name=name, values=values) |
| 303 |
| 304 |
| 305 def exception_field_to_string_node_to_dom_function(node): |
| 306 extended_attributes = {} |
| 307 name = node.GetName() |
| 308 children = node.GetChildren() |
| 309 if len(children) > 2: |
| 310 raise ValueError('ExceptionFieldToString node with %s children, expected
at most 2' % len(children)) |
| 311 |
| 312 type_node = children[0] |
| 313 return_type = type_node_to_type(type_node) |
| 314 |
| 315 if len(children) > 1: |
| 316 ext_attributes_node = children[1] |
| 317 extended_attributes = ext_attributes_node_to_extended_attributes(ext_att
ributes_node) |
| 318 |
| 319 return DomFunction(name=name, data_type=return_type, extended_attributes=ext
ended_attributes) |
| 320 |
| 321 |
| 322 def exception_node_to_dom_interface(node): |
| 323 # Exceptions treated as interfaces with a flag set, |
| 324 # rather than a different class |
| 325 return interface_node_to_dom_interface(node, is_exception=True) |
| 326 |
| 327 |
| 328 def typedef_node_to_typedef(node): |
| 329 data_type = None |
| 330 extended_attributes = None |
| 331 |
| 332 children = node.GetChildren() |
| 333 for child in children: |
| 334 child_class = child.GetClass() |
| 335 if child_class == 'Type': |
| 336 data_type = type_node_to_type(child) |
| 337 elif child_class == 'ExtAttributes': |
| 338 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) |
| 339 raise ValueError('Extended attributes in a typedef are untested!') |
| 340 else: |
| 341 raise ValueError('Unrecognized node class: %s' % child_class) |
| 342 |
| 343 return Typedef(data_type=data_type, extended_attributes=extended_attributes) |
| 344 |
| 345 # Extended attributes |
| 346 |
| 347 |
| 348 def ext_attributes_node_to_extended_attributes(node): |
| 349 # Constructors and Custom Constructors can have duplicate entries due to |
| 350 # overloading, but Named Constructors cannot |
| 351 constructors = [] |
| 352 custom_constructors = [] |
| 353 extended_attributes = {} |
| 354 |
| 355 attribute_list = node.GetChildren() |
| 356 for attribute in attribute_list: |
| 357 name = attribute.GetName() |
| 358 children = attribute.GetChildren() |
| 359 if name in ['Constructor', 'CustomConstructor', 'NamedConstructor']: |
| 360 child = None |
| 361 child_class = None |
| 362 # FIXME: is child required?? append(None)?? |
| 363 if children: |
| 364 if len(children) > 1: |
| 365 raise ValueError('ExtAttributes node with %s children, expec
ted at most 1' % len(children)) |
| 366 child = children[0] |
| 367 child_class = child.GetClass() |
| 368 if name == 'Constructor': |
| 369 if child_class and child_class != 'Arguments': |
| 370 raise ValueError('Constructor only supports Arguments as chi
ld, but has child of class: %s' % child_class) |
| 371 constructors.append(child) |
| 372 elif name == 'CustomConstructor': |
| 373 if child_class and child_class != 'Arguments': |
| 374 raise ValueError('Custom Constructor only supports Arguments
as child, but has child of class: %s' % child_class) |
| 375 custom_constructors.append(child) |
| 376 else: # name == 'NamedConstructor' |
| 377 if child_class and child_class != 'Call': |
| 378 raise ValueError('Named Constructor only supports Call as ch
ild, but has child of class: %s' % child_class) |
| 379 extended_attributes[name] = child |
| 380 elif children: |
| 381 raise ValueError('Non-constructor ExtAttributes node with children:
%s' % name) |
| 382 else: |
| 383 value = attribute.GetProperty('VALUE') |
| 384 extended_attributes[name] = value |
| 385 |
| 386 # Store constructors and custom constructors in special list attributes, |
| 387 # which are deleted later. Note plural in key. |
| 388 if constructors: |
| 389 extended_attributes['Constructors'] = constructors |
| 390 if custom_constructors: |
| 391 extended_attributes['CustomConstructors'] = custom_constructors |
| 392 |
| 393 return extended_attributes |
| 394 |
| 395 |
| 396 def extended_attributes_to_constructors(extended_attributes): |
| 397 """Returns constructors and custom_constructors (lists of DomFunctions), |
| 398 deletes the special list attributes, and puts dummy empty value in |
| 399 Constructor and CustomConstructor extended attributes. |
| 400 Auxiliary function for interface_node_to_dom_interface.""" |
| 401 constructors = [] |
| 402 custom_constructors = [] |
| 403 if 'Constructors' in extended_attributes: |
| 404 constructor_list = extended_attributes['Constructors'] |
| 405 # If not overloaded, have index 0, otherwise index from 1 |
| 406 overloaded_index = 0 if len(constructor_list) == 1 else 1 |
| 407 for arguments in constructor_list: |
| 408 name = 'Constructor' |
| 409 parameters = argument_list_node_to_parameters(arguments) |
| 410 # FIXME: other default for is_variadic |
| 411 constructors.append(DomFunction(name=name, extended_attributes=exten
ded_attributes, overloaded_index=overloaded_index, parameters=parameters)) |
| 412 overloaded_index += 1 |
| 413 del extended_attributes['Constructors'] |
| 414 extended_attributes['Constructor'] = None |
| 415 |
| 416 # Prefix 'CallWith' and 'RaisesException' with 'Constructor' |
| 417 # FIXME: I have no idea why this is necessary |
| 418 if 'CallWith' in extended_attributes: |
| 419 extended_attributes['ConstructorCallWith'] = extended_attributes['Ca
llWith'] |
| 420 del extended_attributes['CallWith'] |
| 421 if 'RaisesException' in extended_attributes: |
| 422 extended_attributes['ConstructorRaisesException'] = extended_attribu
tes['RaisesException'] |
| 423 del extended_attributes['RaisesException'] |
| 424 |
| 425 if 'CustomConstructors' in extended_attributes: |
| 426 custom_constructor_list = extended_attributes['CustomConstructors'] |
| 427 # If not overloaded, have index 0, otherwise index from 1 |
| 428 overloaded_index = 0 if len(custom_constructor_list) == 1 else 1 |
| 429 for arguments in custom_constructor_list: |
| 430 name = 'CustomConstructor' |
| 431 parameters = argument_list_node_to_parameters(arguments) |
| 432 custom_constructors.append(DomFunction(name=name, extended_attribute
s=extended_attributes, overloaded_index=overloaded_index, parameters=parameters)
) |
| 433 overloaded_index += 1 |
| 434 del extended_attributes['CustomConstructors'] |
| 435 extended_attributes['CustomConstructor'] = None |
| 436 |
| 437 if 'NamedConstructor' in extended_attributes: |
| 438 name = 'NamedConstructor' |
| 439 call_node = extended_attributes['NamedConstructor'] |
| 440 extended_attributes['NamedConstructor'] = call_node.GetName() |
| 441 arguments = call_node.GetChildren()[0] |
| 442 parameters = argument_list_node_to_parameters(arguments) |
| 443 overloaded_index = None # FIXME: handle overloaded named constructors |
| 444 constructors.append(DomFunction(name=name, extended_attributes=extended_
attributes, overloaded_index=overloaded_index, parameters=parameters)) |
| 445 |
| 446 return constructors, custom_constructors |
| 447 |
| 448 # Types |
| 449 |
| 450 |
| 451 def type_node_to_type(node): |
| 452 children = node.GetChildren() |
| 453 if not children: |
| 454 raise ValueError('Type node expects children, got none.') |
| 455 if len(children) > 2: |
| 456 raise ValueError('Type node expects at most 2 children (type + optional
array []), got %s (multi-dimensional arrays are not supported).' % len(children)
) |
| 457 |
| 458 type_node_child = children[0] |
| 459 data_type = type_node_inner_to_type(type_node_child) |
| 460 |
| 461 if len(children) == 2: |
| 462 array_node = children[1] |
| 463 array_node_class = array_node.GetClass() |
| 464 if array_node_class != 'Array': |
| 465 raise ValueError('Expected Array node as TypeSuffix, got %s node.' %
array_node_class) |
| 466 data_type += '[]' |
| 467 |
| 468 return data_type |
| 469 |
| 470 |
| 471 def type_node_inner_to_type(node): |
| 472 """Auxiliary.""" |
| 473 # FIXME: better comment |
| 474 node_class = node.GetClass() |
| 475 if node_class in ['PrimitiveType', 'Typeref']: |
| 476 return node.GetName() |
| 477 elif node_class == 'Any': |
| 478 return 'any' |
| 479 elif node_class == 'Sequence': |
| 480 return sequence_node_to_type(node) |
| 481 elif node_class == 'UnionType': |
| 482 return union_type_node_to_type(node) |
| 483 raise ValueError('Unrecognized node class: %s' % node_class) |
| 484 |
| 485 |
| 486 def sequence_node_to_type(node): |
| 487 children = node.GetChildren() |
| 488 if len(children) != 1: |
| 489 raise ValueError('Sequence node expects exactly 1 child, got %s' % len(c
hildren)) |
| 490 sequence_child = children[0] |
| 491 sequence_child_class = sequence_child.GetClass() |
| 492 if sequence_child_class != 'Type': |
| 493 raise ValueError('Unrecognized node class: %s' % sequence_child_class) |
| 494 sequence_type = type_node_to_type(sequence_child) |
| 495 return 'sequence<%s>' % sequence_type |
| 496 |
| 497 |
| 498 def union_type_node_to_type(node): |
| 499 union_member_types = [] |
| 500 for member_type_node in node.GetChildren(): |
| 501 member_type = type_node_inner_to_type(member_type_node) |
| 502 union_member_types.append(member_type) |
| 503 return UnionType(union_member_types=union_member_types) |
| 504 |
| 505 |
| 506 # Perl JSON compatibility functions |
| 507 |
| 508 |
| 509 def get_property(key, dictionary): |
| 510 # Need to use 1/0/None rather than True/False for compatibility |
| 511 # with Perl-generated JSON. |
| 512 # FIXME: can this be replaced by boolean_to_perl in to_json instead? |
| 513 # FIXME: removed once verify generated code same |
| 514 if key in dictionary: |
| 515 if dictionary[key]: |
| 516 return 1 |
| 517 else: |
| 518 return 0 |
| 519 return None |
| 520 |
| 521 |
| 522 def get_quoted_property(key, dictionary): |
| 523 # More bug-for-bug compatibility with Perl, |
| 524 # here giving certain values as strings rather than integers. |
| 525 # FIXME: remove once verify generated code same |
| 526 if key in dictionary: |
| 527 if dictionary[key]: |
| 528 return '1' |
| 529 else: |
| 530 return '0' |
| 531 return None |
OLD | NEW |