def type_node_to_type(node): children = node.GetChildren() if len(children) < 1 or len(children) > 2: raise ValueError( 'Type node expects 1 or 2 children (type + optional array []), got %s (multi-dimensional arrays are not supported).' % len(children)) base_type = type_node_inner_to_type(children[0]) if node.GetProperty('NULLABLE'): base_type = IdlNullableType(base_type) if len(children) == 2: array_node = children[1] array_node_class = array_node.GetClass() if array_node_class != 'Array': raise ValueError( 'Expected Array node as TypeSuffix, got %s node.' % array_node_class) array_type = IdlArrayType(base_type) if array_node.GetProperty('NULLABLE'): return IdlNullableType(array_type) return array_type return base_type
def test_enumerate_argument_types(self): splitter = MethodOverloadSplitter(IdlOperation()) nullable_and_primitive = IdlArgument() nullable_and_primitive.idl_type = IdlNullableType(IdlType('double')) with self.assertRaises(ValueError): splitter._enumerate_argument_types(nullable_and_primitive) argument = IdlArgument() foo_type = IdlType('Foo') bar_type = IdlType('Bar') argument.idl_type = foo_type self.assertEqual(splitter._enumerate_argument_types(argument), [foo_type]) argument.is_optional = True self.assertEqual(splitter._enumerate_argument_types(argument), [None, foo_type]) argument.is_optional = False argument.idl_type = IdlUnionType([foo_type, bar_type]) self.assertEqual(splitter._enumerate_argument_types(argument), [foo_type, bar_type]) argument.is_optional = True self.assertEqual(splitter._enumerate_argument_types(argument), [None, foo_type, bar_type])
def preprocess_idl_type(idl_type): if idl_type.is_nullable: return IdlNullableType(idl_type.inner_type.preprocessed_type) if idl_type.is_enum: # Enumerations are internally DOMStrings return IdlType('DOMString') if idl_type.base_type in ['any', 'object'] or idl_type.is_callback_function: return IdlType('ScriptValue') return idl_type
def type_node_to_type(node): children = node.GetChildren() if len(children) != 1: raise ValueError('Type node expects 1 child, got %d.' % len(children)) base_type = type_node_inner_to_type(children[0]) if node.GetProperty('NULLABLE'): base_type = IdlNullableType(base_type) return base_type
def preprocess_idl_type(idl_type): extended_attributes = idl_type.extended_attributes if idl_type.is_nullable: return IdlNullableType(idl_type.inner_type.preprocessed_type) if idl_type.is_enum: # Enumerations are internally DOMStrings return IdlType('DOMString', extended_attributes) if idl_type.base_type in ['any', 'object'] or idl_type.is_custom_callback_function: return IdlType('ScriptValue', extended_attributes) if idl_type.is_callback_function: return idl_type return idl_type
def sequence_node_to_type(node): children = node.GetChildren() if len(children) != 1: raise ValueError('Sequence node expects exactly 1 child, got %s' % len(children)) sequence_child = children[0] sequence_child_class = sequence_child.GetClass() if sequence_child_class != 'Type': raise ValueError('Unrecognized node class: %s' % sequence_child_class) element_type = type_node_to_type(sequence_child) sequence_type = IdlSequenceType(element_type) if node.GetProperty('NULLABLE'): return IdlNullableType(sequence_type) return sequence_type
def preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes): """Returns IDL type and value, with preliminary type conversions applied.""" idl_type = idl_type.preprocessed_type if idl_type.name == 'Promise': idl_type = IdlType('ScriptValue') if idl_type.base_type in ['long long', 'unsigned long long']: # long long and unsigned long long are not representable in ECMAScript; # we represent them as doubles. is_nullable = idl_type.is_nullable idl_type = IdlType('double') if is_nullable: idl_type = IdlNullableType(idl_type) cpp_value = 'static_cast<double>(%s)' % cpp_value return idl_type, cpp_value
def type_node_to_type(node): children = node.GetChildren() if len(children) != 1 and len(children) != 2: raise ValueError('Type node expects 1 or 2 child(ren), got %d.' % len(children)) base_type = type_node_inner_to_type(children[0]) if len(children) == 2: extended_attributes = ext_attributes_node_to_extended_attributes(children[1]) base_type.set_extended_attributes(extended_attributes) if node.GetProperty('NULLABLE'): base_type = IdlNullableType(base_type) return base_type
def sequence_node_to_type(node): children = node.GetChildren() class_name = node.GetClass() if len(children) != 1: raise ValueError('%s node expects exactly 1 child, got %s' % (class_name, len(children))) sequence_child = children[0] sequence_child_class = sequence_child.GetClass() if sequence_child_class != 'Type': raise ValueError('Unrecognized node class: %s' % sequence_child_class) element_type = type_node_to_type(sequence_child) if class_name == 'Sequence': sequence_type = IdlSequenceType(element_type) elif class_name == 'FrozenArray': sequence_type = IdlFrozenArrayType(element_type) else: raise ValueError('Unexpected node: %s' % class_name) if node.GetProperty('NULLABLE'): return IdlNullableType(sequence_type) return sequence_type
def preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes): """Returns IDL type and value, with preliminary type conversions applied.""" idl_type = idl_type.preprocessed_type if idl_type.name == 'Promise': idl_type = IdlType('ScriptValue') if idl_type.base_type in ['long long', 'unsigned long long']: # long long and unsigned long long are not representable in ECMAScript; # we represent them as doubles. is_nullable = idl_type.is_nullable idl_type = IdlType('double') if is_nullable: idl_type = IdlNullableType(idl_type) cpp_value = 'static_cast<double>(%s)' % cpp_value # HTML5 says that unsigned reflected attributes should be in the range # [0, 2^31). When a value isn't in this range, a default value (or 0) # should be returned instead. extended_attributes = extended_attributes or {} if ('Reflect' in extended_attributes and idl_type.base_type in ['unsigned long', 'unsigned short']): cpp_value = cpp_value.replace('getUnsignedIntegralAttribute', 'getIntegralAttribute') cpp_value = 'std::max(0, static_cast<int>(%s))' % cpp_value return idl_type, cpp_value
def test_valid_inner_type_basic(self): inner_type = IdlType('long') self.assertTrue(IdlNullableType(inner_type).is_nullable)
def test_invalid_inner_type_union_dictionary_member(self): inner_type = IdlUnionType([IdlType(self._TEST_DICTIONARY)]) with self.assertRaises(ValueError): IdlNullableType(inner_type)
def test_valid_inner_type_union(self): inner_type = IdlUnionType([IdlType('long')]) self.assertTrue(IdlNullableType(inner_type).is_nullable)
def test_valid_inner_type_dictionary(self): inner_type = IdlType(self._TEST_DICTIONARY) self.assertTrue(IdlNullableType(inner_type).is_nullable)
def test_invalid_inner_type_any(self): inner_type = IdlType('any') with self.assertRaises(ValueError): IdlNullableType(inner_type)
def test_invalid_inner_type_promise(self): inner_type = IdlType('Promise') with self.assertRaises(ValueError): IdlNullableType(inner_type)
def test_flattened_member_types(self): # We are only testing the algorithm here, so we do create some ambiguous union types. def compare_flattened_members(actual, expected): """Compare a set of IDL types by name, as the objects are different""" actual_names = set([member.name for member in actual]) expected_names = set([member.name for member in expected]) self.assertEqual(actual_names, expected_names) idl_type = IdlUnionType([IdlType('long'), IdlType('SomeInterface')]) compare_flattened_members( idl_type.flattened_member_types, set([IdlType('long'), IdlType('SomeInterface')])) idl_type = IdlUnionType([ IdlUnionType([IdlType('ByteString'), IdlType('float')]), IdlType('boolean') ]) compare_flattened_members( idl_type.flattened_member_types, set([IdlType('float'), IdlType('boolean'), IdlType('ByteString')])) idl_type = IdlUnionType([ IdlUnionType([IdlType('ByteString'), IdlType('DOMString')]), IdlType('DOMString') ]) compare_flattened_members( idl_type.flattened_member_types, set([IdlType('DOMString'), IdlType('ByteString')])) idl_type = IdlUnionType( [IdlNullableType(IdlType('ByteString')), IdlType('byte')]) compare_flattened_members( idl_type.flattened_member_types, set([IdlType('ByteString'), IdlType('byte')])) idl_type = IdlUnionType([ IdlNullableType(IdlType('ByteString')), IdlType('byte'), IdlUnionType([IdlType('ByteString'), IdlType('float')]) ]) self.assertEqual(len(idl_type.flattened_member_types), 3) compare_flattened_members( idl_type.flattened_member_types, set([IdlType('ByteString'), IdlType('byte'), IdlType('float')])) # From the example in the spec: "the flattened member types of the union type (Node or (sequence<long> or Event) or # (XMLHttpRequest or DOMString)? or sequence<(sequence<double> or NodeList)>) are the six types Node, sequence<long>, # Event, XMLHttpRequest, DOMString and sequence<(sequence<double> or NodeList)>" idl_type = IdlUnionType([ IdlType('Node'), IdlUnionType([IdlSequenceType(IdlType('long')), IdlType('Event')]), IdlNullableType( IdlUnionType([IdlType('XMLHttpRequest'), IdlType('DOMString')])), IdlSequenceType( IdlUnionType( [IdlSequenceType(IdlType('double')), IdlType('NodeList')])) ]) self.assertEqual(len(idl_type.flattened_member_types), 6) compare_flattened_members( idl_type.flattened_member_types, set([ IdlType('Node'), IdlSequenceType(IdlType('long')), IdlType('Event'), IdlType('XMLHttpRequest'), IdlType('DOMString'), IdlSequenceType( IdlUnionType([ IdlSequenceType(IdlType('double')), IdlType('NodeList') ])) ]))
def test_invalid_inner_type_nullable(self): inner_type = IdlNullableType(IdlType('long')) with self.assertRaises(ValueError): IdlNullableType(inner_type)
def test_invalid_inner_type_union_nullable_member(self): inner_type = IdlUnionType([IdlNullableType(IdlType('long'))]) with self.assertRaises(ValueError): IdlNullableType(inner_type)