OLD | NEW |
(Empty) | |
| 1 {% from 'utilities.cpp' import declare_enum_validation_variable %} |
| 2 {% include 'copyright_block.txt' %} |
| 3 #include "{{header_filename}}" |
| 4 |
| 5 {% from 'utilities.cpp' import v8_value_to_local_cpp_value %} |
| 6 {% macro assign_and_return_if_hasinstance(member) %} |
| 7 if (V8{{member.type_name}}::hasInstance(v8Value, isolate)) { |
| 8 {{member.cpp_local_type}} cppValue = V8{{member.type_name}}::toImpl(v8::Loca
l<v8::Object>::Cast(v8Value)); |
| 9 impl.set{{member.type_name}}(cppValue); |
| 10 return; |
| 11 } |
| 12 {% endmacro %} |
| 13 {% for filename in cpp_includes %} |
| 14 #include "{{filename}}" |
| 15 {% endfor %} |
| 16 |
| 17 namespace blink { |
| 18 |
| 19 {% for container in containers %} |
| 20 {{container.cpp_class}}::{{container.cpp_class}}() |
| 21 : m_type(SpecificTypeNone) |
| 22 { |
| 23 } |
| 24 |
| 25 {% for member in container.members %} |
| 26 {{member.rvalue_cpp_type}} {{container.cpp_class}}::getAs{{member.type_name}}()
const |
| 27 { |
| 28 ASSERT(is{{member.type_name}}()); |
| 29 return m_{{member.cpp_name}}; |
| 30 } |
| 31 |
| 32 void {{container.cpp_class}}::set{{member.type_name}}({{member.rvalue_cpp_type}}
value) |
| 33 { |
| 34 ASSERT(isNull()); |
| 35 {% if member.enum_values %} |
| 36 NonThrowableExceptionState exceptionState; |
| 37 {{declare_enum_validation_variable(member.enum_values) | indent}} |
| 38 if (!isValidEnum(value, validValues, WTF_ARRAY_LENGTH(validValues), "{{membe
r.type_name}}", exceptionState)) { |
| 39 ASSERT_NOT_REACHED(); |
| 40 return; |
| 41 } |
| 42 {% endif %} |
| 43 m_{{member.cpp_name}} = value; |
| 44 m_type = {{member.specific_type_enum}}; |
| 45 } |
| 46 |
| 47 {{container.cpp_class}} {{container.cpp_class}}::from{{member.type_name}}({{memb
er.rvalue_cpp_type}} value) |
| 48 { |
| 49 {{container.cpp_class}} container; |
| 50 container.set{{member.type_name}}(value); |
| 51 return container; |
| 52 } |
| 53 |
| 54 {% endfor %} |
| 55 {{container.cpp_class}}::{{container.cpp_class}}(const {{container.cpp_class}}&)
= default; |
| 56 {{container.cpp_class}}::~{{container.cpp_class}}() = default; |
| 57 {{container.cpp_class}}& {{container.cpp_class}}::operator=(const {{container.cp
p_class}}&) = default; |
| 58 |
| 59 DEFINE_TRACE({{container.cpp_class}}) |
| 60 { |
| 61 {% for member in container.members if member.is_traceable %} |
| 62 visitor->trace(m_{{member.cpp_name}}); |
| 63 {% endfor %} |
| 64 } |
| 65 |
| 66 void V8{{container.cpp_class}}::toImpl(v8::Isolate* isolate, v8::Local<v8::Value
> v8Value, {{container.cpp_class}}& impl, UnionTypeConversionMode conversionMode
, ExceptionState& exceptionState) |
| 67 { |
| 68 if (v8Value.IsEmpty()) |
| 69 return; |
| 70 |
| 71 {# The numbers in the following comments refer to the steps described in |
| 72 http://heycam.github.io/webidl/#es-union #} |
| 73 {# 1. null or undefined #} |
| 74 if (conversionMode == UnionTypeConversionMode::Nullable && isUndefinedOrNull
(v8Value)) |
| 75 return; |
| 76 |
| 77 {# 3. Platform objects (interfaces) #} |
| 78 {% for interface in container.interface_types %} |
| 79 {{assign_and_return_if_hasinstance(interface) | indent}} |
| 80 |
| 81 {% endfor %} |
| 82 {# 8. ArrayBuffer #} |
| 83 {% if container.array_buffer_type %} |
| 84 {{assign_and_return_if_hasinstance(container.array_buffer_type) | indent}} |
| 85 |
| 86 {% endif %} |
| 87 {# 9., 10. ArrayBufferView #} |
| 88 {# FIXME: Individual typed arrays (e.g. Uint8Array) aren't supported yet. #} |
| 89 {% if container.array_buffer_view_type %} |
| 90 {{assign_and_return_if_hasinstance(container.array_buffer_view_type) | inden
t}} |
| 91 |
| 92 {% endif %} |
| 93 {% if container.dictionary_type %} |
| 94 {# 12. Dictionaries #} |
| 95 {# FIXME: This should also check "object but not Date or RegExp". Add checks |
| 96 when we implement conversions for Date and RegExp. #} |
| 97 if (isUndefinedOrNull(v8Value) || v8Value->IsObject()) { |
| 98 {{v8_value_to_local_cpp_value(container.dictionary_type) | indent(8)}} |
| 99 impl.set{{container.dictionary_type.type_name}}(cppValue); |
| 100 return; |
| 101 } |
| 102 |
| 103 {% endif %} |
| 104 {% if container.array_or_sequence_type %} |
| 105 {# 13.1, 13.2. Arrays and Sequences #} |
| 106 {# FIXME: This should also check "object but not Date or RegExp". Add checks |
| 107 when we implement conversions for Date and RegExp. #} |
| 108 {# FIXME: Should check for sequences too, not just Array instances. #} |
| 109 if (v8Value->IsArray()) { |
| 110 {{v8_value_to_local_cpp_value(container.array_or_sequence_type) | indent
(8)}} |
| 111 impl.set{{container.array_or_sequence_type.type_name}}(cppValue); |
| 112 return; |
| 113 } |
| 114 |
| 115 {% endif %} |
| 116 {# TODO(bashi): Support 13.3 Callback interface when we need it #} |
| 117 {# 13.4. Objects #} |
| 118 {% if container.object_type %} |
| 119 if (isUndefinedOrNull(v8Value) || v8Value->IsObject()) { |
| 120 {{v8_value_to_local_cpp_value(container.object_type) | indent(8)}} |
| 121 impl.set{{container.object_type.type_name}}(cppValue); |
| 122 return; |
| 123 } |
| 124 |
| 125 {% endif %} |
| 126 {# FIXME: In some cases, we can omit boolean and numeric type checks because |
| 127 we have fallback conversions. (step 17 and 18) #} |
| 128 {% if container.boolean_type %} |
| 129 {# 14. Boolean #} |
| 130 if (v8Value->IsBoolean()) { |
| 131 impl.setBoolean(v8Value.As<v8::Boolean>()->Value()); |
| 132 return; |
| 133 } |
| 134 |
| 135 {% endif %} |
| 136 {% if container.numeric_type %} |
| 137 {# 15. Number #} |
| 138 if (v8Value->IsNumber()) { |
| 139 {{v8_value_to_local_cpp_value(container.numeric_type) | indent(8)}} |
| 140 impl.set{{container.numeric_type.type_name}}(cppValue); |
| 141 return; |
| 142 } |
| 143 |
| 144 {% endif %} |
| 145 {% if container.string_type %} |
| 146 {# 16. String #} |
| 147 { |
| 148 {{v8_value_to_local_cpp_value(container.string_type) | indent(8)}} |
| 149 {% if container.string_type.enum_values %} |
| 150 {{declare_enum_validation_variable(container.string_type.enum_values) |
indent(8)}} |
| 151 if (!isValidEnum(cppValue, validValues, WTF_ARRAY_LENGTH(validValues), "
{{container.string_type.type_name}}", exceptionState)) |
| 152 return; |
| 153 {% endif %} |
| 154 impl.set{{container.string_type.type_name}}(cppValue); |
| 155 return; |
| 156 } |
| 157 |
| 158 {# 17. Number (fallback) #} |
| 159 {% elif container.numeric_type %} |
| 160 { |
| 161 {{v8_value_to_local_cpp_value(container.numeric_type) | indent(8)}} |
| 162 impl.set{{container.numeric_type.type_name}}(cppValue); |
| 163 return; |
| 164 } |
| 165 |
| 166 {# 18. Boolean (fallback) #} |
| 167 {% elif container.boolean_type %} |
| 168 { |
| 169 impl.setBoolean(v8Value->BooleanValue()); |
| 170 return; |
| 171 } |
| 172 |
| 173 {% else %} |
| 174 {# 19. TypeError #} |
| 175 exceptionState.throwTypeError("The provided value is not of type '{{containe
r.type_string}}'"); |
| 176 {% endif %} |
| 177 } |
| 178 |
| 179 v8::Local<v8::Value> toV8(const {{container.cpp_class}}& impl, v8::Local<v8::Obj
ect> creationContext, v8::Isolate* isolate) |
| 180 { |
| 181 switch (impl.m_type) { |
| 182 case {{container.cpp_class}}::SpecificTypeNone: |
| 183 {# FIXME: We might want to return undefined in some cases #} |
| 184 return v8::Null(isolate); |
| 185 {% for member in container.members %} |
| 186 case {{container.cpp_class}}::{{member.specific_type_enum}}: |
| 187 return {{member.cpp_value_to_v8_value}}; |
| 188 {% endfor %} |
| 189 default: |
| 190 ASSERT_NOT_REACHED(); |
| 191 } |
| 192 return v8::Local<v8::Value>(); |
| 193 } |
| 194 |
| 195 {{container.cpp_class}} NativeValueTraits<{{container.cpp_class}}>::nativeValue(
v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exceptionState
) |
| 196 { |
| 197 {{container.cpp_class}} impl; |
| 198 V8{{container.cpp_class}}::toImpl(isolate, value, impl, UnionTypeConversionM
ode::NotNullable, exceptionState); |
| 199 return impl; |
| 200 } |
| 201 |
| 202 {% endfor %} |
| 203 } // namespace blink |
OLD | NEW |