Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / scripts / unstable / v8_interface.py
index ed47f82..e75a97b 100644 (file)
@@ -39,15 +39,16 @@ import v8_attributes
 from v8_globals import includes
 import v8_methods
 import v8_types
-from v8_types import inherits_interface
+from v8_types import inherits_interface, is_interface_type
 import v8_utilities
-from v8_utilities import capitalize, conditional_string, cpp_name, has_extended_attribute, has_extended_attribute_value, runtime_enabled_function_name
+from v8_utilities import capitalize, conditional_string, cpp_name, has_extended_attribute_value, runtime_enabled_function_name
 
 
 INTERFACE_H_INCLUDES = set([
     'bindings/v8/V8Binding.h',
     'bindings/v8/V8DOMWrapper.h',
     'bindings/v8/WrapperTypeInfo.h',
+    'heap/Handle.h',
 ])
 INTERFACE_CPP_INCLUDES = set([
     'RuntimeEnabledFeatures.h',
@@ -57,6 +58,8 @@ INTERFACE_CPP_INCLUDES = set([
     'core/dom/ContextFeatures.h',
     'core/dom/Document.h',
     'platform/TraceEvent.h',
+    'wtf/GetPtr.h',  # FIXME: remove if can eliminate WTF::getPtr
+    'wtf/RefPtr.h',
 ])
 
 
@@ -85,17 +88,17 @@ def generate_interface(interface):
     if is_check_security:
         includes.add('bindings/v8/BindingSecurity.h')
 
+    # [MeasureAs]
+    is_measure_as = 'MeasureAs' in extended_attributes
+    if is_measure_as:
+        includes.add('core/frame/UseCounter.h')
+
     # [SetWrapperReferenceFrom]
     reachable_node_function = extended_attributes.get('SetWrapperReferenceFrom')
     if reachable_node_function:
         includes.update(['bindings/v8/V8GCController.h',
                          'core/dom/Element.h'])
 
-    # [MeasureAs]
-    is_measure_as = 'MeasureAs' in extended_attributes
-    if is_measure_as:
-        includes.add('core/frame/UseCounter.h')
-
     # [SetWrapperReferenceTo]
     set_wrapper_reference_to_list = [{
         'name': argument.name,
@@ -113,6 +116,9 @@ def generate_interface(interface):
     for special_wrap_interface in special_wrap_for:
         v8_types.add_includes_for_type(special_wrap_interface)
 
+    # [WillBeGarbageCollected]
+    is_will_be_garbage_collected = 'WillBeGarbageCollected' in extended_attributes
+
     template_contents = {
         'conditional_string': conditional_string(interface),  # [Conditional]
         'cpp_class': cpp_name(interface),
@@ -132,10 +138,15 @@ def generate_interface(interface):
         'is_document': is_document,
         'is_event_target': inherits_interface(interface.name, 'EventTarget'),
         'is_exception': interface.is_exception,
+        'is_will_be_garbage_collected': is_will_be_garbage_collected,
         'is_node': inherits_interface(interface.name, 'Node'),
         'measure_as': v8_utilities.measure_as(interface),  # [MeasureAs]
         'parent_interface': parent_interface,
+        'pass_ref_ptr': 'PassRefPtrWillBeRawPtr'
+                        if is_will_be_garbage_collected else 'PassRefPtr',
         'reachable_node_function': reachable_node_function,
+        'ref_ptr': 'RefPtrWillBeRawPtr'
+                   if is_will_be_garbage_collected else 'RefPtr',
         'runtime_enabled_function': runtime_enabled_function_name(interface),  # [RuntimeEnabled]
         'set_wrapper_reference_to_list': set_wrapper_reference_to_list,
         'special_wrap_for': special_wrap_for,
@@ -200,6 +211,12 @@ def generate_interface(interface):
     template_contents.update({
         'attributes': attributes,
         'has_accessors': any(attribute['is_expose_js_accessors'] for attribute in attributes),
+        'has_attribute_configuration': any(
+             not (attribute['is_expose_js_accessors'] or
+                  attribute['is_static'] or
+                  attribute['runtime_enabled_function'] or
+                  attribute['per_context_enabled_function'])
+             for attribute in attributes),
         'has_constructor_attributes': any(attribute['constructor_type'] for attribute in attributes),
         'has_per_context_enabled_attributes': any(attribute['per_context_enabled_function'] for attribute in attributes),
         'has_replaceable_attributes': any(attribute['is_replaceable'] for attribute in attributes),
@@ -207,7 +224,8 @@ def generate_interface(interface):
 
     # Methods
     methods = [v8_methods.generate_method(interface, method)
-               for method in interface.operations]
+               for method in interface.operations
+               if method.name]  # Skip anonymous special operations (methods)
     generate_overloads(methods)
     for method in methods:
         method['do_generate_method_configuration'] = (
@@ -225,6 +243,16 @@ def generate_interface(interface):
         'methods': methods,
     })
 
+    template_contents.update({
+        'indexed_property_getter': indexed_property_getter(interface),
+        'indexed_property_setter': indexed_property_setter(interface),
+        'indexed_property_deleter': indexed_property_deleter(interface),
+        'is_override_builtins': 'OverrideBuiltins' in extended_attributes,
+        'named_property_getter': named_property_getter(interface),
+        'named_property_setter': named_property_setter(interface),
+        'named_property_deleter': named_property_deleter(interface),
+    })
+
     return template_contents
 
 
@@ -354,6 +382,17 @@ def overload_check_expression(method, argument_count):
 
 
 def overload_check_argument(index, argument):
+    def null_or_optional_check():
+        # If undefined is passed for an optional argument, the argument should
+        # be treated as missing; otherwise undefined is not allowed.
+        if argument['is_nullable']:
+            if argument['is_optional']:
+                return 'isUndefinedOrNull(%s)'
+            return '%s->IsNull()'
+        if argument['is_optional']:
+            return '%s->IsUndefined()'
+        return None
+
     cpp_value = 'info[%s]' % index
     idl_type = argument['idl_type']
     # FIXME: proper type checking, sharing code with attributes and methods
@@ -371,11 +410,16 @@ def overload_check_argument(index, argument):
         if argument['is_nullable']:
             type_check = ' || '.join(['%s->IsNull()' % cpp_value, type_check])
         return type_check
-    if v8_types.is_interface_type(idl_type):
+    if is_interface_type(idl_type):
         # Non-wrapper types are just objects: we don't distinguish type
+        # We only allow undefined for non-wrapper types (notably Dictionary),
+        # as we need it for optional Dictionary arguments, but we don't want to
+        # change behavior of existing bindings for other types.
         type_check = '%s->IsObject()' % cpp_value
-        if argument['is_nullable']:
-            type_check = ' || '.join(['%s->IsNull()' % cpp_value, type_check])
+        added_check_template = null_or_optional_check()
+        if added_check_template:
+            type_check = ' || '.join([added_check_template % cpp_value,
+                                      type_check])
         return type_check
     return None
 
@@ -390,7 +434,12 @@ def generate_constructor(interface, constructor):
         'argument_list': constructor_argument_list(interface, constructor),
         'arguments': [constructor_argument(argument, index)
                       for index, argument in enumerate(constructor.arguments)],
-        'has_exception_state': interface.extended_attributes.get('RaisesException') == 'Constructor',  # [RaisesException=Constructor]
+        'has_exception_state':
+            # [RaisesException=Constructor]
+            interface.extended_attributes.get('RaisesException') == 'Constructor' or
+            any(argument for argument in constructor.arguments
+                if argument.idl_type == 'SerializedScriptValue' or
+                   v8_types.is_integer_type(argument.idl_type)),
         'is_constructor': True,
         'is_variadic': False,  # Required for overload resolution
         'number_of_required_arguments':
@@ -469,3 +518,201 @@ def interface_length(interface, constructors):
         return 0
     return min(constructor['number_of_required_arguments']
                for constructor in constructors)
+
+
+################################################################################
+# Special operations (methods)
+# http://heycam.github.io/webidl/#idl-special-operations
+################################################################################
+
+def property_getter(getter, cpp_arguments):
+    def is_null_expression(idl_type):
+        if v8_types.is_union_type(idl_type):
+            return ' && '.join('!result%sEnabled' % i
+                               for i, _ in
+                               enumerate(idl_type.union_member_types))
+        if idl_type == 'DOMString':
+            return 'result.isNull()'
+        if is_interface_type(idl_type):
+            return '!result'
+        return ''
+
+    idl_type = getter.idl_type
+    extended_attributes = getter.extended_attributes
+    is_raises_exception = 'RaisesException' in extended_attributes
+
+    if v8_types.is_union_type(idl_type):
+        release = [v8_types.is_interface_type(union_member_type)
+                   for union_member_type in idl_type.union_member_types]
+    else:
+        release = v8_types.is_interface_type(idl_type)
+
+    # FIXME: make more generic, so can use v8_methods.cpp_value
+    cpp_method_name = 'imp->%s' % cpp_name(getter)
+
+    if is_raises_exception:
+        cpp_arguments.append('exceptionState')
+    this_union_arguments = v8_methods.union_arguments(idl_type)
+    if this_union_arguments:
+        cpp_arguments.extend(this_union_arguments)
+
+    cpp_value = '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments))
+
+    return {
+        'cpp_type': v8_types.cpp_type(idl_type),
+        'cpp_value': cpp_value,
+        'is_custom':
+            'Custom' in extended_attributes and
+            (not extended_attributes['Custom'] or
+             has_extended_attribute_value(getter, 'Custom', 'PropertyGetter')),
+        'is_custom_property_enumerator': has_extended_attribute_value(
+            getter, 'Custom', 'PropertyEnumerator'),
+        'is_custom_property_query': has_extended_attribute_value(
+            getter, 'Custom', 'PropertyQuery'),
+        'is_enumerable': 'NotEnumerable' not in extended_attributes,
+        'is_null_expression': is_null_expression(idl_type),
+        'is_raises_exception': is_raises_exception,
+        'name': cpp_name(getter),
+        'union_arguments': v8_methods.union_arguments(idl_type),
+        'v8_set_return_value': v8_types.v8_set_return_value(idl_type, 'result', extended_attributes=extended_attributes, script_wrappable='imp', release=release),
+    }
+
+
+def property_setter(setter):
+    idl_type = setter.arguments[1].idl_type
+    extended_attributes = setter.extended_attributes
+    is_raises_exception = 'RaisesException' in extended_attributes
+    return {
+        'has_strict_type_checking':
+            'StrictTypeChecking' in extended_attributes and
+            v8_types.is_wrapper_type(idl_type),
+        'idl_type': idl_type,
+        'is_custom': 'Custom' in extended_attributes,
+        'has_exception_state': is_raises_exception or
+                               v8_types.is_integer_type(idl_type),
+        'is_raises_exception': is_raises_exception,
+        'name': cpp_name(setter),
+        'v8_value_to_local_cpp_value': v8_types.v8_value_to_local_cpp_value(
+            idl_type, extended_attributes, 'jsValue', 'propertyValue'),
+    }
+
+
+def property_deleter(deleter):
+    idl_type = deleter.idl_type
+    if idl_type != 'boolean':
+        raise Exception(
+            'Only deleters with boolean type are allowed, but type is "%s"' %
+            idl_type)
+    extended_attributes = deleter.extended_attributes
+    return {
+        'is_custom': 'Custom' in extended_attributes,
+        'is_raises_exception': 'RaisesException' in extended_attributes,
+        'name': cpp_name(deleter),
+    }
+
+
+################################################################################
+# Indexed properties
+# http://heycam.github.io/webidl/#idl-indexed-properties
+################################################################################
+
+def indexed_property_getter(interface):
+    try:
+        # Find indexed property getter, if present; has form:
+        # getter TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG1)
+        getter = next(
+            method
+            for method in interface.operations
+            if ('getter' in method.specials and
+                len(method.arguments) == 1 and
+                method.arguments[0].idl_type == 'unsigned long'))
+    except StopIteration:
+        return None
+
+    return property_getter(getter, ['index'])
+
+
+def indexed_property_setter(interface):
+    try:
+        # Find indexed property setter, if present; has form:
+        # setter RETURN_TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG1, ARG_TYPE ARG2)
+        setter = next(
+            method
+            for method in interface.operations
+            if ('setter' in method.specials and
+                len(method.arguments) == 2 and
+                method.arguments[0].idl_type == 'unsigned long'))
+    except StopIteration:
+        return None
+
+    return property_setter(setter)
+
+
+def indexed_property_deleter(interface):
+    try:
+        # Find indexed property deleter, if present; has form:
+        # deleter TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG)
+        deleter = next(
+            method
+            for method in interface.operations
+            if ('deleter' in method.specials and
+                len(method.arguments) == 1 and
+                method.arguments[0].idl_type == 'unsigned long'))
+    except StopIteration:
+        return None
+
+    return property_deleter(deleter)
+
+
+################################################################################
+# Named properties
+# http://heycam.github.io/webidl/#idl-named-properties
+################################################################################
+
+def named_property_getter(interface):
+    try:
+        # Find named property getter, if present; has form:
+        # getter TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1)
+        getter = next(
+            method
+            for method in interface.operations
+            if ('getter' in method.specials and
+                len(method.arguments) == 1 and
+                method.arguments[0].idl_type == 'DOMString'))
+    except StopIteration:
+        return None
+
+    getter.name = getter.name or 'anonymousNamedGetter'
+    return property_getter(getter, ['propertyName'])
+
+
+def named_property_setter(interface):
+    try:
+        # Find named property setter, if present; has form:
+        # setter RETURN_TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1, ARG_TYPE ARG2)
+        setter = next(
+            method
+            for method in interface.operations
+            if ('setter' in method.specials and
+                len(method.arguments) == 2 and
+                method.arguments[0].idl_type == 'DOMString'))
+    except StopIteration:
+        return None
+
+    return property_setter(setter)
+
+
+def named_property_deleter(interface):
+    try:
+        # Find named property deleter, if present; has form:
+        # deleter TYPE [OPTIONAL_IDENTIFIER](DOMString ARG)
+        deleter = next(
+            method
+            for method in interface.operations
+            if ('deleter' in method.specials and
+                len(method.arguments) == 1 and
+                method.arguments[0].idl_type == 'DOMString'))
+    except StopIteration:
+        return None
+
+    return property_deleter(deleter)