blob: febec81c7377d66c2be487657480e78cd4134b73 [file] [log] [blame]
{##############################################################################}
{% macro attribute_getter(cpp_class, attribute) %}
static void {{static_attribute_name(attribute, 'Getter')}}(Dart_NativeArguments args) {
{% if attribute.is_getter_raises_exception or attribute.is_call_with_execution_context %}
Dart_Handle exception = nullptr;
{% endif %}
{
{% if attribute.is_call_with_execution_context %}
ExecutionContext* context = DOMDartState::CurrentDocument();
if (!context) {
exception = ToDart("Failed to retrieve a context");
goto fail;
}
{% endif %}
{% if attribute.is_call_with_script_state %}
DartState* dart_state = DartState::Current();
DCHECK(state);
{% endif %}
{% if attribute.dart_set_return_value and not attribute.is_static %}
{{cpp_class}}* receiver = GetReceiver<{{cpp_class}}>(args);
{% else %}
// FIXME: Need receiver setup too.
{% endif %}
{% if attribute.reflect_only %}
{{generate_reflects(attribute)|indent(4)}}
{% endif %}
{{callback_return(attribute)|indent(4)}}
return;
}
{% if attribute.is_getter_raises_exception or attribute.is_call_with_execution_context %}
fail:
Dart_ThrowException(exception);
ASSERT_NOT_REACHED();
{% endif %}
}
{% endmacro %}
{##############################################################################}
{% macro callback_return(attribute) %}
{% if attribute.dart_set_return_value %}
{% if attribute.is_nullable %}
bool is_null = false;
{% endif %}
{% if attribute.is_getter_raises_exception or
attribute.is_nullable %}
ExceptionState es;
{% endif %}
{% if attribute.cached_attribute_validation_method or
attribute.is_getter_raises_exception or
attribute.is_nullable or
attribute.idl_type == 'EventHandler' %}
{{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
{% endif %}
{% if attribute.is_nullable %}
if (is_null)
return;
{% endif %}
{% if attribute.is_getter_raises_exception %}
if (es.had_exception()) {
exception = es.GetDartException(args, {{attribute.auto_scope}});
goto fail;
}
{% endif %}
{{attribute.dart_set_return_value}};
{% else %}
// FIXME: Need to convert this properly.
DART_UNIMPLEMENTED();
{% endif %}
{% endmacro %}
{##############################################################################}
{% macro attribute_setter(cpp_class, attribute) %}
static void {{static_attribute_name(attribute, 'Setter')}}(Dart_NativeArguments args)
{
{% if attribute.idl_type == "EventHandler" or not attribute.cpp_setter %}
{# TODO(terry): Need to fix properly. #}
// FIXME: proper implementation.
DART_UNIMPLEMENTED();
{% else %}
Dart_Handle exception = nullptr;
{
{{cpp_class}}* receiver = GetReceiver<{{cpp_class}}>(args);
{% if attribute.is_custom_element_callbacks %}
CustomElementCallbackScope deliveryScope;
{% endif %}
{% set attribute_name = attribute.name if not attribute.put_forwards else 'value' %}
{{attribute.local_cpp_type}} {{attribute.setter_lvalue}} = {{attribute.dart_value_to_local_cpp_value}};
if (exception)
goto fail;
{% if attribute.is_call_with_execution_context or
attribute.is_setter_call_with_execution_context %}
ExecutionContext* context = DOMDartState::CurrentDocument();
if (!context) {
exception = ToDart("Failed to retrieve a context");
goto fail;
}
{% endif %}
{% if attribute.is_call_with_script_state %}
ScriptState* state = DartUtilities::currentScriptState();
if (!state) {
exception = ToDart("Failed to retrieve a script state");
goto fail;
}
{% endif %}
{% if attribute.is_setter_raises_exception %}
ExceptionState es;
{% endif %}
{{attribute.cpp_setter}};
{% if attribute.is_setter_raises_exception %}
if (es.had_exception()) {
exception = es.GetDartException(args, {{attribute.auto_scope}});
goto fail;
}
{% endif %}
return;
}
fail:
Dart_ThrowException(exception);
ASSERT_NOT_REACHED();
{% endif %}
}
{% endmacro %}
{######################################}
{% macro generate_reflects(attribute) %}
{% set reflect_only_values = attribute.reflect_only %}
{% set reflect_missing = attribute.reflect_missing %}
{% set reflect_invalid = attribute.reflect_invalid %}
{% set reflect_empty = attribute.reflect_empty %}
{{attribute.cpp_type}} result = {{attribute.cpp_value_original}};
{# Attribute is limited to only known values: check that the attribute value is
one of those. If not, set it to the empty string.
http://www.whatwg.org/specs/web-apps/current-work/#limited-to-only-known-values #}
{% if reflect_empty %}
if (result.isNull()) {
{% if reflect_missing %}
result = "{{reflect_missing}}";
{% else %}
;
{% endif %}
} else if (result.isEmpty()) {
result = "{{reflect_empty}}";
{% else %}
if (result.isEmpty()) {
{# FIXME: should use [ReflectEmpty] instead; need to change IDL files #}
{% if reflect_missing %}
result = "{{reflect_missing}}";
{% else %}
;
{% endif %}
{% endif %}
{% for value in reflect_only_values %}
} else if (equalIgnoringCase(result, "{{value}}")) {
result = "{{value}}";
{% endfor %}
} else {
result = "{{reflect_invalid}}";
}
{% endmacro %}
{##############################################################################}
{% macro static_attribute_name(attribute, setter_or_getter) -%}
{{attribute.name}}{{setter_or_getter}}
{%- endmacro -%}
{##############################################################################}
{% macro generate_attribute_resolver_body(dart_class, class_name, attribute) %}
if (argumentCount == 1 && name == "{{attribute.native_entry_getter.resolver_string}}") {
*autoSetupScope = {{attribute.auto_scope}};
return {{dart_class}}Internal::{{static_attribute_name(attribute, 'Getter')}};
}
{# FIXME Disabling PutForwards for now #}
{# {% if not attribute.is_read_only or attribute.put_forwards %} #}
{% if not attribute.is_read_only %}
if (argumentCount == 2 && name == "{{attribute.native_entry_setter.resolver_string}}") {
*autoSetupScope = {{attribute.auto_scope}};
return {{dart_class}}Internal::{{static_attribute_name(attribute, 'Setter')}};
}
{% endif %}
{% endmacro %}
{##############################################################################}
{% macro generate_attribute_symbolizer_body(dart_class, class_name, attribute) %}
if (native_function == {{dart_class}}Internal::{{static_attribute_name(attribute, 'Getter')}}) {
return reinterpret_cast<const uint8_t*>("{{attribute.native_entry_getter.resolver_string}}");
}
{% if not attribute.is_read_only %}
if (native_function == {{dart_class}}Internal::{{static_attribute_name(attribute, 'Setter')}}) {
return reinterpret_cast<const uint8_t*>("{{attribute.native_entry_setter.resolver_string}}");
}
{% endif %}
{% endmacro %}