Index: bindings/scripts/v8_union.py |
diff --git a/bindings/scripts/v8_union.py b/bindings/scripts/v8_union.py |
index 1b94261bc8e3a3d79a3a23879c14b89928f756d8..fa22cdbac8cdabb86993dad1181c470e81ae327e 100644 |
--- a/bindings/scripts/v8_union.py |
+++ b/bindings/scripts/v8_union.py |
@@ -25,11 +25,14 @@ UNION_CPP_INCLUDES_BLACKLIST = frozenset([ |
cpp_includes = set() |
header_forward_decls = set() |
+header_includes = set() |
def union_context(union_types, interfaces_info): |
cpp_includes.clear() |
header_forward_decls.clear() |
+ header_includes.clear() |
+ header_includes.update(UNION_H_INCLUDES) |
# For container classes we strip nullable wrappers. For example, |
# both (A or B)? and (A? or B) will become AOrB. This should be OK |
@@ -37,26 +40,21 @@ def union_context(union_types, interfaces_info): |
# distinguishing (A or B)? and (A? or B) doesn't make sense. |
container_cpp_types = set() |
union_types_for_containers = set() |
- nullable_cpp_types = set() |
for union_type in union_types: |
cpp_type = union_type.cpp_type |
if cpp_type not in container_cpp_types: |
union_types_for_containers.add(union_type) |
container_cpp_types.add(cpp_type) |
- if union_type.includes_nullable_type: |
- nullable_cpp_types.add(cpp_type) |
union_types_for_containers = sorted(union_types_for_containers, |
key=lambda union_type: union_type.cpp_type) |
- nullable_cpp_types = sorted(nullable_cpp_types) |
return { |
'containers': [container_context(union_type, interfaces_info) |
for union_type in union_types_for_containers], |
'cpp_includes': sorted(cpp_includes - UNION_CPP_INCLUDES_BLACKLIST), |
'header_forward_decls': sorted(header_forward_decls), |
- 'header_includes': sorted(UNION_H_INCLUDES), |
- 'nullable_cpp_types': nullable_cpp_types, |
+ 'header_includes': sorted(header_includes), |
} |
@@ -72,6 +70,7 @@ def container_context(union_type, interfaces_info): |
dictionary_type = None |
interface_types = [] |
numeric_type = None |
+ object_type = None |
string_type = None |
for member in union_type.member_types: |
context = member_context(member, interfaces_info) |
@@ -84,8 +83,7 @@ def container_context(union_type, interfaces_info): |
if array_buffer_view_type: |
raise Exception('%s is ambiguous.' % union_type.name) |
array_buffer_view_type = context |
- # FIXME: Remove generic Dictionary special casing. |
- elif member.is_dictionary or member.base_type == 'Dictionary': |
+ elif member.is_dictionary: |
if dictionary_type: |
raise Exception('%s is ambiguous.' % union_type.name) |
dictionary_type = context |
@@ -93,6 +91,11 @@ def container_context(union_type, interfaces_info): |
if array_or_sequence_type: |
raise Exception('%s is ambiguous.' % union_type.name) |
array_or_sequence_type = context |
+ # "Dictionary" is an object, rather than an IDL dictionary. |
+ elif member.base_type == 'Dictionary': |
+ if object_type: |
+ raise Exception('%s is ambiguous.' % union_type.name) |
+ object_type = context |
elif member.is_interface_type: |
interface_types.append(context) |
elif member is union_type.boolean_member_type: |
@@ -122,17 +125,37 @@ def container_context(union_type, interfaces_info): |
'interface_types': interface_types, |
'members': members, |
'numeric_type': numeric_type, |
+ 'object_type': object_type, |
'string_type': string_type, |
'type_string': str(union_type), |
} |
+def _update_includes_and_forward_decls(member, interface_info): |
+ if interface_info: |
+ cpp_includes.update(interface_info.get( |
+ 'dependencies_include_paths', [])) |
+ # TODO(bashi): Workaround for http://crbug.com/524424 |
+ # Avoid using forward declaration for IDL dictionaries so that they |
+ # aren't imcomplete types in UnionTypes.h. This enables an IDL |
+ # dictionary to have a union type which has an IDL dictionary. e.g. |
+ # dictionary DictA { (boolean or DictB) member; } |
+ # Note that this doesn't cover all cases. We still can't use an IDL |
+ # dictionary in a union type when the dictionary contains a union type. |
+ # e.g. |
+ # void foo((DOMString or DictA) arg); // won't compile |
+ if member.is_dictionary: |
+ header_includes.update(member.includes_for_type()) |
+ else: |
+ cpp_includes.update(member.includes_for_type()) |
+ header_forward_decls.add(member.implemented_as) |
+ else: |
+ cpp_includes.update(member.includes_for_type()) |
+ |
+ |
def member_context(member, interfaces_info): |
- cpp_includes.update(member.includes_for_type()) |
interface_info = interfaces_info.get(member.name, None) |
- if interface_info: |
- cpp_includes.update(interface_info.get('dependencies_include_paths', [])) |
- header_forward_decls.add(member.implemented_as) |
+ _update_includes_and_forward_decls(member, interface_info) |
if member.is_nullable: |
member = member.inner_type |
return { |