1use crate::attribute::ExtendedAttributeList;
2use crate::common::{Generics, Identifier, Parenthesized, Punctuated};
3use crate::term;
4use crate::Parse;
5
6pub type UnionType<'a> = Parenthesized<Punctuated<UnionMemberType<'a>, term!(or)>>;
8
9ast_types! {
10 enum Type<'a> {
12 Single(enum SingleType<'a> {
14 Any(term!(any)),
15 NonAny(NonAnyType<'a>),
16 }),
17 Union(MayBeNull<UnionType<'a>>),
18 }
19
20 enum NonAnyType<'a> {
22 Promise(PromiseType<'a>),
23 Integer(MayBeNull<IntegerType>),
24 FloatingPoint(MayBeNull<FloatingPointType>),
25 Boolean(MayBeNull<term!(boolean)>),
26 Byte(MayBeNull<term!(byte)>),
27 Octet(MayBeNull<term!(octet)>),
28 ByteString(MayBeNull<term!(ByteString)>),
29 DOMString(MayBeNull<term!(DOMString)>),
30 USVString(MayBeNull<term!(USVString)>),
31 Sequence(MayBeNull<SequenceType<'a>>),
32 Object(MayBeNull<term!(object)>),
33 Symbol(MayBeNull<term!(symbol)>),
34 Error(MayBeNull<term!(Error)>),
35 ArrayBuffer(MayBeNull<term!(ArrayBuffer)>),
36 DataView(MayBeNull<term!(DataView)>),
37 Int8Array(MayBeNull<term!(Int8Array)>),
38 Int16Array(MayBeNull<term!(Int16Array)>),
39 Int32Array(MayBeNull<term!(Int32Array)>),
40 Uint8Array(MayBeNull<term!(Uint8Array)>),
41 Uint16Array(MayBeNull<term!(Uint16Array)>),
42 Uint32Array(MayBeNull<term!(Uint32Array)>),
43 Uint8ClampedArray(MayBeNull<term!(Uint8ClampedArray)>),
44 Float32Array(MayBeNull<term!(Float32Array)>),
45 Float64Array(MayBeNull<term!(Float64Array)>),
46 ArrayBufferView(MayBeNull<term!(ArrayBufferView)>),
47 BufferSource(MayBeNull<term!(BufferSource)>),
48 FrozenArrayType(MayBeNull<FrozenArrayType<'a>>),
49 ObservableArrayType(MayBeNull<ObservableArrayType<'a>>),
50 RecordType(MayBeNull<RecordType<'a>>),
51 Identifier(MayBeNull<Identifier<'a>>),
52 }
53
54 struct SequenceType<'a> {
56 sequence: term!(sequence),
57 generics: Generics<Box<Type<'a>>>,
58 }
59
60 struct FrozenArrayType<'a> {
62 frozen_array: term!(FrozenArray),
63 generics: Generics<Box<Type<'a>>>,
64 }
65
66 struct ObservableArrayType<'a> {
68 observable_array: term!(ObservableArray),
69 generics: Generics<Box<Type<'a>>>,
70 }
71
72 #[derive(Copy)]
76 struct MayBeNull<T> where [T: Parse<'a>] {
77 type_: T,
78 q_mark: Option<term::QMark>,
79 }
80
81 struct PromiseType<'a> {
83 promise: term!(Promise),
84 generics: Generics<Box<ReturnType<'a>>>,
85 }
86
87 #[derive(Copy)]
89 enum IntegerType {
90 #[derive(Copy)]
92 LongLong(struct LongLongType {
93 unsigned: Option<term!(unsigned)>,
94 long_long: (term!(long), term!(long)),
95 }),
96 #[derive(Copy)]
98 Long(struct LongType {
99 unsigned: Option<term!(unsigned)>,
100 long: term!(long),
101 }),
102 #[derive(Copy)]
104 Short(struct ShortType {
105 unsigned: Option<term!(unsigned)>,
106 short: term!(short),
107 }),
108 }
109
110 #[derive(Copy)]
112 enum FloatingPointType {
113 #[derive(Copy)]
115 Float(struct FloatType {
116 unrestricted: Option<term!(unrestricted)>,
117 float: term!(float),
118 }),
119 #[derive(Copy)]
121 Double(struct DoubleType {
122 unrestricted: Option<term!(unrestricted)>,
123 double: term!(double),
124 }),
125 }
126
127 struct RecordType<'a> {
129 record: term!(record),
130 generics: Generics<(Box<RecordKeyType<'a>>, term!(,), Box<Type<'a>>)>,
131 }
132
133 enum RecordKeyType<'a> {
135 Byte(term!(ByteString)),
136 DOM(term!(DOMString)),
137 USV(term!(USVString)),
138 NonAny(NonAnyType<'a>),
139 }
140
141 enum UnionMemberType<'a> {
143 Single(AttributedNonAnyType<'a>),
144 Union(MayBeNull<UnionType<'a>>),
145 }
146
147 enum ConstType<'a> {
149 Integer(MayBeNull<IntegerType>),
150 FloatingPoint(MayBeNull<FloatingPointType>),
151 Boolean(MayBeNull<term!(boolean)>),
152 Byte(MayBeNull<term!(byte)>),
153 Octet(MayBeNull<term!(octet)>),
154 Identifier(MayBeNull<Identifier<'a>>),
155 }
156
157 enum ReturnType<'a> {
159 Undefined(term!(undefined)),
160 Type(Type<'a>),
161 }
162
163 struct AttributedType<'a> {
165 attributes: Option<ExtendedAttributeList<'a>>,
166 type_: Type<'a>,
167 }
168
169 struct AttributedNonAnyType<'a> {
171 attributes: Option<ExtendedAttributeList<'a>>,
172 type_: NonAnyType<'a>,
173 }
174}
175
176#[cfg(test)]
177mod test {
178 use super::*;
179
180 test!(should_parse_may_be_null { "short" =>
181 "";
182 MayBeNull<crate::types::IntegerType>;
183 q_mark.is_none();
184 });
185
186 test!(should_parse_nullable { "short?" =>
187 "";
188 MayBeNull<crate::types::IntegerType>;
189 q_mark.is_some();
190 });
191
192 test_variants!(
193 ReturnType {
194 Undefined == "undefined",
195 Type == "any",
196 }
197 );
198
199 test_variants!(
200 ConstType {
201 Integer == "short",
202 FloatingPoint == "float",
203 Boolean == "boolean",
204 Byte == "byte",
205 Octet == "octet",
206 Identifier == "name",
207 }
208 );
209
210 test_variants!(
211 NonAnyType {
212 Promise == "Promise<long>",
213 Integer == "long",
214 FloatingPoint == "float",
215 Boolean == "boolean",
216 Byte == "byte",
217 Octet == "octet",
218 ByteString == "ByteString",
219 DOMString == "DOMString",
220 USVString == "USVString",
221 Sequence == "sequence<short>",
222 Object == "object",
223 Symbol == "symbol",
224 Error == "Error",
225 ArrayBuffer == "ArrayBuffer",
226 DataView == "DataView",
227 Int8Array == "Int8Array",
228 Int16Array == "Int16Array",
229 Int32Array == "Int32Array",
230 Uint8Array == "Uint8Array",
231 Uint16Array == "Uint16Array",
232 Uint32Array == "Uint32Array",
233 Uint8ClampedArray == "Uint8ClampedArray",
234 Float32Array == "Float32Array",
235 Float64Array == "Float64Array",
236 ArrayBufferView == "ArrayBufferView",
237 BufferSource == "BufferSource",
238 FrozenArrayType == "FrozenArray<short>",
239 ObservableArrayType == "ObservableArray<short>",
240 RecordType == "record<DOMString, short>",
241 Identifier == "mango"
242 }
243 );
244
245 test_variants!(
246 UnionMemberType {
247 Single == "byte",
248 Union == "([Clamp] unsigned long or byte)"
249 }
250 );
251
252 test_variants!(
253 RecordKeyType {
254 DOM == "DOMString",
255 USV == "USVString",
256 Byte == "ByteString"
257 }
258 );
259
260 test!(should_parse_record_type { "record<DOMString, short>" =>
261 "";
262 RecordType;
263 });
264
265 test!(should_parse_record_type_alt_types { "record<u64, short>" =>
266 "";
267 RecordType;
268 });
269
270 test!(should_parse_double_type { "double" =>
271 "";
272 DoubleType;
273 });
274
275 test!(should_parse_float_type { "float" =>
276 "";
277 FloatType;
278 });
279
280 test_variants!(
281 FloatingPointType {
282 Float == "float",
283 Double == "double"
284 }
285 );
286
287 test!(should_parse_long_long_type { "long long" =>
288 "";
289 LongLongType;
290 });
291
292 test!(should_parse_long_type { "long" =>
293 "";
294 LongType;
295 });
296
297 test!(should_parse_short_type { "short" =>
298 "";
299 ShortType;
300 });
301
302 test_variants!(
303 IntegerType {
304 Short == "short",
305 Long == "long",
306 LongLong == "long long"
307 }
308 );
309
310 test!(should_parse_promise_type { "Promise<short>" =>
311 "";
312 PromiseType;
313 });
314
315 test!(should_parse_frozen_array_type { "FrozenArray<short>" =>
316 "";
317 FrozenArrayType;
318 });
319
320 test!(should_parse_observable_array_type { "ObservableArray<short>" =>
321 "";
322 ObservableArrayType;
323 });
324
325 test!(should_parse_sequence_type { "sequence<short>" =>
326 "";
327 SequenceType;
328 });
329
330 test_variants!(
331 SingleType {
332 Any == "any",
333 NonAny == "Promise<short>",
334 }
335 );
336
337 test_variants!(
338 Type {
339 Single == "short",
340 Union == "(short or float)"
341 }
342 );
343
344 test!(should_parse_attributed_type { "[Named] short" =>
345 "";
346 AttributedType;
347 attributes.is_some();
348 });
349
350 test!(should_parse_type_as_identifier { "DOMStringMap" =>
351 "";
353 crate::types::Type;
354 });
355
356 #[test]
357 fn should_parse_union_member_type_attributed_union() {
358 use crate::types::UnionMemberType;
359 let (rem, parsed) = UnionMemberType::parse("([Clamp] byte or [Named] byte)").unwrap();
360 assert_eq!(rem, "");
361 match parsed {
362 UnionMemberType::Union(MayBeNull {
363 type_:
364 Parenthesized {
365 body: Punctuated { list, .. },
366 ..
367 },
368 ..
369 }) => {
370 assert_eq!(list.len(), 2);
371
372 match list[0] {
373 UnionMemberType::Single(AttributedNonAnyType { ref attributes, .. }) => {
374 assert!(attributes.is_some());
375 }
376
377 _ => {
378 panic!("Failed to parse list[0] attributes");
379 }
380 };
381
382 match list[1] {
383 UnionMemberType::Single(AttributedNonAnyType { ref attributes, .. }) => {
384 assert!(attributes.is_some());
385 }
386
387 _ => {
388 panic!("Failed to parse list[1] attributes");
389 }
390 };
391 }
392
393 _ => {
394 panic!("Failed to parse");
395 }
396 }
397 }
398}