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 |