nanvm_lib/parser/
parser.rs

1use super::{
2    any_state::{AnyResult, AnyState},
3    const_state::ConstState,
4    json_state::JsonState,
5    path::{concat, split},
6    root_state::{RootState, RootStatus},
7    shared::{JsonElement, ModuleCache, ParseError, ParseResult, ParsingStatus},
8};
9use crate::{
10    common::default::default,
11    mem::manager::Manager,
12    tokenizer::{tokenize, JsonToken},
13};
14use io_trait::Io;
15
16pub struct Context<'a, M: Manager, I: Io> {
17    manager: M,
18    io: &'a I,
19    path: String,
20    module_cache: &'a mut ModuleCache<M::Dealloc>,
21}
22
23impl<'a, M: Manager, I: Io> Context<'a, M, I> {
24    pub fn new(
25        manager: M,
26        io: &'a I,
27        path: String,
28        module_cache: &'a mut ModuleCache<M::Dealloc>,
29    ) -> Self {
30        Context {
31            manager,
32            io,
33            path,
34            module_cache,
35        }
36    }
37}
38
39fn const_state_parse<M: Manager + 'static, I: Io>(
40    const_state: ConstState<M>,
41    context: &mut Context<M, I>,
42    token: JsonToken<M::Dealloc>,
43) -> JsonState<M> {
44    match token {
45        JsonToken::Semicolon => todo!(),
46        _ => {
47            let result = any_state_parse(const_state.state, context, token);
48            match result {
49                AnyResult::Continue(state) => JsonState::ParseConst(ConstState {
50                    key: const_state.key,
51                    state,
52                }),
53                AnyResult::Success(mut success) => {
54                    success.state.consts.insert(const_state.key, success.value);
55                    JsonState::ParseRoot(RootState {
56                        status: RootStatus::Initial,
57                        state: success.state,
58                        new_line: false,
59                    })
60                }
61                AnyResult::Error(error) => JsonState::Error(error),
62            }
63        }
64    }
65}
66
67fn any_state_parse_for_module<M: Manager + 'static, I: Io>(
68    any_state: AnyState<M>,
69    context: &mut Context<M, I>,
70    token: JsonToken<M::Dealloc>,
71) -> JsonState<M> {
72    let result = any_state_parse(any_state, context, token);
73    match result {
74        AnyResult::Continue(state) => JsonState::ParseModule(state),
75        AnyResult::Success(success) => JsonState::Result(ParseResult {
76            data_type: success.state.data_type,
77            any: success.value,
78        }),
79        AnyResult::Error(error) => JsonState::Error(error),
80    }
81}
82
83fn any_state_parse_import_value<M: Manager + 'static, I: Io>(
84    any_state: AnyState<M>,
85    context: &mut Context<M, I>,
86    token: JsonToken<M::Dealloc>,
87) -> AnyResult<M> {
88    match token {
89        JsonToken::String(s) => {
90            let current_path = concat(split(&context.path).0, s.as_str());
91            if let Some(any) = context.module_cache.complete.get(&current_path) {
92                return AnyResult::Continue(AnyState {
93                    status: ParsingStatus::ImportEnd,
94                    current: JsonElement::Any(any.clone()),
95                    ..any_state
96                });
97            }
98            if context.module_cache.progress.contains(&current_path) {
99                return AnyResult::Error(ParseError::CircularDependency);
100            }
101            context.module_cache.progress.insert(current_path.clone());
102            let read_result = context.io.read_to_string(current_path.as_str());
103            match read_result {
104                Ok(s) => {
105                    let tokens = tokenize(context.manager, s);
106                    let res = parse_with_tokens(context, tokens.into_iter());
107                    match res {
108                        Ok(r) => {
109                            context.module_cache.progress.remove(&current_path);
110                            context
111                                .module_cache
112                                .complete
113                                .insert(current_path, r.any.clone());
114                            AnyResult::Continue(AnyState {
115                                status: ParsingStatus::ImportEnd,
116                                current: JsonElement::Any(r.any),
117                                ..any_state
118                            })
119                        }
120                        Err(e) => AnyResult::Error(e),
121                    }
122                }
123                Err(_) => AnyResult::<M>::Error(ParseError::CannotReadFile),
124            }
125        }
126        _ => AnyResult::Error(ParseError::WrongRequireStatement),
127    }
128}
129
130fn any_state_parse<M: Manager + 'static, I: Io>(
131    any_state: AnyState<M>,
132    context: &mut Context<M, I>,
133    token: JsonToken<M::Dealloc>,
134) -> AnyResult<M> {
135    match any_state.status {
136        ParsingStatus::Initial | ParsingStatus::ObjectColon => {
137            any_state.parse_value(context.manager, token)
138        }
139        ParsingStatus::ArrayBegin => any_state.parse_array_begin(context.manager, token),
140        ParsingStatus::ArrayValue => any_state.parse_array_value(context.manager, token),
141        ParsingStatus::ArrayComma => any_state.parse_array_comma(context.manager, token),
142        ParsingStatus::ObjectBegin => any_state.parse_object_begin(context.manager, token),
143        ParsingStatus::ObjectKey => any_state.parse_object_key(token),
144        ParsingStatus::ObjectValue => any_state.parse_object_next(context.manager, token),
145        ParsingStatus::ObjectComma => any_state.parse_object_comma(context.manager, token),
146        ParsingStatus::ImportBegin => any_state.parse_import_begin(token),
147        ParsingStatus::ImportValue => any_state_parse_import_value(any_state, context, token),
148        ParsingStatus::ImportEnd => any_state.parse_import_end(token),
149    }
150}
151
152fn root_state_parse<M: Manager + 'static, I: Io>(
153    root_state: RootState<M>,
154    context: &mut Context<M, I>,
155    token: JsonToken<M::Dealloc>,
156) -> JsonState<M> {
157    let (json_state, import) = root_state.parse(context.manager, token);
158    match import {
159        None => json_state,
160        Some((id, module)) => match json_state {
161            JsonState::ParseRoot(mut root_state) => {
162                let current_path = concat(split(&context.path).0, module.as_str());
163                if let Some(any) = context.module_cache.complete.get(&current_path) {
164                    root_state.state.consts.insert(id, any.clone());
165                    return JsonState::ParseRoot(RootState {
166                        status: RootStatus::Initial,
167                        state: root_state.state,
168                        new_line: false,
169                    });
170                }
171                if context.module_cache.progress.contains(&current_path) {
172                    return JsonState::Error(ParseError::CircularDependency);
173                }
174                context.module_cache.progress.insert(current_path.clone());
175                let read_result = context.io.read_to_string(current_path.as_str());
176                match read_result {
177                    Ok(s) => {
178                        let tokens = tokenize(context.manager, s);
179                        let res = parse_with_tokens(context, tokens.into_iter());
180                        match res {
181                            Ok(r) => {
182                                context.module_cache.progress.remove(&current_path);
183                                context
184                                    .module_cache
185                                    .complete
186                                    .insert(current_path, r.any.clone());
187                                root_state.state.consts.insert(id, r.any);
188                                JsonState::ParseRoot(RootState {
189                                    status: RootStatus::Initial,
190                                    state: root_state.state,
191                                    new_line: false,
192                                })
193                            }
194                            Err(e) => JsonState::Error(e),
195                        }
196                    }
197                    Err(_) => JsonState::Error(ParseError::CannotReadFile),
198                }
199            }
200            _ => panic!("JsonState::ParseRoot expected when root_state.parse returns import"),
201        },
202    }
203}
204
205fn json_state_push<M: Manager + 'static, I: Io>(
206    json_state: JsonState<M>,
207    context: &mut Context<M, I>,
208    token: JsonToken<M::Dealloc>,
209) -> JsonState<M> {
210    if let JsonToken::NewLine = token {
211        return match json_state {
212            JsonState::ParseRoot(state) => root_state_parse(state, context, token),
213            _ => json_state,
214        };
215    }
216    match json_state {
217        JsonState::ParseRoot(state) => root_state_parse(state, context, token),
218        JsonState::Result(_) => JsonState::Error(ParseError::UnexpectedToken),
219        JsonState::ParseModule(state) => any_state_parse_for_module(state, context, token),
220        JsonState::ParseConst(state) => const_state_parse(state, context, token),
221        _ => json_state,
222    }
223}
224
225pub fn parse<M: Manager + 'static, I: Io>(
226    context: &mut Context<M, I>,
227) -> Result<ParseResult<M::Dealloc>, ParseError> {
228    context.module_cache.progress.insert(context.path.clone());
229    let read_result = context.io.read_to_string(context.path.as_str());
230    match read_result {
231        Ok(s) => {
232            let tokens = tokenize(context.manager, s);
233            parse_with_tokens(context, tokens.into_iter())
234        }
235        Err(_) => Err(ParseError::CannotReadFile),
236    }
237}
238
239pub fn parse_with_tokens<M: Manager + 'static, I: Io>(
240    context: &mut Context<M, I>,
241    iter: impl Iterator<Item = JsonToken<M::Dealloc>>,
242) -> Result<ParseResult<M::Dealloc>, ParseError> {
243    let mut state = JsonState::ParseRoot(RootState {
244        status: RootStatus::Initial,
245        state: default(),
246        new_line: true,
247    });
248    for token in iter {
249        state = json_state_push(state, context, token);
250    }
251    state.end()
252}
253
254#[cfg(test)]
255mod test {
256    use io_test::VirtualIo;
257    use io_trait::Io;
258    use wasm_bindgen_test::wasm_bindgen_test;
259
260    use crate::{
261        common::default::default,
262        js::{
263            js_array::JsArrayRef,
264            js_bigint::{from_u64, new_bigint, JsBigintRef, Sign},
265            js_object::JsObjectRef,
266            js_string::JsStringRef,
267            type_::Type,
268        },
269        mem::{global::GLOBAL, local::Local, manager::Manager},
270        tokenizer::{tokenize, ErrorType, JsonToken},
271    };
272
273    use super::super::{parser::parse, path::concat, shared::DataType};
274
275    use super::{parse_with_tokens, Context, ModuleCache, ParseError, ParseResult};
276
277    fn virtual_io() -> VirtualIo {
278        VirtualIo::new(&[])
279    }
280
281    fn create_test_context<'a, M: Manager>(
282        manager: M,
283        io: &'a VirtualIo,
284        module_cache: &'a mut ModuleCache<M::Dealloc>,
285    ) -> Context<'a, M, VirtualIo> {
286        Context::new(manager, io, default(), module_cache)
287    }
288
289    fn parse_with_virtual_io<M: Manager + 'static>(
290        manager: M,
291        iter: impl Iterator<Item = JsonToken<M::Dealloc>>,
292    ) -> Result<ParseResult<M::Dealloc>, ParseError> {
293        parse_with_tokens(
294            &mut create_test_context(manager, &virtual_io(), &mut default()),
295            iter,
296        )
297    }
298
299    fn test_global() {
300        let _ = {
301            let global = GLOBAL;
302            parse_with_tokens(
303                &mut create_test_context(global, &virtual_io(), &mut default()),
304                [].into_iter(),
305            )
306        };
307    }
308
309    #[test]
310    #[wasm_bindgen_test]
311    fn test_json() {
312        let json_str = include_str!("../../test/test-json.json");
313        let tokens = tokenize(GLOBAL, json_str.to_owned());
314        let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
315        assert!(result.is_ok());
316        assert_eq!(result.unwrap().data_type, DataType::Json);
317    }
318
319    #[test]
320    #[wasm_bindgen_test]
321    fn test_djs() {
322        let json_str = include_str!("../../test/test-djs.d.cjs");
323        let tokens = tokenize(GLOBAL, json_str.to_owned());
324        let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
325        assert!(result.is_ok());
326        assert_eq!(result.unwrap().data_type, DataType::Cjs);
327
328        let json_str = include_str!("../../test/test-djs.d.mjs");
329        let tokens = tokenize(GLOBAL, json_str.to_owned());
330        let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
331        assert!(result.is_ok());
332        assert_eq!(result.unwrap().data_type, DataType::Mjs);
333    }
334
335    #[test]
336    #[wasm_bindgen_test]
337    fn test_const() {
338        test_const_with_manager(GLOBAL);
339    }
340
341    fn test_const_with_manager<M: Manager + 'static>(manager: M) {
342        let json_str = include_str!("../../test/test-const.d.cjs");
343        let tokens = tokenize(manager, json_str.to_owned());
344        let result = parse_with_virtual_io(manager, tokens.into_iter());
345        assert!(result.is_ok());
346        let result_unwrap = result
347            .unwrap()
348            .any
349            .try_move::<JsArrayRef<M::Dealloc>>()
350            .unwrap();
351        let items = result_unwrap.items();
352        let item0 = items[0].clone();
353        assert_eq!(item0.try_move(), Ok(2.0));
354        let item1 = items[1].clone();
355        assert_eq!(item1.try_move(), Ok(2.0));
356
357        let json_str = include_str!("../../test/test-const-error.d.cjs.txt");
358        let tokens = tokenize(manager, json_str.to_owned());
359        let result = parse_with_virtual_io(manager, tokens.into_iter());
360        assert!(result.is_err());
361
362        let json_str = include_str!("../../test/test-const-error-new-line.d.cjs.txt");
363        let tokens = tokenize(manager, json_str.to_owned());
364        let result = parse_with_virtual_io(manager, tokens.into_iter());
365        assert!(result.is_err());
366        assert_eq!(result.unwrap_err(), ParseError::NewLineExpected);
367    }
368
369    #[test]
370    #[wasm_bindgen_test]
371    fn test_stack() {
372        test_stack_with_manager(GLOBAL);
373    }
374
375    fn test_stack_with_manager<M: Manager + 'static>(manager: M) {
376        let json_str = include_str!("../../test/test-stack.d.cjs");
377        let tokens = tokenize(manager, json_str.to_owned());
378        let result = parse_with_virtual_io(manager, tokens.into_iter());
379        assert!(result.is_ok());
380        let result_unwrap = result
381            .unwrap()
382            .any
383            .try_move::<JsArrayRef<M::Dealloc>>()
384            .unwrap();
385        let items = result_unwrap.items();
386        let item0 = items[0].clone();
387        let result_unwrap = item0.try_move::<JsObjectRef<M::Dealloc>>().unwrap();
388        let items = result_unwrap.items();
389        let (key0, value0) = items[0].clone();
390        let key0_items = key0.items();
391        assert_eq!(key0_items, [0x61]);
392        let result_unwrap = value0.try_move::<JsArrayRef<M::Dealloc>>().unwrap();
393        let items = result_unwrap.items();
394        let item0 = items[0].clone();
395        assert_eq!(item0.get_type(), Type::Null);
396    }
397
398    #[test]
399    #[wasm_bindgen_test]
400    fn test_import() {
401        test_import_with_manager(GLOBAL);
402    }
403
404    fn test_import_with_manager<M: Manager + 'static>(manager: M) {
405        let io: VirtualIo = VirtualIo::new(&[]);
406
407        let main = include_str!("../../test/test_import_main.d.cjs");
408        //let path = "../../test/test-import-main.d.cjs";
409        let main_path = "test_import_main.d.cjs";
410        io.write(main_path, main.as_bytes()).unwrap();
411
412        let module = include_str!("../../test/test_import_module.d.cjs");
413        let module_path = "test_import_module.d.cjs";
414        io.write(module_path, module.as_bytes()).unwrap();
415
416        let mut mc = default();
417        let mut context = Context::new(
418            manager,
419            &io,
420            concat(io.current_dir().unwrap().as_str(), main_path),
421            &mut mc,
422        );
423
424        let result = parse(&mut context);
425        assert!(result.is_ok());
426        let result_unwrap = result
427            .unwrap()
428            .any
429            .try_move::<JsArrayRef<M::Dealloc>>()
430            .unwrap();
431        let items = result_unwrap.items();
432        let item0 = items[0].clone();
433        assert_eq!(item0.try_move(), Ok(3.0));
434
435        let io: VirtualIo = VirtualIo::new(&[]);
436
437        let main = include_str!("../../test/test_import_main.d.mjs");
438        //let path = "../../test/test-import-main.d.mjs";
439        let main_path = "test_import_main.d.mjs";
440        io.write(main_path, main.as_bytes()).unwrap();
441
442        let module = include_str!("../../test/test_import_module.d.mjs");
443        let module_path = "test_import_module.d.mjs";
444        io.write(module_path, module.as_bytes()).unwrap();
445
446        let mut mc = default();
447        let mut context = Context::new(
448            manager,
449            &io,
450            concat(io.current_dir().unwrap().as_str(), main_path),
451            &mut mc,
452        );
453
454        let result = parse(&mut context);
455        assert!(result.is_ok());
456        let result_unwrap = result
457            .unwrap()
458            .any
459            .try_move::<JsArrayRef<M::Dealloc>>()
460            .unwrap();
461        let items = result_unwrap.items();
462        let item0 = items[0].clone();
463        assert_eq!(item0.try_move(), Ok(4.0));
464    }
465
466    #[test]
467    #[wasm_bindgen_test]
468    fn test_cache() {
469        test_cache_with_manager(GLOBAL);
470    }
471
472    fn test_cache_with_manager<M: Manager + 'static>(manager: M) {
473        let io: VirtualIo = VirtualIo::new(&[]);
474
475        let main = include_str!("../../test/test_cache_main.d.cjs");
476        let main_path = "test_cache_main.d.cjs";
477        io.write(main_path, main.as_bytes()).unwrap();
478
479        let module_b = include_str!("../../test/test_cache_b.d.cjs");
480        let module_b_path = "test_cache_b.d.cjs";
481        io.write(module_b_path, module_b.as_bytes()).unwrap();
482
483        let module_c = include_str!("../../test/test_cache_c.d.cjs");
484        let module_c_path = "test_cache_c.d.cjs";
485        io.write(module_c_path, module_c.as_bytes()).unwrap();
486
487        let mut mc = default();
488        let mut context = Context::new(
489            manager,
490            &io,
491            concat(io.current_dir().unwrap().as_str(), main_path),
492            &mut mc,
493        );
494
495        let result = parse(&mut context);
496        assert!(result.is_ok());
497        let result_unwrap = result
498            .unwrap()
499            .any
500            .try_move::<JsArrayRef<M::Dealloc>>()
501            .unwrap();
502        let items = result_unwrap.items();
503        let item0 = items[0].clone();
504        assert_eq!(item0.try_move(), Ok(1.0));
505        let item1 = items[1].clone();
506        assert_eq!(item1.try_move(), Ok(1.0));
507
508        let io: VirtualIo = VirtualIo::new(&[]);
509
510        let main = include_str!("../../test/test_cache_main.d.mjs");
511        let main_path = "test_cache_main.d.mjs";
512        io.write(main_path, main.as_bytes()).unwrap();
513
514        let module_b = include_str!("../../test/test_cache_b.d.mjs");
515        let module_b_path = "test_cache_b.d.mjs";
516        io.write(module_b_path, module_b.as_bytes()).unwrap();
517
518        let module_c = include_str!("../../test/test_cache_c.d.mjs");
519        let module_c_path = "test_cache_c.d.mjs";
520        io.write(module_c_path, module_c.as_bytes()).unwrap();
521
522        let mut mc = default();
523        let mut context = Context::new(
524            manager,
525            &io,
526            concat(io.current_dir().unwrap().as_str(), main_path),
527            &mut mc,
528        );
529
530        let result = parse(&mut context);
531        assert!(result.is_ok());
532        let result_unwrap = result
533            .unwrap()
534            .any
535            .try_move::<JsArrayRef<M::Dealloc>>()
536            .unwrap();
537        let items = result_unwrap.items();
538        let item0 = items[0].clone();
539        assert_eq!(item0.try_move(), Ok(2.0));
540        let item1 = items[1].clone();
541        assert_eq!(item1.try_move(), Ok(2.0));
542    }
543
544    #[test]
545    #[wasm_bindgen_test]
546    fn test_circular_error() {
547        test_circular_error_with_manager(GLOBAL);
548    }
549
550    fn test_circular_error_with_manager<M: Manager + 'static>(manager: M) {
551        let io: VirtualIo = VirtualIo::new(&[]);
552
553        let main = include_str!("../../test/test_circular_1.d.cjs.txt");
554        let main_path = "test_circular_1.d.cjs.txt";
555        io.write(main_path, main.as_bytes()).unwrap();
556
557        let module = include_str!("../../test/test_circular_2.d.cjs.txt");
558        let module_path = "test_circular_2.d.cjs.txt";
559        io.write(module_path, module.as_bytes()).unwrap();
560
561        let mut mc = default();
562        let mut context = Context::new(
563            manager,
564            &io,
565            concat(io.current_dir().unwrap().as_str(), main_path),
566            &mut mc,
567        );
568
569        let result = parse(&mut context);
570        assert!(result.is_err());
571        assert_eq!(result.unwrap_err(), ParseError::CircularDependency);
572
573        let io: VirtualIo = VirtualIo::new(&[]);
574
575        let main = include_str!("../../test/test_circular_1.d.mjs.txt");
576        let main_path = "test_circular_1.d.mjs.txt";
577        io.write(main_path, main.as_bytes()).unwrap();
578
579        let module = include_str!("../../test/test_circular_2.d.mjs.txt");
580        let module_path = "test_circular_2.d.mjs.txt";
581        io.write(module_path, module.as_bytes()).unwrap();
582
583        let mut mc = default();
584        let mut context = Context::new(
585            manager,
586            &io,
587            concat(io.current_dir().unwrap().as_str(), main_path),
588            &mut mc,
589        );
590
591        let result = parse(&mut context);
592        assert!(result.is_err());
593        assert_eq!(result.unwrap_err(), ParseError::CircularDependency);
594    }
595
596    #[test]
597    #[wasm_bindgen_test]
598    fn test_import_error() {
599        test_import_error_with_manager(GLOBAL);
600    }
601
602    fn test_import_error_with_manager<M: Manager + 'static>(manager: M) {
603        let io: VirtualIo = VirtualIo::new(&[]);
604
605        let main = include_str!("../../test/test_import_error.d.cjs.txt");
606        //let path = "../../test/test-import-main.d.cjs";
607        let main_path = "test_import_error.d.cjs.txt";
608        io.write(main_path, main.as_bytes()).unwrap();
609
610        let module = include_str!("../../test/test_import_module.d.mjs");
611        let module_path = "test_import_module.d.mjs";
612        io.write(module_path, module.as_bytes()).unwrap();
613
614        let mut mc = default();
615        let mut context = Context::new(
616            manager,
617            &io,
618            concat(io.current_dir().unwrap().as_str(), main_path),
619            &mut mc,
620        );
621
622        let result = parse(&mut context);
623        assert!(result.is_err());
624        assert_eq!(result.unwrap_err(), ParseError::UnexpectedToken);
625
626        let io: VirtualIo = VirtualIo::new(&[]);
627
628        let main = include_str!("../../test/test_import_error.d.mjs.txt");
629        //let path = "../../test/test-import-main.d.cjs";
630        let main_path = "test_import_error.d.mjs.txt";
631        io.write(main_path, main.as_bytes()).unwrap();
632
633        let module = include_str!("../../test/test_import_module.d.cjs");
634        let module_path = "test_import_module.d.cjs";
635        io.write(module_path, module.as_bytes()).unwrap();
636
637        let mut mc = default();
638        let mut context = Context::new(
639            manager,
640            &io,
641            concat(io.current_dir().unwrap().as_str(), main_path),
642            &mut mc,
643        );
644
645        let result = parse(&mut context);
646        assert!(result.is_err());
647        assert_eq!(result.unwrap_err(), ParseError::UnexpectedToken);
648    }
649
650    #[test]
651    #[wasm_bindgen_test]
652    fn test_trailing_comma() {
653        let json_str = include_str!("../../test/test-trailing-comma.d.cjs");
654        let tokens = tokenize(GLOBAL, json_str.to_owned());
655        let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
656        assert!(result.is_ok());
657    }
658
659    #[test]
660    #[wasm_bindgen_test]
661    fn test_check_sizes() {
662        {
663            let tokens = [
664                JsonToken::ObjectBegin,
665                JsonToken::String(String::from("k")),
666                JsonToken::Colon,
667                JsonToken::ObjectBegin,
668                JsonToken::ObjectEnd,
669                JsonToken::ObjectEnd,
670            ];
671            {
672                let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
673                assert!(result.is_ok());
674                let _result_unwrap = result.unwrap();
675            }
676            //assert_eq!(GLOBAL.size(), 0);
677        }
678    }
679
680    #[test]
681    #[wasm_bindgen_test]
682    fn test_check_sizes2() {
683        let local = Local::default();
684        {
685            let tokens = [
686                JsonToken::ObjectBegin,
687                JsonToken::String(String::from("k")),
688                JsonToken::Colon,
689                JsonToken::ObjectBegin,
690                JsonToken::ObjectEnd,
691                JsonToken::ObjectEnd,
692            ];
693            {
694                let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
695                assert!(result.is_ok());
696                let result_unwrap = result.unwrap().any;
697                let _result_unwrap = result_unwrap.try_move::<JsObjectRef<_>>();
698            }
699            assert_eq!(local.size(), 0);
700        }
701    }
702
703    #[test]
704    #[wasm_bindgen_test]
705    fn test_data_type() {
706        let tokens = [JsonToken::Id(String::from("null"))];
707        let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
708        assert!(result.is_ok());
709        assert_eq!(result.unwrap().data_type, DataType::Json);
710    }
711
712    #[test]
713    #[wasm_bindgen_test]
714    fn test_export_block() {
715        let tokens = [
716            JsonToken::Id(String::from("export")),
717            JsonToken::Id(String::from("default")),
718            JsonToken::Id(String::from("null")),
719        ];
720        let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
721        assert!(result.is_ok());
722        assert_eq!(result.unwrap().data_type, DataType::Mjs);
723
724        let tokens = [
725            JsonToken::Id(String::from("module")),
726            JsonToken::Dot,
727            JsonToken::Id(String::from("exports")),
728            JsonToken::Equals,
729            JsonToken::Id(String::from("null")),
730        ];
731        let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
732        assert!(result.is_ok());
733        assert_eq!(result.unwrap().data_type, DataType::Cjs);
734    }
735
736    #[test]
737    #[wasm_bindgen_test]
738    fn test_id_in_objects() {
739        let tokens = [
740            JsonToken::Id(String::from("export")),
741            JsonToken::Id(String::from("default")),
742            JsonToken::ObjectBegin,
743            JsonToken::Id(String::from("key")),
744            JsonToken::Colon,
745            JsonToken::Number(0.0),
746            JsonToken::ObjectEnd,
747        ];
748        let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
749        assert!(result.is_ok());
750        let result_unwrap = result.unwrap().any.try_move::<JsObjectRef<_>>().unwrap();
751        let items = result_unwrap.items();
752        let (key0, value0) = items[0].clone();
753        let key0_items = key0.items();
754        assert_eq!(key0_items, [0x6b, 0x65, 0x79]);
755        assert_eq!(value0.try_move(), Ok(0.0));
756
757        let tokens = [
758            JsonToken::ObjectBegin,
759            JsonToken::Id(String::from("key")),
760            JsonToken::Colon,
761            JsonToken::Number(0.0),
762            JsonToken::ObjectEnd,
763        ];
764        let result = parse_with_virtual_io(GLOBAL, tokens.into_iter());
765        assert!(result.is_err());
766    }
767
768    #[test]
769    #[wasm_bindgen_test]
770    fn test_valid_global() {
771        test_valid_with_manager(GLOBAL);
772    }
773
774    fn test_valid_with_manager<M: Manager + 'static>(manager: M) {
775        let tokens = [JsonToken::Id(String::from("null"))];
776        let result = parse_with_virtual_io(manager, tokens.into_iter());
777        assert!(result.is_ok());
778        assert_eq!(result.unwrap().any.get_type(), Type::Null);
779
780        let tokens = [JsonToken::Id(String::from("true"))];
781        let result = parse_with_virtual_io(manager, tokens.into_iter());
782        assert!(result.is_ok());
783        assert_eq!(result.unwrap().any.try_move(), Ok(true));
784
785        let tokens = [JsonToken::Id(String::from("false"))];
786        let result = parse_with_virtual_io(manager, tokens.into_iter());
787        assert!(result.is_ok());
788        assert_eq!(result.unwrap().any.try_move(), Ok(false));
789
790        let tokens = [JsonToken::Number(0.1)];
791        let result = parse_with_virtual_io(manager, tokens.into_iter());
792        assert!(result.is_ok());
793        assert_eq!(result.unwrap().any.try_move(), Ok(0.1));
794
795        let tokens = [JsonToken::String(String::from("abc"))];
796        let result = parse_with_virtual_io(manager, tokens.into_iter());
797        assert!(result.is_ok());
798        let result = result.unwrap().any.try_move::<JsStringRef<M::Dealloc>>();
799        assert!(result.is_ok());
800        let result = result.unwrap();
801        let items = result.items();
802        assert_eq!(items, [0x61, 0x62, 0x63]);
803
804        let tokens = [JsonToken::BigInt(from_u64(manager, Sign::Positive, 1))];
805        let result = parse_with_virtual_io(manager, tokens.into_iter());
806        assert!(result.is_ok());
807        let result = result.unwrap().any.try_move::<JsBigintRef<M::Dealloc>>();
808        assert!(result.is_ok());
809        let result = result.unwrap();
810        assert_eq!(result.header_len(), 1);
811        let items = result.items();
812        assert_eq!(items, [0x1]);
813
814        let tokens = [JsonToken::BigInt(new_bigint(
815            manager,
816            Sign::Negative,
817            [2, 3],
818        ))];
819        let result = parse_with_virtual_io(manager, tokens.into_iter());
820        assert!(result.is_ok());
821        let result = result.unwrap().any.try_move::<JsBigintRef<M::Dealloc>>();
822        assert!(result.is_ok());
823        let result = result.unwrap();
824        assert_eq!(result.header_len(), -2);
825        let items = result.items();
826        assert_eq!(items, [0x2, 0x3]);
827
828        let tokens = [JsonToken::ArrayBegin, JsonToken::ArrayEnd];
829        let result = parse_with_virtual_io(manager, tokens.into_iter());
830        assert!(result.is_ok());
831        let result_unwrap = result
832            .unwrap()
833            .any
834            .try_move::<JsArrayRef<M::Dealloc>>()
835            .unwrap();
836        let items = result_unwrap.items();
837        assert!(items.is_empty());
838
839        let tokens = [
840            JsonToken::ArrayBegin,
841            JsonToken::Number(1.0),
842            JsonToken::Comma,
843            JsonToken::Id(String::from("true")),
844            JsonToken::ArrayEnd,
845        ];
846        let result = parse_with_virtual_io(manager, tokens.into_iter());
847        assert!(result.is_ok());
848        let result_unwrap = result
849            .unwrap()
850            .any
851            .try_move::<JsArrayRef<M::Dealloc>>()
852            .unwrap();
853        let items = result_unwrap.items();
854        let item0 = items[0].clone();
855        assert_eq!(item0.try_move(), Ok(1.0));
856        let item1 = items[1].clone();
857        assert_eq!(item1.try_move(), Ok(true));
858
859        let tokens = [
860            JsonToken::ArrayBegin,
861            JsonToken::Number(1.0),
862            JsonToken::Comma,
863            JsonToken::Id(String::from("true")),
864            JsonToken::Comma,
865            JsonToken::ArrayEnd,
866        ];
867        let result = parse_with_virtual_io(manager, tokens.into_iter());
868        assert!(result.is_ok());
869
870        let tokens = [
871            JsonToken::ObjectBegin,
872            JsonToken::String(String::from("k1")),
873            JsonToken::Colon,
874            JsonToken::Number(1.0),
875            JsonToken::Comma,
876            JsonToken::String(String::from("k0")),
877            JsonToken::Colon,
878            JsonToken::Number(0.0),
879            JsonToken::Comma,
880            JsonToken::String(String::from("k2")),
881            JsonToken::Colon,
882            JsonToken::Number(2.0),
883            JsonToken::ObjectEnd,
884        ];
885        let result = parse_with_virtual_io(manager, tokens.into_iter());
886        assert!(result.is_ok());
887        let result_unwrap = result
888            .unwrap()
889            .any
890            .try_move::<JsObjectRef<M::Dealloc>>()
891            .unwrap();
892        let items = result_unwrap.items();
893        let (key0, value0) = items[0].clone();
894        let key0_items = key0.items();
895        assert_eq!(key0_items, [0x6b, 0x30]);
896        assert_eq!(value0.try_move(), Ok(0.0));
897        let (key1, value1) = items[1].clone();
898        let key1_items = key1.items();
899        assert_eq!(key1_items, [0x6b, 0x31]);
900        assert_eq!(value1.try_move(), Ok(1.0));
901        let (key2, value2) = items[2].clone();
902        let key2_items = key2.items();
903        assert_eq!(key2_items, [0x6b, 0x32]);
904        assert_eq!(value2.try_move(), Ok(2.0));
905
906        let tokens = [JsonToken::ObjectBegin, JsonToken::ObjectEnd];
907        let result = parse_with_virtual_io(manager, tokens.into_iter());
908        assert!(result.is_ok());
909        let result_unwrap = result
910            .unwrap()
911            .any
912            .try_move::<JsObjectRef<M::Dealloc>>()
913            .unwrap();
914        let items = result_unwrap.items();
915        assert!(items.is_empty());
916        let tokens = [
917            JsonToken::ObjectBegin,
918            JsonToken::String(String::from("k")),
919            JsonToken::Colon,
920            JsonToken::ObjectBegin,
921            JsonToken::ObjectEnd,
922            JsonToken::ObjectEnd,
923        ];
924        {
925            let result = parse_with_virtual_io(manager, tokens.into_iter());
926            assert!(result.is_ok());
927            let result_unwrap = result.unwrap();
928            let result_unwrap = result_unwrap
929                .any
930                .try_move::<JsObjectRef<M::Dealloc>>()
931                .unwrap();
932            let items = result_unwrap.items();
933            let (_, value0) = items[0].clone();
934            let value0_unwrap = value0.try_move::<JsObjectRef<M::Dealloc>>().unwrap();
935            let value0_items = value0_unwrap.items();
936            assert!(value0_items.is_empty());
937        }
938    }
939
940    #[test]
941    #[wasm_bindgen_test]
942    fn test_invalid_global() {
943        test_invalid_with_manager(GLOBAL);
944    }
945
946    fn test_invalid_with_manager<M: Manager + 'static>(manager: M) {
947        let tokens = [];
948        let result = parse_with_virtual_io(manager, tokens.into_iter());
949        assert!(result.is_err());
950
951        let tokens = [JsonToken::ErrorToken(ErrorType::InvalidNumber)];
952        let result = parse_with_virtual_io(manager, tokens.into_iter());
953        assert!(result.is_err());
954
955        let tokens = [JsonToken::ArrayBegin, JsonToken::Comma, JsonToken::ArrayEnd];
956        let result = parse_with_virtual_io(manager, tokens.into_iter());
957        assert!(result.is_err());
958
959        let tokens = [
960            JsonToken::ArrayBegin,
961            JsonToken::Number(0.0),
962            JsonToken::Number(1.0),
963            JsonToken::ArrayEnd,
964        ];
965        let result = parse_with_virtual_io(manager, tokens.into_iter());
966        assert!(result.is_err());
967
968        let tokens = [
969            JsonToken::ArrayBegin,
970            JsonToken::Number(0.0),
971            JsonToken::Comma,
972            JsonToken::Comma,
973            JsonToken::Number(1.0),
974            JsonToken::ArrayEnd,
975        ];
976        let result = parse_with_virtual_io(manager, tokens.into_iter());
977        assert!(result.is_err());
978
979        let tokens = [
980            JsonToken::ArrayBegin,
981            JsonToken::ArrayEnd,
982            JsonToken::ArrayEnd,
983        ];
984        let result = parse_with_virtual_io(manager, tokens.into_iter());
985        assert!(result.is_err());
986
987        let tokens = [JsonToken::ArrayBegin, JsonToken::String(String::default())];
988        let result = parse_with_virtual_io(manager, tokens.into_iter());
989        assert!(result.is_err());
990
991        let tokens = [
992            JsonToken::ArrayBegin,
993            JsonToken::Comma,
994            JsonToken::Number(1.0),
995            JsonToken::ArrayEnd,
996        ];
997        let result = parse_with_virtual_io(manager, tokens.into_iter());
998        assert!(result.is_err());
999
1000        let tokens = [JsonToken::ArrayBegin, JsonToken::Colon, JsonToken::ArrayEnd];
1001        let result = parse_with_virtual_io(manager, tokens.into_iter());
1002        assert!(result.is_err());
1003
1004        let tokens = [JsonToken::ArrayEnd];
1005        let result = parse_with_virtual_io(manager, tokens.into_iter());
1006        assert!(result.is_err());
1007
1008        let tokens = [
1009            JsonToken::ObjectBegin,
1010            JsonToken::Comma,
1011            JsonToken::ObjectEnd,
1012        ];
1013        let result = parse_with_virtual_io(manager, tokens.into_iter());
1014        assert!(result.is_err());
1015
1016        let tokens = [
1017            JsonToken::ObjectBegin,
1018            JsonToken::Number(0.0),
1019            JsonToken::Comma,
1020            JsonToken::Number(1.0),
1021            JsonToken::ObjectEnd,
1022        ];
1023        let result = parse_with_virtual_io(manager, tokens.into_iter());
1024        assert!(result.is_err());
1025
1026        let tokens = [
1027            JsonToken::ObjectBegin,
1028            JsonToken::String(String::from("key")),
1029            JsonToken::Number(0.0),
1030            JsonToken::ObjectEnd,
1031        ];
1032        let result = parse_with_virtual_io(manager, tokens.into_iter());
1033        assert!(result.is_err());
1034
1035        let tokens = [
1036            JsonToken::ObjectBegin,
1037            JsonToken::String(String::from("key")),
1038            JsonToken::Colon,
1039            JsonToken::Colon,
1040            JsonToken::Number(0.0),
1041            JsonToken::ObjectEnd,
1042        ];
1043        let result = parse_with_virtual_io(manager, tokens.into_iter());
1044        assert!(result.is_err());
1045
1046        let tokens = [
1047            JsonToken::ObjectBegin,
1048            JsonToken::String(String::from("key0")),
1049            JsonToken::Colon,
1050            JsonToken::Number(0.0),
1051            JsonToken::Comma,
1052            JsonToken::Comma,
1053            JsonToken::String(String::from("key1")),
1054            JsonToken::Colon,
1055            JsonToken::Number(1.0),
1056            JsonToken::ObjectEnd,
1057        ];
1058        let result = parse_with_virtual_io(manager, tokens.into_iter());
1059        assert!(result.is_err());
1060
1061        let tokens = [
1062            JsonToken::ObjectBegin,
1063            JsonToken::ObjectEnd,
1064            JsonToken::ObjectEnd,
1065        ];
1066        let result = parse_with_virtual_io(manager, tokens.into_iter());
1067        assert!(result.is_err());
1068
1069        let tokens = [
1070            JsonToken::ObjectBegin,
1071            JsonToken::String(String::from("key")),
1072            JsonToken::Colon,
1073            JsonToken::Number(0.0),
1074        ];
1075        let result = parse_with_virtual_io(manager, tokens.into_iter());
1076        assert!(result.is_err());
1077
1078        let tokens = [
1079            JsonToken::ObjectBegin,
1080            JsonToken::Comma,
1081            JsonToken::String(String::from("key")),
1082            JsonToken::Colon,
1083            JsonToken::Number(0.0),
1084            JsonToken::ObjectEnd,
1085        ];
1086        let result = parse_with_virtual_io(manager, tokens.into_iter());
1087        assert!(result.is_err());
1088
1089        let tokens = [JsonToken::ObjectEnd];
1090        let result = parse_with_virtual_io(manager, tokens.into_iter());
1091        assert!(result.is_err());
1092
1093        let tokens = [
1094            JsonToken::ArrayBegin,
1095            JsonToken::ObjectBegin,
1096            JsonToken::ArrayEnd,
1097            JsonToken::ObjectEnd,
1098        ];
1099        let result = parse_with_virtual_io(manager, tokens.into_iter());
1100        assert!(result.is_err());
1101
1102        let tokens = [
1103            JsonToken::ObjectBegin,
1104            JsonToken::ArrayBegin,
1105            JsonToken::ObjectEnd,
1106            JsonToken::ArrayEnd,
1107        ];
1108        let result = parse_with_virtual_io(manager, tokens.into_iter());
1109        assert!(result.is_err());
1110    }
1111}