1use crate::parser::ast::StatementType::BreakStatement;
2use crate::parser::ast::{
3 AssignmentOperator, AssignmentPropertyData, AstBuilderValidationErrorType, BinaryOperator,
4 BlockStatementData, CatchClauseData, ClassBodyData, ClassData, DeclarationType,
5 ExpressionOrSpreadElement, ExpressionOrSuper, ExpressionPatternType, ExpressionType,
6 ExtendedNumberLiteralType, FormalParameters, ForIteratorData, FunctionBodyData,
7 FunctionBodyOrExpression, FunctionData, HasMeta, IdentifierData, JsError, JsErrorType,
8 LiteralData, LiteralType, LogicalOperator, MemberExpressionType, Meta, MethodDefinitionData,
9 MethodDefinitionKind, NumberLiteralType, PatternOrExpression, PatternType, ProgramData,
10 PropertyData, PropertyKind, StatementType, SwitchCaseData, TemplateElementData,
11 TemplateLiteralData, UnaryOperator, UpdateOperator, VariableDeclarationData,
12 VariableDeclarationKind, VariableDeclarationOrExpression, VariableDeclarationOrPattern,
13 VariableDeclaratorData,
14};
15use crate::parser::static_semantics::Semantics;
16use crate::parser::util::TAB_WIDTH;
17use pest::iterators::{Pair, Pairs};
18use pest::Parser;
19use pest_derive::Parser;
20use std::borrow::Borrow;
21use std::collections::HashMap;
22use std::rc::Rc;
23use std::time::Instant;
24
25#[derive(Parser)]
41#[grammar = "parser/js_grammar.pest"] pub struct JsParser;
43
44type JsRuleError = JsError<Rule>;
45
46fn pair_to_string(pair: Pair<Rule>, level: usize) -> Vec<String> {
47 let mut tree = vec![];
48 let span = pair.as_span();
49 let rule_name = format!(
50 "{:?} => ({},{}) #{:?}",
51 pair.as_rule(),
52 span.start(),
53 span.end(),
54 span.as_str()
55 );
56 let mut string_pads = String::with_capacity(level * TAB_WIDTH);
57 for _ in 1..level * TAB_WIDTH + 1 {
58 string_pads.push('_');
59 }
60 tree.push(format!("{}{}", string_pads, rule_name));
61 for child_pair in pair.into_inner() {
62 tree.append(pair_to_string(child_pair, level + 1).as_mut());
63 }
64 tree
65}
66
67impl JsParser {
68 pub fn parse_to_token_tree(script: &str) -> Result<String, String> {
83 let mut tree = vec![];
84 let start = Instant::now();
85 let result = Self::parse(Rule::script, script);
86 let end = Instant::now();
87 let total_time = end.saturating_duration_since(start);
88 println!("Actual parse time is {}ms", total_time.as_millis());
89
90 match result {
91 Ok(pairs) => {
92 for pair in pairs {
93 tree.push(pair_to_string(pair, 0).join("\n"));
94 }
95 }
96 Err(err) => {
97 return Err(format!("Parse error due to {:?}", err));
98 }
99 }
100 Ok(tree.join("\n"))
101 }
102
103 pub fn parse_to_ast(script: Rc<String>) -> Result<ProgramData, JsRuleError> {
119 let result = Self::parse(Rule::script, &script);
120 match result {
121 Ok(pairs) => build_ast_from_script(pairs, &script),
122 Err(err) => {
123 return Err(JsRuleError {
124 kind: JsErrorType::ParserValidation(err.clone()),
125 message: format!("Parse error due to \n{}", err),
126 });
127 }
128 }
129 }
130
131 pub fn parse_to_ast_from_str(script: &str) -> Result<ProgramData, JsRuleError> {
146 Self::parse_to_ast(Rc::new(script.to_string()))
147 }
148
149 pub fn parse_to_ast_formatted_string(script: &str) -> Result<String, JsRuleError> {
163 let result = Self::parse_to_ast_from_str(script)?;
164 Ok(result.to_formatted_string(script))
165 }
166
167 pub fn parse_numeric_string(
186 s: &String,
187 is_error_on_empty: bool,
188 ) -> Result<ExtendedNumberLiteralType, JsRuleError> {
189 let result = Self::parse(Rule::string_numeric_literal, s);
190 Ok(match result {
191 Ok(mut pairs) => {
192 if let Some(pair) = pairs.next() {
193 match pair.as_rule() {
194 Rule::str_numeric_literal => build_ast_from_str_numeric_literal(pair)?,
195 _ => return Err(get_unexpected_error("parse_numeric_string", &pair)),
196 }
197 } else {
198 if is_error_on_empty {
199 return Err(JsRuleError {
200 kind: JsErrorType::ParserGeneralError,
201 message: "Got empty string".to_string(),
202 });
203 } else {
204 ExtendedNumberLiteralType::Std(NumberLiteralType::IntegerLiteral(0))
205 }
206 }
207 }
208 Err(err) => {
209 return Err(JsRuleError {
210 kind: JsErrorType::ParserValidation(err.clone()),
211 message: format!("Parse error due to \n{}", err),
212 });
213 }
214 })
215 }
216}
217
218fn get_unexpected_error(src: &'static str, pair: &Pair<Rule>) -> JsRuleError {
219 get_unexpected_error_with_rule(src, &pair.as_rule())
220}
221
222fn get_unexpected_error_with_rule(src: &'static str, rule: &Rule) -> JsRuleError {
223 let message = format!("Unexpected state reached in the parser at \"{:?}\". This indicates internal logic error in the parser.", rule);
224 JsRuleError {
225 message,
226 kind: JsErrorType::Unexpected(src),
227 }
228}
229
230fn get_validation_error(
231 error: String,
232 kind: AstBuilderValidationErrorType,
233 pair: &Pair<Rule>,
234 script: &Rc<String>,
235) -> JsRuleError {
236 get_validation_error_with_meta(error, kind, get_meta(pair, script))
237}
238
239fn get_validation_error_with_meta(
240 error: String,
241 kind: AstBuilderValidationErrorType,
242 meta: Meta,
243) -> JsRuleError {
244 let message = format!("Parsing error encountered: {}", error);
245 JsRuleError {
246 message,
247 kind: JsErrorType::AstBuilderValidation(kind, meta),
248 }
249}
250
251fn get_meta(pair: &Pair<Rule>, script: &Rc<String>) -> Meta {
252 Meta {
253 start_index: pair.as_span().start(),
254 end_index: pair.as_span().end(),
255 script: script.clone(),
256 }
257}
258
259fn expect_inner<'a>(
262 pair: Pair<'a, Rule>,
263 context: &str,
264 script: &Rc<String>,
265) -> Result<Pair<'a, Rule>, JsRuleError> {
266 let meta = get_meta(&pair, script);
267 pair.into_inner().next().ok_or_else(|| {
268 get_validation_error_with_meta(
269 format!("Expected inner token in {}", context),
270 AstBuilderValidationErrorType::SyntaxError,
271 meta,
272 )
273 })
274}
275
276fn build_ast_from_script(
277 pairs: Pairs<Rule>,
278 script: &Rc<String>,
279) -> Result<ProgramData, JsRuleError> {
280 let mut instructions = vec![];
281 let mut end: usize = 0;
282 for pair in pairs {
283 let meta = get_meta(&pair, script);
284 if meta.end_index > end {
285 end = meta.end_index;
286 }
287 match pair.as_rule() {
288 Rule::EOI => { }
289 Rule::statement_list => {
290 let (sl, sl_s) = build_ast_from_statement_list(pair, script)?;
292 if sl_s.contains_unpaired_continue.is_true() {
293 return Err(get_validation_error_with_meta(
294 "Invalid 'continue' statement".to_string(),
295 AstBuilderValidationErrorType::SyntaxError,
296 meta,
297 ));
298 }
299 if sl_s.contains_unpaired_break.is_true() {
300 return Err(get_validation_error_with_meta(
301 "Invalid 'break' statement".to_string(),
302 AstBuilderValidationErrorType::SyntaxError,
303 meta,
304 ));
305 }
306 validate_lexically_declared_names_have_no_duplicates_and_also_not_present_in_var_declared_names(&sl_s)?;
307 instructions = sl;
310 }
311 _ => return Err(get_unexpected_error("build_ast_from_script", &pair)),
312 };
313 }
314 Ok(ProgramData {
315 meta: Meta {
316 start_index: 0,
317 end_index: end,
318 script: script.clone(),
319 },
320 body: instructions,
321 })
322}
323
324fn build_ast_from_declaration(
325 pair: Pair<Rule>,
326 script: &Rc<String>,
327) -> Result<(DeclarationType, Semantics), JsRuleError> {
328 let inner_pair = expect_inner(pair, "build_ast_from_declaration", script)?;
329 Ok(match inner_pair.as_rule() {
330 Rule::hoistable_declaration | Rule::hoistable_declaration__yield => {
331 let (h, _h_s) = build_ast_from_hoistable_declaration(inner_pair, script)?;
332 (h, Semantics::new_empty()) }
334 Rule::class_declaration | Rule::class_declaration__yield => {
335 let (c, c_s) = build_ast_from_class_declaration(inner_pair, script)?;
336 let mut s = Semantics::new_empty();
337 s.top_level_lexically_declared_names = c_s.bound_names;
338 (DeclarationType::ClassDeclaration(c), s)
339 }
340 Rule::lexical_declaration__in | Rule::lexical_declaration__in_yield => {
341 let (ld, ld_s) = build_ast_from_lexical_declaration(inner_pair, script)?;
342 let mut s = Semantics::new_empty();
343 s.top_level_lexically_declared_names = ld_s.bound_names;
344 (DeclarationType::VariableDeclaration(ld), s)
345 }
346 _ => {
347 return Err(get_unexpected_error(
348 "build_ast_from_declaration",
349 &inner_pair,
350 ))
351 }
352 })
353}
354
355fn build_ast_from_lexical_declaration(
356 pair: Pair<Rule>,
357 script: &Rc<String>,
358) -> Result<(VariableDeclarationData, Semantics), JsRuleError> {
359 let meta = get_meta(&pair, script);
360 let mut s = Semantics::new_empty();
361 let mut declarations = vec![];
362 let mut inner_iter = pair.into_inner();
363 let let_or_const_pair = inner_iter.next().unwrap();
364 let is_let = let_or_const_pair.as_str() == "let";
365 let binding_list_pair = inner_iter.next().unwrap();
366 for lexical_binding_pair in binding_list_pair.into_inner() {
367 let lexical_binding_meta = get_meta(&lexical_binding_pair, script);
368 let (l, l_s) = build_ast_from_lexical_binding_or_variable_declaration_or_binding_element(
369 lexical_binding_pair,
370 script,
371 )?;
372 if !is_let {
373 if let PatternType::PatternWhichCanBeExpression(ExpressionPatternType::Identifier(id)) =
375 l.id.borrow()
376 {
377 if l.init.is_none() {
378 return Err(get_validation_error_with_meta(
379 format!(
380 "Initializer not provided for constant declaration: {}",
381 id.name
382 ),
383 AstBuilderValidationErrorType::SyntaxError,
384 lexical_binding_meta,
385 ));
386 }
387 }
388 }
389 s.merge(l_s);
390 declarations.push(l);
391 }
392 let mut found = HashMap::new();
394 for n in &s.bound_names {
395 if n.name == "let" {
396 return Err(get_validation_error_with_meta(
397 format!("Illegal name found: {}", n),
398 AstBuilderValidationErrorType::SyntaxError,
399 n.meta.clone(),
400 ));
401 } else if found.contains_key(&n.name) {
402 return Err(get_validation_error_with_meta(
403 format!("Duplicate declaration found: {}", n),
404 AstBuilderValidationErrorType::SyntaxError,
405 n.meta.clone(),
406 ));
407 } else {
408 found.insert(n.name.clone(), true);
409 }
410 }
411 Ok((
412 VariableDeclarationData {
413 meta,
414 declarations,
415 kind: if is_let {
416 VariableDeclarationKind::Let
417 } else {
418 VariableDeclarationKind::Const
419 },
420 },
421 s,
422 ))
423}
424
425fn build_ast_from_hoistable_declaration(
426 pair: Pair<Rule>,
427 script: &Rc<String>,
428) -> Result<(DeclarationType, Semantics), JsRuleError> {
429 let inner_pair = pair.into_inner().next().unwrap();
430 Ok(match inner_pair.as_rule() {
431 Rule::generator_declaration | Rule::generator_declaration__yield => {
432 let (f, s) =
433 build_ast_from_generator_declaration_or_generator_expression(inner_pair, script)?;
434 (DeclarationType::FunctionOrGeneratorDeclaration(f), s)
435 }
436 Rule::function_declaration | Rule::function_declaration__yield => {
437 let (f, s) =
438 build_ast_from_function_declaration_or_function_expression(inner_pair, script)?;
439 (DeclarationType::FunctionOrGeneratorDeclaration(f), s)
440 }
441 _ => {
442 return Err(get_unexpected_error(
443 "build_ast_from_hoistable_declaration",
444 &inner_pair,
445 ))
446 }
447 })
448}
449
450fn build_ast_from_generator_declaration_or_generator_expression(
451 pair: Pair<Rule>,
452 script: &Rc<String>,
453) -> Result<(FunctionData, Semantics), JsRuleError> {
454 let is_generator_declaration = match pair.as_rule() {
455 Rule::generator_declaration | Rule::generator_declaration__yield => true,
456 _ => false,
457 };
458 let meta = get_meta(&pair, script);
459 let mut pair_iter = pair.into_inner();
460 let first_pair = pair_iter.next().unwrap();
461 let (f_name, mut s, formal_parameters_pair) =
462 if first_pair.as_rule() == Rule::binding_identifier {
463 let (bi, mut bi_s) = get_binding_identifier_data(first_pair, script)?;
464 if !is_generator_declaration {
465 bi_s.bound_names = vec![];
467 }
468 (Some(bi), bi_s, pair_iter.next().unwrap())
469 } else {
470 (None, Semantics::new_empty(), first_pair)
471 };
472 let (args, args_s) = build_ast_from_formal_parameters(formal_parameters_pair, script)?;
473 if args_s.contains_yield_expression.is_true() {
474 return Err(get_validation_error_with_meta(
475 "Cannot reference 'yield' in parameters".to_string(),
476 AstBuilderValidationErrorType::SyntaxError,
477 meta.clone(),
478 ));
479 }
480 if args_s.contains_super_property.is_true() {
481 return Err(get_validation_error_with_meta(
482 "Cannot invoke 'super'".to_string(),
483 AstBuilderValidationErrorType::SyntaxError,
484 meta.clone(),
485 ));
486 }
487 let function_body_pair = pair_iter.next().unwrap().into_inner().next().unwrap();
489 let (f_body, f_body_s) = build_ast_from_function_body(function_body_pair, script)?;
490 if f_body_s.contains_super_property.is_true() {
491 return Err(get_validation_error_with_meta(
492 "Cannot invoke 'super'".to_string(),
493 AstBuilderValidationErrorType::SyntaxError,
494 meta.clone(),
495 ));
496 }
497 if f_body_s.has_direct_super.is_true() {
498 return Err(get_validation_error_with_meta(
499 "Invalid reference to 'super'".to_string(),
500 AstBuilderValidationErrorType::SyntaxError,
501 meta.clone(),
502 ));
503 }
504 validate_bound_names_have_no_duplicates_and_also_not_present_in_var_declared_names_or_lexically_declared_names(&args_s.bound_names, &vec![], &f_body_s.lexically_declared_names)?;
505 let body = Box::new(f_body);
506 s.merge(args_s);
507 Ok((
509 FunctionData {
510 meta,
511 id: f_name,
512 body,
513 params: FormalParameters::new(args),
514 generator: true,
515 },
516 s,
517 ))
518}
519
520fn build_ast_from_function_declaration_or_function_expression(
521 pair: Pair<Rule>,
522 script: &Rc<String>,
523) -> Result<(FunctionData, Semantics), JsRuleError> {
524 let is_function_declaration = match pair.as_rule() {
525 Rule::function_declaration | Rule::function_declaration__yield => true,
526 _ => false,
527 };
528 let meta = get_meta(&pair, script);
529 let mut pair_iter = pair.into_inner();
530 let first_pair = pair_iter.next().unwrap();
531 let (f_name, mut s, formal_parameters_pair) =
532 if first_pair.as_rule() == Rule::binding_identifier {
533 let (bi, mut bi_s) = get_binding_identifier_data(first_pair, script)?;
534 if !is_function_declaration {
535 bi_s.bound_names = vec![];
537 }
538 (Some(bi), bi_s, pair_iter.next().unwrap())
539 } else {
540 (None, Semantics::new_empty(), first_pair)
541 };
542 let formal_parameters_meta = get_meta(&formal_parameters_pair, script);
543 let (args, args_s) = build_ast_from_formal_parameters(formal_parameters_pair, script)?;
544 if args_s.contains_super_call.is_true() || args_s.contains_super_property.is_true() {
545 return Err(get_validation_error_with_meta(
546 "Cannot invoke 'super'".to_string(),
547 AstBuilderValidationErrorType::SyntaxError,
548 formal_parameters_meta,
549 ));
550 }
551 let function_body_pair = pair_iter.next().unwrap();
552 let function_body_meta = get_meta(&function_body_pair, script);
553 let (f_body, f_body_s) = build_ast_from_function_body(function_body_pair, script)?;
554 if f_body_s.contains_super_call.is_true() || f_body_s.contains_super_property.is_true() {
555 return Err(get_validation_error_with_meta(
556 "Cannot invoke 'super'".to_string(),
557 AstBuilderValidationErrorType::SyntaxError,
558 function_body_meta,
559 ));
560 }
561 validate_bound_names_have_no_duplicates_and_also_not_present_in_var_declared_names_or_lexically_declared_names(&args_s.bound_names, &vec![], &f_body_s.lexically_declared_names,)?;
562 let body = Box::new(f_body);
563 s.merge(args_s);
564 Ok((
566 FunctionData {
567 meta,
568 id: f_name,
569 body,
570 params: FormalParameters::new(args),
571 generator: false,
572 },
573 s,
574 ))
575}
576
577fn build_ast_from_formal_parameters(
578 pair: Pair<Rule>,
579 script: &Rc<String>,
580) -> Result<(Vec<PatternType>, Semantics), JsRuleError> {
581 let mut args: Vec<PatternType> = vec![];
582 let mut s = Semantics::new_empty();
583 for param in pair.into_inner() {
584 let meta = get_meta(¶m, script);
585 args.push(match param.as_rule() {
586 Rule::function_rest_parameter | Rule::function_rest_parameter__yield => {
587 let binding_rest_element = param.into_inner().next().unwrap();
588 let binding_identifier_item = binding_rest_element.into_inner().next().unwrap();
589 let (binding_identifier, binding_identifier_s) =
590 get_binding_identifier_data(binding_identifier_item, script)?;
591 s.merge(binding_identifier_s);
592 PatternType::RestElement {
593 meta,
594 argument: Box::new(
595 ExpressionPatternType::Identifier(binding_identifier).convert_to_pattern(),
596 ),
597 }
598 }
599 Rule::formal_parameter | Rule::formal_parameter__yield => {
600 let binding_element = param.into_inner().next().unwrap();
602 let (pattern, pattern_s) = build_ast_from_binding_element(binding_element, script)?;
603 s.merge(pattern_s);
604 pattern
605 }
606 _ => {
607 return Err(get_unexpected_error(
608 "build_ast_from_formal_parameters",
609 ¶m,
610 ))
611 }
612 });
613 }
614 Ok((args, s))
615}
616
617fn build_ast_from_single_formal_parameter(
619 pair: Pair<Rule>,
620 script: &Rc<String>,
621) -> Result<(Vec<PatternType>, Semantics), JsRuleError> {
622 let mut args: Vec<PatternType> = vec![];
623 let mut s = Semantics::new_empty();
624
625 match pair.as_rule() {
626 Rule::formal_parameter | Rule::formal_parameter__yield => {
627 let binding_element = pair.into_inner().next().unwrap();
629 let (pattern, pattern_s) = build_ast_from_binding_element(binding_element, script)?;
630 s.merge(pattern_s);
631 args.push(pattern);
632 }
633 _ => {
634 return Err(get_unexpected_error(
635 "build_ast_from_single_formal_parameter",
636 &pair,
637 ))
638 }
639 }
640 Ok((args, s))
641}
642
643fn build_ast_from_generator_body(
644 pair: Pair<Rule>,
645 script: &Rc<String>,
646) -> Result<(FunctionBodyData, Semantics), JsRuleError> {
647 build_ast_from_function_body(pair.into_inner().next().unwrap(), script)
648}
649
650fn build_ast_from_function_body(
651 pair: Pair<Rule>,
652 script: &Rc<String>,
653) -> Result<(FunctionBodyData, Semantics), JsRuleError> {
654 let meta = get_meta(&pair, script);
655 let statement_list_pair = pair.into_inner().next().unwrap();
656 let statement_list_meta = get_meta(&statement_list_pair, script);
657 let (statements, statements_s) = build_ast_from_statement_list(statement_list_pair, script)?;
658 if statements_s.contains_unpaired_continue.is_true() {
659 return Err(get_validation_error_with_meta(
660 "Invalid 'continue' statement".to_string(),
661 AstBuilderValidationErrorType::SyntaxError,
662 statement_list_meta,
663 ));
664 }
665 if statements_s.contains_unpaired_break.is_true() {
666 return Err(get_validation_error_with_meta(
667 "Invalid 'break' statement".to_string(),
668 AstBuilderValidationErrorType::SyntaxError,
669 statement_list_meta,
670 ));
671 }
672 validate_lexically_declared_names_have_no_duplicates_and_also_not_present_in_var_declared_names(&statements_s)?;
673 let mut s = Semantics::new_empty();
674 s.lexically_declared_names = statements_s.top_level_lexically_declared_names;
675 s.var_declared_names = statements_s.top_level_var_declared_names;
676 Ok((
677 FunctionBodyData {
678 meta,
679 body: statements,
680 },
681 s,
682 ))
683}
684
685fn build_ast_from_statement(
686 pair: Pair<Rule>,
687 script: &Rc<String>,
688) -> Result<(StatementType, Semantics), JsRuleError> {
689 let inner_pair = pair.into_inner().next().unwrap();
690 let meta = get_meta(&inner_pair, script);
691 Ok(match inner_pair.as_rule() {
692 Rule::debugger_statement => unimplemented!(),
693 Rule::continue_statement | Rule::continue_statement__yield => {
694 let (c, _) = build_ast_from_continue_statement(inner_pair, script)?;
695 (c, Semantics::new_empty())
696 }
697 Rule::break_statement | Rule::break_statement__yield => {
698 (BreakStatement { meta }, Semantics::new_empty())
699 }
700 Rule::throw_statement | Rule::throw_statement__yield => {
701 let (t, _) = build_ast_from_throw_statement(inner_pair, script)?;
702 (t, Semantics::new_empty())
703 }
704 Rule::if_statement
705 | Rule::if_statement__yield
706 | Rule::if_statement__return
707 | Rule::if_statement__yield_return => build_ast_from_if_statement(inner_pair, script)?,
708 Rule::with_statement
709 | Rule::with_statement__yield
710 | Rule::with_statement__return
711 | Rule::with_statement__yield_return => unimplemented!(),
712 Rule::try_statement
713 | Rule::try_statement__yield
714 | Rule::try_statement__return
715 | Rule::try_statement__yield_return => build_ast_from_try_statement(inner_pair, script)?,
716 Rule::variable_statement | Rule::variable_statement__yield => {
717 build_ast_from_variable_statement(inner_pair, script)?
718 }
719 Rule::breakable_statement
720 | Rule::breakable_statement__yield
721 | Rule::breakable_statement__return
722 | Rule::breakable_statement__yield_return => {
723 build_ast_from_breakable_statement(inner_pair, script)?
724 }
725 Rule::block_statement
726 | Rule::block_statement__yield
727 | Rule::block_statement__return
728 | Rule::block_statement__yield_return => {
729 let (bsd, bsd_s) =
730 build_ast_from_block(inner_pair.into_inner().next().unwrap(), script)?;
731 (StatementType::BlockStatement(bsd), bsd_s)
732 }
733 Rule::expression_statement | Rule::expression_statement__yield => {
734 let (exp, _exp_s) =
735 build_ast_from_expression(inner_pair.into_inner().next().unwrap(), script)?;
736 (
737 StatementType::ExpressionStatement {
738 meta,
739 expression: Box::new(exp),
740 },
741 Semantics::new_empty(),
742 )
743 }
744 Rule::empty_statement => (
745 StatementType::EmptyStatement { meta },
746 Semantics::new_empty(),
747 ),
748 Rule::return_statement | Rule::return_statement__yield => {
749 let (r, _) = build_ast_from_return_statement(inner_pair, script)?;
750 (r, Semantics::new_empty())
751 }
752 _ => {
753 return Err(get_unexpected_error(
754 "build_ast_from_statement",
755 &inner_pair,
756 ))
757 }
758 })
759}
760
761fn build_ast_from_if_statement(
762 pair: Pair<Rule>,
763 script: &Rc<String>,
764) -> Result<(StatementType, Semantics), JsRuleError> {
765 let meta = get_meta(&pair, script);
766 let mut inner_iter = pair.into_inner();
767 let expression_pair = inner_iter.next().unwrap();
768 let (expression, _) = build_ast_from_expression(expression_pair, script)?;
769 let mut s = Semantics::new_empty();
770 let (statement_true, statement_true_s) =
771 build_ast_from_statement(inner_iter.next().unwrap(), script)?;
772 s.var_declared_names = statement_true_s.var_declared_names;
773 let (statement_else, _statement_else_s) = if let Some(statement_else_pair) = inner_iter.next() {
774 let (st, mut st_s) = build_ast_from_statement(statement_else_pair, script)?;
775 s.var_declared_names.append(&mut st_s.var_declared_names);
776 (Some(Box::new(st)), st_s)
777 } else {
778 (None, Semantics::new_empty())
779 };
780 Ok((
781 StatementType::IfStatement {
782 meta,
783 test: Box::new(expression),
784 consequent: Box::new(statement_true),
785 alternate: statement_else,
786 },
787 s,
788 ))
789}
790
791fn build_ast_from_throw_statement(
792 pair: Pair<Rule>,
793 script: &Rc<String>,
794) -> Result<(StatementType, Semantics), JsRuleError> {
795 let meta = get_meta(&pair, script);
796 let inner_pair = pair.into_inner().next().unwrap();
797 let (e, e_s) = build_ast_from_expression(inner_pair, script)?;
798 Ok((
799 StatementType::ThrowStatement {
800 meta,
801 argument: Box::new(e),
802 },
803 e_s,
804 ))
805}
806
807fn build_ast_from_continue_statement(
808 pair: Pair<Rule>,
809 script: &Rc<String>,
810) -> Result<(StatementType, Semantics), JsRuleError> {
811 let mut s = Semantics::new_empty();
812 s.contains_unpaired_continue.make_true();
813 Ok((
814 StatementType::ContinueStatement {
815 meta: get_meta(&pair, script),
816 },
817 s,
818 ))
819}
820
821fn build_ast_from_statement_list(
822 pair: Pair<Rule>,
823 script: &Rc<String>,
824) -> Result<(Vec<StatementType>, Semantics), JsRuleError> {
825 let _meta = get_meta(&pair, script);
826 let mut declarations = vec![];
827 let mut s = Semantics::new_empty();
828 for inner_pair in pair.into_inner() {
829 declarations.push(match inner_pair.as_rule() {
830 Rule::declaration | Rule::declaration__yield => {
831 let (d, mut d_s) = build_ast_from_declaration(inner_pair, script)?;
832 s.lexically_declared_names.append(&mut d_s.bound_names);
833 StatementType::DeclarationStatement(d)
834 }
835 Rule::statement
836 | Rule::statement__yield
837 | Rule::statement__return
838 | Rule::statement__yield_return => {
839 let (st, st_s) = build_ast_from_statement(inner_pair, script)?;
840 s.merge(st_s);
841 st
842 }
843 _ => {
844 return Err(get_unexpected_error(
845 "build_ast_from_statement_list",
846 &inner_pair,
847 ))
848 }
849 });
850 }
851 Ok((declarations, s))
852}
853
854fn validate_lexically_declared_names_have_no_duplicates_and_also_not_present_in_var_declared_names(
855 s: &Semantics,
856) -> Result<(), JsRuleError> {
857 let mut found = HashMap::new();
859 for n in &s.lexically_declared_names {
860 if found.contains_key(&n.name) || s.var_declared_names.contains(n) {
861 return Err(get_validation_error_with_meta(
862 format!("Duplicate declaration found: {}", n),
863 AstBuilderValidationErrorType::SyntaxError,
864 n.meta.clone(),
865 ));
866 } else {
867 found.insert(n.name.clone(), true);
868 }
869 }
870 Ok(())
871}
872
873fn validate_bound_names_have_no_duplicates_and_also_not_present_in_var_declared_names_or_lexically_declared_names(
874 bound_names: &Vec<IdentifierData>,
875 var_declared_names: &Vec<IdentifierData>,
876 lexically_declared_names: &Vec<IdentifierData>,
877) -> Result<(), JsRuleError> {
878 let mut found = HashMap::new();
880 for n in bound_names {
881 if found.contains_key(&n.name)
882 || var_declared_names.contains(n)
883 || lexically_declared_names.contains(n)
884 {
885 return Err(get_validation_error_with_meta(
886 format!("Duplicate declaration found: {}", n),
887 AstBuilderValidationErrorType::SyntaxError,
888 n.meta.clone(),
889 ));
890 } else {
891 found.insert(n.name.clone(), true);
892 }
893 }
894 Ok(())
895}
896
897fn build_ast_from_block(
898 pair: Pair<Rule>,
899 script: &Rc<String>,
900) -> Result<(BlockStatementData, Semantics), JsRuleError> {
901 let meta = get_meta(&pair, script);
902 let (declarations, s) = if let Some(inner_pair) = pair.into_inner().next() {
903 build_ast_from_statement_list(inner_pair, script)?
904 } else {
905 (vec![], Semantics::new_empty())
906 };
907 validate_lexically_declared_names_have_no_duplicates_and_also_not_present_in_var_declared_names(&s)?;
908 Ok((
909 BlockStatementData {
910 meta,
911 body: declarations,
912 },
913 s,
914 ))
915}
916
917fn build_ast_from_breakable_statement(
918 pair: Pair<Rule>,
919 script: &Rc<String>,
920) -> Result<(StatementType, Semantics), JsRuleError> {
921 let inner_pair = pair.into_inner().next().unwrap();
922 Ok(
923 if inner_pair.as_rule() == Rule::iteration_statement
924 || inner_pair.as_rule() == Rule::iteration_statement__yield
925 || inner_pair.as_rule() == Rule::iteration_statement__return
926 || inner_pair.as_rule() == Rule::iteration_statement__yield_return
927 {
928 build_ast_from_iteration_statement(inner_pair, script)?
929 } else {
930 build_ast_from_switch_statement(inner_pair, script)?
931 },
932 )
933}
934
935fn build_ast_from_iteration_statement(
936 pair: Pair<Rule>,
937 script: &Rc<String>,
938) -> Result<(StatementType, Semantics), JsRuleError> {
939 let tag = pair.as_str().splitn(2, ' ').next().unwrap();
940 Ok(match tag {
941 "do" => build_ast_for_breakable_statement_do(pair, script)?,
942 "while" => build_ast_for_breakable_statement_while(pair, script)?,
943 "for" => build_ast_for_breakable_statement_for(pair, script)?,
944 _ => {
945 return Err(get_unexpected_error(
946 "build_ast_from_iteration_statement",
947 &pair,
948 ))
949 }
950 })
951}
952
953fn build_ast_for_breakable_statement_do(
954 pair: Pair<Rule>,
955 script: &Rc<String>,
956) -> Result<(StatementType, Semantics), JsRuleError> {
957 let meta = get_meta(&pair, script);
958 let mut inner_iter = pair.into_inner();
959 let statement_pair = inner_iter.next().unwrap();
960 let test_expression_pair = inner_iter.next().unwrap();
961 let mut s = Semantics::new_empty();
962 let (e, _) = build_ast_from_expression(test_expression_pair, script)?;
963 let (st, st_s) = build_ast_from_statement(statement_pair, script)?;
964 s.var_declared_names = st_s.var_declared_names;
965 Ok((
966 StatementType::DoWhileStatement {
967 meta,
968 test: Box::new(e),
969 body: Box::new(st),
970 },
971 s,
972 ))
973}
974
975fn build_ast_for_breakable_statement_while(
976 pair: Pair<Rule>,
977 script: &Rc<String>,
978) -> Result<(StatementType, Semantics), JsRuleError> {
979 let meta = get_meta(&pair, script);
980 let mut inner_iter = pair.into_inner();
981 let test_expression_pair = inner_iter.next().unwrap();
982 let statement_pair = inner_iter.next().unwrap();
983 let mut s = Semantics::new_empty();
984 let (e, _) = build_ast_from_expression(test_expression_pair, script)?;
985 let (st, st_s) = build_ast_from_statement(statement_pair, script)?;
986 s.var_declared_names = st_s.var_declared_names;
987 Ok((
988 StatementType::WhileStatement {
989 meta,
990 test: Box::new(e),
991 body: Box::new(st),
992 },
993 s,
994 ))
995}
996
997fn build_ast_for_breakable_statement_for(
998 pair: Pair<Rule>,
999 script: &Rc<String>,
1000) -> Result<(StatementType, Semantics), JsRuleError> {
1001 let meta = get_meta(&pair, script);
1002 let mut inner_iter = pair.into_inner();
1003 let first_pair = inner_iter.next().unwrap();
1004 let mut s = Semantics::new_empty();
1005 Ok(match first_pair.as_rule() {
1006 Rule::left_hand_side_expression
1007 | Rule::left_hand_side_expression__yield
1008 | Rule::for_binding
1009 | Rule::for_binding__yield
1010 | Rule::for_declaration
1011 | Rule::for_declaration__yield => {
1012 let in_of_left = match first_pair.as_rule() {
1014 Rule::left_hand_side_expression | Rule::left_hand_side_expression__yield => {
1015 let (exp, exp_s) =
1016 build_ast_from_left_hand_side_expression(first_pair, script)?;
1017 let m = Box::new(convert_lhs_expression_to_pattern_for_assignment_operation(
1018 exp,
1019 Some(&exp_s),
1020 )?);
1021 VariableDeclarationOrPattern::Pattern(m)
1022 }
1023 Rule::for_binding | Rule::for_binding__yield => {
1024 let meta = get_meta(&first_pair, script);
1025 let meta2 = meta.clone();
1026 let (b, mut b_s) = build_ast_from_for_binding(first_pair, script)?;
1027 s.var_declared_names.append(&mut b_s.bound_names);
1028
1029 VariableDeclarationOrPattern::VariableDeclaration(VariableDeclarationData {
1030 meta,
1031 declarations: vec![VariableDeclaratorData {
1032 meta: meta2,
1033 id: Box::new(b),
1034 init: None,
1035 }],
1036 kind: VariableDeclarationKind::Var,
1037 })
1038 }
1039 Rule::for_declaration | Rule::for_declaration__yield => {
1040 let (d, d_s) = build_ast_from_for_declaration(first_pair, script)?;
1041 let mut found = HashMap::new();
1042 for bn in &d_s.bound_names {
1043 if bn.name == "let" {
1044 return Err(get_validation_error_with_meta(
1045 "Illegal name: let".to_string(),
1046 AstBuilderValidationErrorType::SyntaxError,
1047 bn.meta.clone(),
1048 ));
1049 } else if found.contains_key(&bn.name) {
1050 return Err(get_validation_error_with_meta(
1051 format!("Duplicate declaration present: {}", bn),
1052 AstBuilderValidationErrorType::SyntaxError,
1053 bn.meta.clone(),
1054 ));
1055 } else if d_s.var_declared_names.contains(bn) {
1056 return Err(get_validation_error_with_meta(
1057 format!("Duplicate declaration present: {}", bn),
1058 AstBuilderValidationErrorType::SyntaxError,
1059 bn.meta.clone(),
1060 ));
1061 }
1062 found.insert(bn.name.clone(), true);
1063 }
1064 VariableDeclarationOrPattern::VariableDeclaration(d)
1065 }
1066 _ => {
1067 return Err(get_unexpected_error(
1068 "build_ast_for_breakable_statement_for:2",
1069 &first_pair,
1070 ))
1071 }
1072 };
1073 let second_pair = inner_iter.next().unwrap();
1074 let ((in_of_right, _in_of_right_s), is_for_of) = match second_pair.as_rule() {
1075 Rule::assignment_expression__in | Rule::assignment_expression__in_yield => (
1076 build_ast_from_assignment_expression(second_pair, script)?,
1077 true,
1078 ),
1079 _ => (build_ast_from_expression(second_pair, script)?, false),
1080 };
1081 let (statement, mut statement_s) =
1082 build_ast_from_statement(inner_iter.next().unwrap(), script)?;
1083 let node = ForIteratorData {
1084 meta,
1085 left: in_of_left,
1086 right: Box::new(in_of_right),
1087 body: Box::new(statement),
1088 };
1089 s.var_declared_names
1090 .append(&mut statement_s.var_declared_names);
1091 (
1092 if is_for_of {
1093 StatementType::ForOfStatement(node)
1094 } else {
1095 StatementType::ForInStatement(node)
1096 },
1097 s,
1098 )
1099 }
1100 _ => {
1101 let mut lexical_bound_names = HashMap::new();
1103 let init = match first_pair.as_rule() {
1104 Rule::lexical_declaration | Rule::lexical_declaration__yield => {
1105 let last_char = first_pair.as_str().trim_end().chars().last().unwrap();
1107 if last_char != ';' {
1108 return Err(get_validation_error(
1109 format!(
1110 "Was expecting semi-colon at the end, but got '{}'.",
1111 last_char
1112 ),
1113 AstBuilderValidationErrorType::SyntaxError,
1114 &first_pair,
1115 script,
1116 ));
1117 } else {
1118 let (d, d_s) = build_ast_from_lexical_declaration(first_pair, script)?;
1119 for n in &d_s.bound_names {
1120 lexical_bound_names.insert(n.name.clone(), true);
1121 }
1122 Some(VariableDeclarationOrExpression::VariableDeclaration(d))
1123 }
1124 }
1125 Rule::variable_declaration_list | Rule::variable_declaration_list__yield => {
1126 let meta = get_meta(&first_pair, script);
1127 let (declarations, mut declarations_s) =
1128 build_ast_from_variable_declaration_list(first_pair, script)?;
1129 s.var_declared_names.append(&mut declarations_s.bound_names);
1130
1131 if declarations.is_empty() {
1132 None
1133 } else {
1134 Some(VariableDeclarationOrExpression::VariableDeclaration(
1135 VariableDeclarationData {
1136 meta,
1137 declarations,
1138 kind: VariableDeclarationKind::Var,
1139 },
1140 ))
1141 }
1142 }
1143 Rule::init_expression | Rule::init_expression__yield => {
1144 if let Some(inner_pair) = first_pair.into_inner().next() {
1145 let (e, _e_s) = build_ast_from_expression(inner_pair, script)?;
1146 Some(VariableDeclarationOrExpression::Expression(Box::new(e)))
1147 } else {
1148 None
1149 }
1150 }
1151 _ => {
1152 return Err(get_unexpected_error(
1153 "build_ast_for_breakable_statement_for:2",
1154 &first_pair,
1155 ))
1156 }
1157 };
1158 let test_pair = inner_iter.next().unwrap();
1159 let (test, _test_s) = if let Some(test_expression_pair) = test_pair.into_inner().next() {
1160 let (e, e_s) = build_ast_from_expression(test_expression_pair, script)?;
1161 (Some(Box::new(e)), e_s)
1162 } else {
1163 (None, Semantics::new_empty())
1164 };
1165 let update_pair = inner_iter.next().unwrap();
1166 let (update, _update_s) =
1167 if let Some(update_expression_pair) = update_pair.into_inner().next() {
1168 let (e, e_s) = build_ast_from_expression(update_expression_pair, script)?;
1169 (Some(Box::new(e)), e_s)
1170 } else {
1171 (None, Semantics::new_empty())
1172 };
1173 let st_pair = inner_iter.next().unwrap();
1174 let (st, mut st_s) = build_ast_from_statement(st_pair, script)?;
1175 for n in &st_s.bound_names {
1176 if lexical_bound_names.contains_key(&n.name) {
1177 return Err(get_validation_error_with_meta(
1178 format!("Duplicate declaration found: {}", n),
1179 AstBuilderValidationErrorType::SyntaxError,
1180 n.meta.clone(),
1181 ));
1182 }
1183 }
1184 s.var_declared_names.append(&mut st_s.var_declared_names);
1185 (
1186 StatementType::ForStatement {
1187 meta,
1188 init,
1189 test,
1190 update,
1191 body: Box::new(st),
1192 },
1193 s,
1194 )
1195 }
1196 })
1197}
1198
1199fn build_ast_from_binding_pattern(
1200 pair: Pair<Rule>,
1201 script: &Rc<String>,
1202) -> Result<(PatternType, Semantics), JsRuleError> {
1203 let meta = get_meta(&pair, script);
1204 let mut binding_properties = vec![];
1205 let mut s = Semantics::new_empty();
1206 let inner_pair = pair.into_inner().next().unwrap();
1207 Ok(match inner_pair.as_rule() {
1208 Rule::object_binding_pattern | Rule::object_binding_pattern__yield => {
1209 let binding_pattern_inner_iter = inner_pair.into_inner();
1210 for binding_property_pair in binding_pattern_inner_iter {
1211 let (b, b_s) = build_ast_from_binding_property(binding_property_pair, script)?;
1212 s.merge(b_s);
1213 binding_properties.push(b);
1214 }
1215 (
1216 PatternType::ObjectPattern {
1217 meta,
1218 properties: binding_properties,
1219 },
1220 s,
1221 )
1222 }
1223 Rule::array_binding_pattern | Rule::array_binding_pattern__yield => {
1224 let mut elements: Vec<Option<Box<PatternType>>> = vec![];
1225 for item_pair in inner_pair.into_inner() {
1226 match item_pair.as_rule() {
1227 Rule::elision => {
1228 for _ in 0..(item_pair.as_str().matches(',').count()) {
1230 elements.push(None);
1231 }
1232 }
1233 Rule::binding_element | Rule::binding_element__yield => {
1234 let (element, element_s) =
1235 build_ast_from_binding_element(item_pair, script)?;
1236 s.merge(element_s);
1237 elements.push(Some(Box::new(element)));
1238 }
1239 Rule::binding_rest_element | Rule::binding_rest_element__yield => {
1240 let rest_meta = get_meta(&item_pair, script);
1241 let binding_id_pair = item_pair.into_inner().next().ok_or_else(|| {
1242 get_validation_error_with_meta(
1243 "Expected binding identifier in rest element".to_string(),
1244 AstBuilderValidationErrorType::SyntaxError,
1245 rest_meta.clone(),
1246 )
1247 })?;
1248 let (id, id_s) = get_binding_identifier_data(binding_id_pair, script)?;
1249 s.merge(id_s);
1250 elements.push(Some(Box::new(PatternType::RestElement {
1251 meta: rest_meta,
1252 argument: Box::new(
1253 ExpressionPatternType::Identifier(id).convert_to_pattern(),
1254 ),
1255 })));
1256 }
1257 _ => {
1258 return Err(get_unexpected_error(
1259 "build_ast_from_binding_pattern:array",
1260 &item_pair,
1261 ))
1262 }
1263 }
1264 }
1265 (PatternType::ArrayPattern { meta, elements }, s)
1266 }
1267 _ => {
1268 return Err(get_unexpected_error(
1269 "build_ast_from_binding_pattern",
1270 &inner_pair,
1271 ))
1272 }
1273 })
1274}
1275
1276fn build_ast_from_binding_element(
1278 pair: Pair<Rule>,
1279 script: &Rc<String>,
1280) -> Result<(PatternType, Semantics), JsRuleError> {
1281 let meta = get_meta(&pair, script);
1282 let mut inner_iter = pair.into_inner();
1283 let inner_pair = inner_iter.next().ok_or_else(|| {
1284 get_validation_error_with_meta(
1285 "Expected binding element content".to_string(),
1286 AstBuilderValidationErrorType::SyntaxError,
1287 meta.clone(),
1288 )
1289 })?;
1290
1291 match inner_pair.as_rule() {
1292 Rule::single_name_binding | Rule::single_name_binding__yield => {
1293 let (var_decl, s) = build_ast_from_single_name_binding(inner_pair, script)?;
1294 let VariableDeclaratorData { meta, id, init } = var_decl;
1295 if let Some(init_expr) = init {
1296 Ok((
1298 PatternType::AssignmentPattern {
1299 meta,
1300 left: id,
1301 right: init_expr,
1302 },
1303 s,
1304 ))
1305 } else {
1306 Ok((*id, s))
1308 }
1309 }
1310 Rule::binding_pattern | Rule::binding_pattern__yield => {
1311 let (pattern, s) = build_ast_from_binding_pattern(inner_pair, script)?;
1312 if let Some(init_pair) = inner_iter.next() {
1314 let init_inner = init_pair.into_inner().next().ok_or_else(|| {
1315 get_validation_error_with_meta(
1316 "Expected initializer expression".to_string(),
1317 AstBuilderValidationErrorType::SyntaxError,
1318 meta.clone(),
1319 )
1320 })?;
1321 let (init_expr, _init_s) =
1322 build_ast_from_assignment_expression(init_inner, script)?;
1323 Ok((
1324 PatternType::AssignmentPattern {
1325 meta,
1326 left: Box::new(pattern),
1327 right: Box::new(init_expr),
1328 },
1329 s,
1330 ))
1331 } else {
1332 Ok((pattern, s))
1333 }
1334 }
1335 _ => Err(get_unexpected_error(
1336 "build_ast_from_binding_element",
1337 &inner_pair,
1338 )),
1339 }
1340}
1341
1342fn build_ast_from_binding_property(
1343 pair: Pair<Rule>,
1344 script: &Rc<String>,
1345) -> Result<(AssignmentPropertyData, Semantics), JsRuleError> {
1346 let mut inner_iter = pair.into_inner();
1347 let inner_pair = inner_iter.next().unwrap();
1348 let meta = get_meta(&inner_pair, script);
1349 if inner_pair.as_rule() == Rule::single_name_binding
1350 || inner_pair.as_rule() == Rule::single_name_binding__yield
1351 {
1352 let inner_pair_rule = &inner_pair.as_rule();
1353 let (VariableDeclaratorData { meta, id, init }, s) =
1354 build_ast_from_single_name_binding(inner_pair, script)?;
1355 let id = if let PatternType::PatternWhichCanBeExpression(
1356 ExpressionPatternType::Identifier(id),
1357 ) = *id
1358 {
1359 id
1360 } else {
1361 return Err(get_unexpected_error_with_rule(
1362 "build_ast_from_binding_property:1",
1363 inner_pair_rule,
1364 ));
1365 };
1366 let meta2 = meta.clone();
1367 let id2 = id.clone();
1368 let value = if let Some(init) = init {
1369 PatternType::AssignmentPattern {
1370 meta,
1371 left: Box::new(ExpressionPatternType::Identifier(id).convert_to_pattern()),
1372 right: init,
1373 }
1374 } else {
1375 ExpressionPatternType::Identifier(id).convert_to_pattern()
1376 };
1377 Ok((
1378 AssignmentPropertyData::new_with_identifier_key(meta2, id2, value, true),
1379 s,
1380 ))
1381 } else if inner_pair.as_rule() == Rule::property_name
1382 || inner_pair.as_rule() == Rule::property_name__yield
1383 {
1384 let (key, _key_s) = build_ast_from_property_name(inner_pair, script)?;
1385 let (value, value_s) =
1386 build_ast_from_lexical_binding_or_variable_declaration_or_binding_element(
1387 inner_iter.next().unwrap(),
1388 script,
1389 )?;
1390 let value_exp = if let Some(init) = value.init {
1391 PatternType::AssignmentPattern {
1392 meta: value.meta,
1393 left: value.id,
1394 right: init,
1395 }
1396 } else {
1397 *value.id
1398 };
1399 Ok((
1401 AssignmentPropertyData::new_with_any_expression_key(meta, key, value_exp, false),
1402 value_s,
1403 ))
1404 } else {
1405 Err(get_unexpected_error(
1406 "build_ast_from_binding_property:2",
1407 &inner_pair,
1408 ))
1409 }
1410}
1411
1412fn build_ast_from_property_name(
1413 pair: Pair<Rule>,
1414 script: &Rc<String>,
1415) -> Result<(ExpressionType, Semantics), JsRuleError> {
1416 let inner_pair = pair.into_inner().next().unwrap();
1417 Ok(if inner_pair.as_rule() == Rule::literal_property_name {
1418 let pn_pair = inner_pair.into_inner().next().unwrap();
1419 let s = Semantics::new_empty();
1420 (
1421 if pn_pair.as_rule() == Rule::identifier_name {
1422 let id = get_identifier_data(pn_pair, script);
1423 ExpressionPatternType::Identifier(id).convert_to_expression()
1424 } else if pn_pair.as_rule() == Rule::string_literal {
1425 let d = build_ast_from_string_literal(pn_pair, script)?;
1426 ExpressionType::Literal(d)
1427 } else if pn_pair.as_rule() == Rule::numeric_literal {
1428 let meta = get_meta(&pn_pair, script);
1429 let d = build_ast_from_numeric_literal(pn_pair)?;
1430 ExpressionType::Literal(LiteralData {
1431 meta,
1432 value: LiteralType::NumberLiteral(d),
1433 })
1434 } else {
1435 return Err(get_unexpected_error(
1436 "build_ast_from_property_name:1",
1437 &pn_pair,
1438 ));
1439 },
1440 s,
1441 )
1442 } else if inner_pair.as_rule() == Rule::computed_property_name
1443 || inner_pair.as_rule() == Rule::computed_property_name__yield
1444 {
1445 build_ast_from_assignment_expression(inner_pair.into_inner().next().unwrap(), script)?
1446 } else {
1447 return Err(get_unexpected_error(
1448 "build_ast_from_property_name:2",
1449 &inner_pair,
1450 ));
1451 })
1452}
1453
1454fn build_ast_from_for_binding(
1455 pair: Pair<Rule>,
1456 script: &Rc<String>,
1457) -> Result<(PatternType, Semantics), JsRuleError> {
1458 let inner_pair = pair.into_inner().next().unwrap();
1459 Ok(match inner_pair.as_rule() {
1460 Rule::binding_identifier | Rule::binding_identifier__yield => {
1461 let (bi, bi_s) = get_binding_identifier_data(inner_pair, script)?;
1462 (
1463 ExpressionPatternType::Identifier(bi).convert_to_pattern(),
1464 bi_s,
1465 )
1466 }
1467 Rule::binding_pattern | Rule::binding_pattern__yield => {
1468 build_ast_from_binding_pattern(inner_pair, script)?
1469 }
1470 _ => {
1471 return Err(get_unexpected_error(
1472 "build_ast_from_for_binding",
1473 &inner_pair,
1474 ))
1475 }
1476 })
1477}
1478
1479fn build_ast_from_for_declaration(
1480 pair: Pair<Rule>,
1481 script: &Rc<String>,
1482) -> Result<(VariableDeclarationData, Semantics), JsRuleError> {
1483 let meta = get_meta(&pair, script);
1484 let mut inner_iter = pair.into_inner();
1485 let let_or_const_pair = inner_iter.next().unwrap();
1486 let for_binding_pair = inner_iter.next().unwrap();
1487 let meta2 = meta.clone();
1488 let (b, b_s) = build_ast_from_for_binding(for_binding_pair, script)?;
1489 Ok((
1490 VariableDeclarationData {
1491 meta,
1492 declarations: vec![VariableDeclaratorData {
1493 meta: meta2,
1494 id: Box::new(b),
1495 init: None,
1496 }],
1497 kind: get_let_or_const(let_or_const_pair)?,
1498 },
1499 b_s,
1500 ))
1501}
1502
1503fn get_let_or_const(let_or_const_pair: Pair<Rule>) -> Result<VariableDeclarationKind, JsRuleError> {
1504 Ok(match let_or_const_pair.as_str() {
1505 "let" => VariableDeclarationKind::Let,
1506 "const" => VariableDeclarationKind::Const,
1507 _ => return Err(get_unexpected_error("get_let_or_const", &let_or_const_pair)),
1508 })
1509}
1510
1511fn build_ast_from_switch_statement(
1512 pair: Pair<Rule>,
1513 script: &Rc<String>,
1514) -> Result<(StatementType, Semantics), JsRuleError> {
1515 let meta = get_meta(&pair, script);
1516 let mut inner_iter = pair.into_inner();
1517 let condition_pair = inner_iter.next().unwrap();
1518 let (condition, _condition_s) = build_ast_from_expression(condition_pair, script)?;
1519 let case_block_pair = inner_iter.next().unwrap();
1520 let mut cases = vec![];
1521 let mut s = Semantics::new_empty();
1522 for case_clause_pair in case_block_pair.into_inner() {
1523 match case_clause_pair.as_rule() {
1524 Rule::case_clause
1525 | Rule::case_clause__yield
1526 | Rule::case_clause__return
1527 | Rule::case_clause__yield_return => {
1528 let (c, c_s) = build_ast_from_case_clause(case_clause_pair, script)?;
1529 cases.push(c);
1530 s.merge(c_s);
1531 }
1532 Rule::default_clause
1533 | Rule::default_clause__yield
1534 | Rule::default_clause__return
1535 | Rule::default_clause__yield_return => {
1536 let (c, c_s) = build_ast_from_default_clause(case_clause_pair, script)?;
1537 cases.push(c);
1538 s.merge(c_s);
1539 }
1540 _ => {
1541 return Err(get_unexpected_error(
1542 "build_ast_from_switch_statement",
1543 &case_clause_pair,
1544 ))
1545 }
1546 }
1547 }
1548
1549 Ok((
1550 StatementType::SwitchStatement {
1551 meta,
1552 discriminant: Box::new(condition),
1553 cases,
1554 },
1555 s,
1556 ))
1557}
1558
1559fn build_ast_from_case_clause(
1560 pair: Pair<Rule>,
1561 script: &Rc<String>,
1562) -> Result<(SwitchCaseData, Semantics), JsRuleError> {
1563 let meta = get_meta(&pair, script);
1564 let mut inner_iter = pair.into_inner();
1565 let test_pair = inner_iter.next().unwrap();
1566 let (test_exp, _test_exp_s) = build_ast_from_expression(test_pair, script)?;
1567 let (statements, statements_s) = if let Some(statement_pair) = inner_iter.next() {
1568 build_ast_from_statement_list(statement_pair, script)?
1569 } else {
1570 (vec![], Semantics::new_empty())
1571 };
1572 validate_lexically_declared_names_have_no_duplicates_and_also_not_present_in_var_declared_names(&statements_s)?;
1575 let mut s = Semantics::new_empty();
1576 s.var_declared_names = statements_s.var_declared_names;
1577 Ok((
1578 SwitchCaseData {
1579 meta,
1580 test: Some(Box::new(test_exp)),
1581 consequent: statements,
1582 },
1583 s,
1584 ))
1585}
1586
1587fn build_ast_from_default_clause(
1588 pair: Pair<Rule>,
1589 script: &Rc<String>,
1590) -> Result<(SwitchCaseData, Semantics), JsRuleError> {
1591 let meta = get_meta(&pair, script);
1592 let mut inner_iter = pair.into_inner();
1593 let (statements, statements_s) = if let Some(statement_pair) = inner_iter.next() {
1594 build_ast_from_statement_list(statement_pair, script)?
1595 } else {
1596 (vec![], Semantics::new_empty())
1597 };
1598 validate_lexically_declared_names_have_no_duplicates_and_also_not_present_in_var_declared_names(&statements_s)?;
1601 let mut s = Semantics::new_empty();
1602 s.var_declared_names = statements_s.var_declared_names;
1603 Ok((
1604 SwitchCaseData {
1605 meta,
1606 test: None,
1607 consequent: statements,
1608 },
1609 s,
1610 ))
1611}
1612
1613fn build_ast_from_return_statement(
1614 pair: Pair<Rule>,
1615 script: &Rc<String>,
1616) -> Result<(StatementType, Semantics), JsRuleError> {
1617 let meta = get_meta(&pair, script);
1618 let inner_pair = pair.into_inner().next().unwrap();
1619 let (argument, s) = if inner_pair.as_rule() == Rule::expression__in {
1620 let (e, e_s) = build_ast_from_expression(inner_pair, script)?;
1621 (Some(Box::new(e)), e_s)
1622 } else if inner_pair.as_rule() == Rule::smart_semicolon {
1623 (None, Semantics::new_empty())
1624 } else {
1625 return Err(get_unexpected_error(
1626 "build_ast_from_return_statement",
1627 &inner_pair,
1628 ));
1629 };
1630 Ok((StatementType::ReturnStatement { meta, argument }, s))
1631}
1632
1633fn build_ast_from_try_statement(
1634 pair: Pair<Rule>,
1635 script: &Rc<String>,
1636) -> Result<(StatementType, Semantics), JsRuleError> {
1637 let meta = get_meta(&pair, script);
1638 let mut inner_iter = pair.into_inner();
1639 let block_pair = inner_iter.next().unwrap();
1640 let mut s = Semantics::new_empty();
1641 let (block, mut block_s) = build_ast_from_block(block_pair, script)?;
1642 let next_pair = inner_iter.next().unwrap();
1643 let (handler, mut handler_s, next_pair_option) = match next_pair.as_rule() {
1644 Rule::catch | Rule::catch__yield | Rule::catch__return | Rule::catch__yield_return => {
1645 let meta = get_meta(&next_pair, script);
1646 let mut catch_inner_iter = next_pair.into_inner();
1647 let catch_parameter_pair = catch_inner_iter.next().unwrap();
1648 let catch_parameter_inner_pair = catch_parameter_pair.into_inner().next().unwrap();
1649 let (catch_param, catch_param_s) = match catch_parameter_inner_pair.as_rule() {
1650 Rule::binding_identifier | Rule::binding_identifier__yield => {
1651 let (bi, bi_s) =
1652 get_binding_identifier_data(catch_parameter_inner_pair, script)?;
1653 (
1654 ExpressionPatternType::Identifier(bi).convert_to_pattern(),
1655 bi_s,
1656 )
1657 }
1658 Rule::binding_pattern | Rule::binding_pattern__yield => {
1659 build_ast_from_binding_pattern(catch_parameter_inner_pair, script)?
1660 }
1661 _ => {
1662 return Err(get_unexpected_error(
1663 "build_ast_from_try_statement",
1664 &catch_parameter_inner_pair,
1665 ))
1666 }
1667 };
1668 let block_pair = catch_inner_iter.next().unwrap();
1669 let (block, block_s) = build_ast_from_block(block_pair, script)?;
1670 validate_bound_names_have_no_duplicates_and_also_not_present_in_var_declared_names_or_lexically_declared_names(&catch_param_s.bound_names, &block_s.var_declared_names,&block_s.lexically_declared_names)?;
1671 let mut s = Semantics::new_empty();
1672 s.var_declared_names = block_s.var_declared_names;
1673 (
1674 Some(CatchClauseData {
1675 meta,
1676 param: Box::new(catch_param),
1677 body: block,
1678 }),
1679 s,
1680 inner_iter.next(),
1681 )
1682 }
1683 _ => (None, Semantics::new_empty(), Some(next_pair)),
1684 };
1685 let (finalizer, mut finalizer_s) = if let Some(finally_pair) = next_pair_option {
1686 let finally_block_pair = finally_pair.into_inner().next().unwrap();
1687 let (b, b_s) = build_ast_from_block(finally_block_pair, script)?;
1688 (Some(b), b_s)
1689 } else {
1690 (None, Semantics::new_empty())
1691 };
1692 s.var_declared_names.append(&mut block_s.var_declared_names);
1693 s.var_declared_names
1694 .append(&mut handler_s.var_declared_names);
1695 s.var_declared_names
1696 .append(&mut finalizer_s.var_declared_names);
1697 Ok((
1698 StatementType::TryStatement {
1699 meta,
1700 block,
1701 handler,
1702 finalizer,
1703 },
1704 s,
1705 ))
1706}
1707
1708fn build_ast_from_variable_statement(
1709 pair: Pair<Rule>,
1710 script: &Rc<String>,
1711) -> Result<(StatementType, Semantics), JsRuleError> {
1712 let meta = get_meta(&pair, script);
1713 let (dl, dl_s) =
1714 build_ast_from_variable_declaration_list(pair.into_inner().next().unwrap(), script)?;
1715 let mut s = Semantics::new_empty();
1716 s.var_declared_names = dl_s.bound_names;
1717 Ok((
1718 StatementType::DeclarationStatement(DeclarationType::VariableDeclaration(
1719 VariableDeclarationData {
1720 meta,
1721 declarations: dl,
1722 kind: VariableDeclarationKind::Var,
1723 },
1724 )),
1725 s,
1726 ))
1727}
1728
1729fn build_ast_from_variable_declaration_list(
1730 pair: Pair<Rule>,
1731 script: &Rc<String>,
1732) -> Result<(Vec<VariableDeclaratorData>, Semantics), JsRuleError> {
1733 let mut declarations = vec![];
1734 let mut s = Semantics::new_empty();
1735 for var_pair in pair.into_inner() {
1736 if var_pair.as_rule() == Rule::variable_declaration
1737 || var_pair.as_rule() == Rule::variable_declaration__in
1738 {
1739 let (d, d_s) =
1740 build_ast_from_lexical_binding_or_variable_declaration_or_binding_element(
1741 var_pair, script,
1742 )?;
1743 s.merge(d_s);
1744 declarations.push(d)
1745 } else {
1746 return Err(get_unexpected_error(
1747 "build_ast_from_variable_declaration_list",
1748 &var_pair,
1749 ));
1750 }
1751 }
1752 Ok((declarations, s))
1753}
1754
1755fn build_ast_from_lexical_binding_or_variable_declaration_or_binding_element(
1756 pair: Pair<Rule>,
1757 script: &Rc<String>,
1758) -> Result<(VariableDeclaratorData, Semantics), JsRuleError> {
1759 let meta = get_meta(&pair, script);
1760 let mut inner_iter = pair.into_inner();
1761 let inner_pair = inner_iter.next().unwrap();
1762 Ok(
1763 if inner_pair.as_rule() == Rule::binding_identifier
1764 || inner_pair.as_rule() == Rule::binding_identifier__yield
1765 {
1766 let (bi, bi_s) = get_binding_identifier_data(inner_pair, script)?;
1767 let id = Box::new(ExpressionPatternType::Identifier(bi).convert_to_pattern());
1768 (
1769 if let Some(initializer) = inner_iter.next() {
1770 let (a, _a_s) = build_ast_from_assignment_expression(
1771 initializer.into_inner().next().unwrap(),
1772 script,
1773 )?;
1774 VariableDeclaratorData {
1776 meta,
1777 id,
1778 init: Some(Box::new(a)),
1779 }
1780 } else {
1781 VariableDeclaratorData {
1782 meta,
1783 id,
1784 init: None,
1785 }
1786 },
1787 bi_s,
1788 )
1789 } else if inner_pair.as_rule() == Rule::binding_pattern
1790 || inner_pair.as_rule() == Rule::binding_pattern__yield
1791 {
1792 let (b, b_s) = build_ast_from_binding_pattern(inner_pair, script)?;
1793 let id = Box::new(b);
1794 let init = if let Some(initializer) = inner_iter.next() {
1795 let (a, _a_s) = build_ast_from_assignment_expression(
1796 initializer.into_inner().next().unwrap(),
1797 script,
1798 )?;
1799 Some(Box::new(a))
1801 } else {
1802 None
1803 };
1804 (VariableDeclaratorData { meta, id, init }, b_s)
1805 } else if inner_pair.as_rule() == Rule::single_name_binding
1806 || inner_pair.as_rule() == Rule::single_name_binding__yield
1807 {
1808 build_ast_from_single_name_binding(inner_pair, script)?
1809 } else {
1810 return Err(get_unexpected_error(
1811 "build_ast_from_lexical_binding_or_variable_declaration",
1812 &inner_pair,
1813 ));
1814 },
1815 )
1816}
1817
1818fn build_ast_from_single_name_binding(
1819 pair: Pair<Rule>,
1820 script: &Rc<String>,
1821) -> Result<(VariableDeclaratorData, Semantics), JsRuleError> {
1822 let meta = get_meta(&pair, script);
1823 let mut inner_iter = pair.into_inner();
1824 let (b, s) = get_binding_identifier_data(inner_iter.next().unwrap(), script)?;
1825 let id = Box::new(ExpressionPatternType::Identifier(b).convert_to_pattern());
1826 Ok(if let Some(initializer) = inner_iter.next() {
1827 let (a, _a_s) = build_ast_from_assignment_expression(initializer, script)?;
1828 (
1830 VariableDeclaratorData {
1831 meta,
1832 id,
1833 init: Some(Box::new(a)),
1834 },
1835 s,
1836 )
1837 } else {
1838 (
1839 VariableDeclaratorData {
1840 meta,
1841 id,
1842 init: None,
1843 },
1844 s,
1845 )
1846 })
1847}
1848
1849fn build_ast_from_assignment_expression(
1850 pair: Pair<Rule>,
1851 script: &Rc<String>,
1852) -> Result<(ExpressionType, Semantics), JsRuleError> {
1853 let meta = get_meta(&pair, script);
1854 let mut inner_pair_iter = pair.into_inner();
1855 let inner_pair = inner_pair_iter.next().unwrap();
1856 Ok(match inner_pair.as_rule() {
1857 Rule::arrow_function
1858 | Rule::arrow_function__in
1859 | Rule::arrow_function__yield
1860 | Rule::arrow_function__in_yield => build_ast_from_arrow_function(inner_pair, script)?,
1861 Rule::left_hand_side_expression | Rule::left_hand_side_expression__yield => {
1862 let lhs_pair = inner_pair;
1863 let lhs_meta = get_meta(&lhs_pair, script);
1864 let (lhs, mut s) = build_ast_from_left_hand_side_expression(lhs_pair, script)?;
1865 let mut next_pair = inner_pair_iter.next().unwrap();
1866 let (left, operator) = if next_pair.as_rule() == Rule::assignment_operator {
1867 if s.is_valid_simple_assignment_target.is_false() {
1868 return Err(get_validation_error_with_meta(
1869 "L.H.S. needs to be a simple expression".to_string(),
1870 AstBuilderValidationErrorType::ReferenceError,
1871 lhs_meta,
1872 ));
1873 }
1874 let op_str = next_pair.as_str();
1875 next_pair = inner_pair_iter.next().unwrap();
1876 (
1877 PatternOrExpression::Expression(Box::new(lhs)),
1878 match op_str {
1879 "*=" => AssignmentOperator::MultiplyEquals,
1880 "/=" => AssignmentOperator::DivideEquals,
1881 "%=" => AssignmentOperator::ModuloEquals,
1882 "+=" => AssignmentOperator::AddEquals,
1883 "-=" => AssignmentOperator::SubtractEquals,
1884 "<<=" => AssignmentOperator::BitwiseLeftShiftEquals,
1885 ">>=" => AssignmentOperator::BitwiseRightShiftEquals,
1886 ">>>=" => AssignmentOperator::BitwiseUnsignedRightShiftEquals,
1887 "&=" => AssignmentOperator::BitwiseAndEquals,
1888 "^=" => AssignmentOperator::BitwiseXorEquals,
1889 "|=" => AssignmentOperator::BitwiseOrEquals,
1890 _ => {
1891 return Err(get_unexpected_error(
1892 "build_ast_from_assignment_expression:1",
1893 &next_pair,
1894 ))
1895 }
1896 },
1897 )
1898 } else {
1899 let left = match &lhs {
1903 ExpressionType::MemberExpression(_) => {
1904 PatternOrExpression::Expression(Box::new(lhs))
1906 }
1907 ExpressionType::ExpressionWhichCanBePattern(ExpressionPatternType::Identifier(_)) => {
1908 PatternOrExpression::Expression(Box::new(lhs))
1910 }
1911 _ => {
1912 PatternOrExpression::Pattern(Box::new(
1914 convert_lhs_expression_to_pattern_for_assignment_operation(lhs, Some(&s))?,
1915 ))
1916 }
1917 };
1918 (left, AssignmentOperator::Equals)
1919 };
1920 let (assignment_exp, assignment_exp_s) =
1922 build_ast_from_assignment_expression(next_pair, script)?;
1923 s.merge(assignment_exp_s);
1924 (
1925 ExpressionType::AssignmentExpression {
1926 meta,
1927 left,
1928 operator,
1929 right: Box::new(assignment_exp),
1930 },
1931 s,
1932 )
1933 }
1934 Rule::yield_expression | Rule::yield_expression__in => {
1935 match inner_pair.into_inner().next() {
1936 Some(inner_pair) => {
1937 let (assign_rule_pair, delegate) = if inner_pair.as_rule()
1938 == Rule::star_assignment_expression__yield
1939 || inner_pair.as_rule() == Rule::star_assignment_expression__in_yield
1940 {
1941 (inner_pair.into_inner().next().unwrap(), true)
1942 } else {
1943 (inner_pair, false)
1944 };
1945 let (assignment_exp, assignment_exp_s) =
1946 build_ast_from_assignment_expression(assign_rule_pair, script)?;
1947 (
1948 ExpressionType::YieldExpression {
1949 meta,
1950 delegate,
1951 argument: Some(Box::new(assignment_exp)),
1952 },
1953 assignment_exp_s,
1954 )
1955 }
1956 None => (
1957 ExpressionType::YieldExpression {
1958 meta,
1959 delegate: false,
1960 argument: None,
1961 },
1962 Semantics::new_empty(),
1963 ),
1964 }
1965 }
1966 Rule::conditional_expression
1967 | Rule::conditional_expression__in
1968 | Rule::conditional_expression__yield
1969 | Rule::conditional_expression__in_yield => {
1970 build_ast_from_conditional_expression(inner_pair, script)?
1971 }
1972 _ => {
1973 return Err(get_unexpected_error(
1974 "build_ast_from_assignment_expression:2",
1975 &inner_pair,
1976 ))
1977 }
1978 })
1979}
1980
1981fn convert_lhs_expression_to_pattern_for_assignment_operation(
1982 lhs_exp: ExpressionType,
1983 s: Option<&Semantics>,
1984) -> Result<PatternType, JsRuleError> {
1985 match lhs_exp {
1986 ExpressionType::ExpressionWhichCanBePattern(p) => Ok(p.convert_to_pattern()),
1987 ExpressionType::MemberExpression(member_expr) => {
1988 Err(get_validation_error_with_meta(
1992 "Member expression cannot be used as destructuring pattern".to_string(),
1993 AstBuilderValidationErrorType::ReferenceError,
1994 member_expr.get_meta().clone(),
1995 ))
1996 }
1997 ExpressionType::ArrayExpression {
1998 meta,
1999 elements: o_elements,
2000 } => {
2001 let mut elements = vec![];
2003 for p in o_elements {
2004 elements.push(if let Some(es) = p {
2005 Some(Box::new(match es {
2006 ExpressionOrSpreadElement::Expression(e) => {
2007 convert_lhs_expression_to_pattern_for_assignment_operation(
2008 *e,
2009 None,
2010 )?
2011 }
2012 ExpressionOrSpreadElement::SpreadElement(s) => {
2013 let s = convert_lhs_expression_to_pattern_for_assignment_operation(
2014 *s,
2015 None,
2016 )?;
2017 PatternType::RestElement {
2018 meta: s.get_meta().clone(),
2019 argument: Box::new(s),
2020 }
2021 }
2022 }))
2023 } else {
2024 None
2025 });
2026 }
2027 Ok(PatternType::ArrayPattern { meta, elements })
2028 }
2029 ExpressionType::ObjectExpression {
2030 meta,
2031 properties: o_props,
2032 } => {
2033 let mut properties = vec![];
2035 for p in o_props {
2036 if p.method {
2037 return Err(get_validation_error_with_meta(
2038 "Invalid object pattern. Cannot have methods.".to_string(),
2039 AstBuilderValidationErrorType::SyntaxError,
2040 p.meta,
2041 ));
2042 } else {
2043 properties.push(AssignmentPropertyData::new_with_any_expression_key(
2044 p.meta,
2045 *p.key,
2046 convert_lhs_expression_to_pattern_for_assignment_operation(
2047 *p.value,
2048 None,
2049 )?,
2050 p.shorthand,
2051 ));
2052 }
2053 }
2054 Ok(PatternType::ObjectPattern { meta, properties })
2055 }
2056 ExpressionType::Literal(LiteralData { meta, .. })
2057 | ExpressionType::ThisExpression { meta }
2058 | ExpressionType::FunctionOrGeneratorExpression(FunctionData { meta, .. })
2059 | ExpressionType::UnaryExpression { meta, .. }
2060 | ExpressionType::UpdateExpression { meta, .. }
2061 | ExpressionType::BinaryExpression { meta, .. }
2062 | ExpressionType::AssignmentExpression { meta, .. }
2063 | ExpressionType::LogicalExpression { meta, .. }
2064 | ExpressionType::ConditionalExpression { meta, .. }
2065 | ExpressionType::CallExpression { meta, .. }
2066 | ExpressionType::NewExpression { meta, .. }
2067 | ExpressionType::SequenceExpression { meta, .. }
2068 | ExpressionType::ArrowFunctionExpression { meta, .. }
2069 | ExpressionType::YieldExpression { meta, .. }
2070 | ExpressionType::TemplateLiteral(TemplateLiteralData { meta, .. })
2071 | ExpressionType::TaggedTemplateExpression { meta, .. }
2072 | ExpressionType::ClassExpression(ClassData { meta, .. })
2073 | ExpressionType::MetaProperty { meta, .. } => {
2074 if s.is_some() && s.unwrap().is_valid_simple_assignment_target.is_true() {
2075 Err(JsRuleError{ kind: JsErrorType::Unexpected("Unexpected error reached in convert_lhs_expression_to_pattern"), message: "Did not expect a simple assignment target here. It then needs to be converted to pattern".to_string() })
2076 } else {
2077 Err( get_validation_error_with_meta("Parsing error encountered: L.H.S. needs to be a simple expression or object/array literal".to_string(),AstBuilderValidationErrorType::ReferenceError, meta ) )
2078 }
2079 }
2080 }
2081}
2082
2083fn build_ast_from_arrow_function(
2084 pair: Pair<Rule>,
2085 script: &Rc<String>,
2086) -> Result<(ExpressionType, Semantics), JsRuleError> {
2087 let meta = get_meta(&pair, script);
2088 let mut inner_iter = pair.into_inner();
2089 let arrow_parameters_pair = inner_iter.next().unwrap();
2090 let inner_arrow_parameters_pair = arrow_parameters_pair.into_inner().next().unwrap();
2091 let (params, params_s) = match inner_arrow_parameters_pair.as_rule() {
2092 Rule::binding_identifier | Rule::binding_identifier__yield => {
2093 let (b, b_s) = get_binding_identifier_data(inner_arrow_parameters_pair, script)?;
2094 (
2095 vec![
2096 ExpressionPatternType::Identifier(b).convert_to_pattern()
2097 ],
2098 b_s,
2099 )
2100 }
2101 Rule::formal_parameters | Rule::formal_parameters__yield => {
2102 let (f, f_s) = build_ast_from_formal_parameters(inner_arrow_parameters_pair, script)?;
2103 (f, f_s)
2104 }
2105 _ => {
2106 return Err(get_unexpected_error(
2107 "build_ast_from_arrow_function:1",
2108 &inner_arrow_parameters_pair,
2109 ));
2110 }
2111 };
2112 let concise_body_pair = inner_iter.next().unwrap();
2113 let inner_concise_body_pair = concise_body_pair.into_inner().next().unwrap();
2114 let (body, body_s) = match inner_concise_body_pair.as_rule() {
2115 Rule::function_body => {
2116 let (f, f_s) = build_ast_from_function_body(inner_concise_body_pair, script)?;
2117 (Box::new(FunctionBodyOrExpression::FunctionBody(f)), f_s)
2118 }
2119 Rule::assignment_expression | Rule::assignment_expression__in => {
2120 let (a, _a_s) = build_ast_from_assignment_expression(inner_concise_body_pair, script)?;
2121 (
2122 Box::new(FunctionBodyOrExpression::Expression(a)),
2123 Semantics::new_empty(),
2124 )
2125 }
2126 _ => {
2127 return Err(get_unexpected_error(
2128 "build_ast_from_arrow_function:2",
2129 &inner_concise_body_pair,
2130 ));
2131 }
2132 };
2133 if body_s.contains_yield_expression.is_true() || params_s.contains_yield_expression.is_true() {
2134 Err(get_validation_error_with_meta(
2135 "'yield' is not allowed in arrow function".to_string(),
2136 AstBuilderValidationErrorType::SyntaxError,
2137 body.get_meta().clone(),
2138 ))
2139 } else {
2140 validate_bound_names_have_no_duplicates_and_also_not_present_in_var_declared_names_or_lexically_declared_names(¶ms_s.bound_names,&vec![], &body_s.lexically_declared_names)?;
2141
2142 Ok((
2146 ExpressionType::ArrowFunctionExpression { meta, params, body },
2147 Semantics::new_empty(),
2148 ))
2149 }
2150}
2151
2152fn build_ast_from_left_hand_side_expression(
2153 pair: Pair<Rule>,
2154 script: &Rc<String>,
2155) -> Result<(ExpressionType, Semantics), JsRuleError> {
2156 let inner_pair: Pair<Rule> = pair.into_inner().next().unwrap();
2157 Ok(match inner_pair.as_rule() {
2158 Rule::call_expression | Rule::call_expression__yield => {
2159 build_ast_from_call_expression(inner_pair, script)?
2160 }
2161 Rule::new_expression | Rule::new_expression__yield => {
2162 build_ast_from_new_expression(inner_pair, script)?
2163 }
2164 _ => {
2165 return Err(get_unexpected_error(
2166 "build_ast_from_left_hand_side_expression",
2167 &inner_pair,
2168 ))
2169 }
2170 })
2171}
2172
2173fn build_ast_from_new_expression(
2174 pair: Pair<Rule>,
2175 script: &Rc<String>,
2176) -> Result<(ExpressionType, Semantics), JsRuleError> {
2177 let inner_pair = pair.into_inner().next().unwrap();
2178 Ok(
2179 if inner_pair.as_rule() == Rule::member_expression
2180 || inner_pair.as_rule() == Rule::member_expression__yield
2181 {
2182 build_ast_from_member_expression(inner_pair, script)?
2183 } else {
2184 let ne_meta = get_meta(&inner_pair, script);
2185 let (n, n_s) = build_ast_from_new_expression(inner_pair, script)?;
2186 (
2187 ExpressionType::NewExpression {
2188 meta: ne_meta,
2189 callee: Box::new(n),
2190 arguments: vec![],
2191 },
2192 n_s,
2193 )
2194 },
2195 )
2196}
2197
2198fn build_ast_from_conditional_expression(
2199 pair: Pair<Rule>,
2200 script: &Rc<String>,
2201) -> Result<(ExpressionType, Semantics), JsRuleError> {
2202 let meta = get_meta(&pair, script);
2203 let mut pair_iter = pair.into_inner();
2204 let logical_or_pair = pair_iter.next().unwrap();
2205 let (or_node, mut s) = build_ast_from_logical_or_expression(logical_or_pair, script)?;
2206 if let Some(inner_pair) = pair_iter.next() {
2207 let (truthy, truthy_s) = build_ast_from_assignment_expression(inner_pair, script)?;
2208 let (falsy, falsy_s) =
2209 build_ast_from_assignment_expression(pair_iter.next().unwrap(), script)?;
2210 s.merge(truthy_s).merge(falsy_s);
2211 Ok((
2212 ExpressionType::ConditionalExpression {
2213 meta,
2214 test: Box::new(or_node),
2215 consequent: Box::new(truthy),
2216 alternate: Box::new(falsy),
2217 },
2218 s,
2219 ))
2220 } else {
2221 Ok((or_node, s))
2222 }
2223}
2224
2225fn get_ast_for_logical_expression(
2226 left: Option<ExpressionType>,
2227 right: ExpressionType,
2228 operator: LogicalOperator,
2229 script: &Rc<String>,
2230) -> ExpressionType {
2231 if let Some(actual_left) = left {
2232 ExpressionType::LogicalExpression {
2233 meta: Meta {
2234 start_index: actual_left.get_meta().start_index,
2235 end_index: right.get_meta().end_index,
2236 script: script.clone(),
2237 },
2238 operator,
2239 left: Box::new(actual_left),
2240 right: Box::new(right),
2241 }
2242 } else {
2243 right
2244 }
2245}
2246
2247fn get_ast_for_binary_expression(
2248 left: Option<ExpressionType>,
2249 right: ExpressionType,
2250 operator: Option<BinaryOperator>,
2251 script: &Rc<String>,
2252) -> ExpressionType {
2253 if let Some(actual_left) = left {
2254 ExpressionType::BinaryExpression {
2255 meta: Meta {
2256 start_index: actual_left.get_meta().start_index,
2257 end_index: right.get_meta().end_index,
2258 script: script.clone(),
2259 },
2260 operator: operator.unwrap(),
2261 left: Box::new(actual_left),
2262 right: Box::new(right),
2263 }
2264 } else {
2265 right
2266 }
2267}
2268
2269fn build_ast_from_logical_or_expression(
2270 pair: Pair<Rule>,
2271 script: &Rc<String>,
2272) -> Result<(ExpressionType, Semantics), JsRuleError> {
2273 let mut left = None;
2274 let mut s = Semantics::new_empty();
2275 for inner_pair in pair.into_inner() {
2276 let (right, right_s) = build_ast_from_logical_and_expression(inner_pair, script)?;
2277 s.merge(right_s);
2278 left = Some(get_ast_for_logical_expression(
2279 left,
2280 right,
2281 LogicalOperator::Or,
2282 script,
2283 ));
2284 }
2285 Ok((left.unwrap(), s))
2286}
2287
2288fn build_ast_from_logical_and_expression(
2289 pair: Pair<Rule>,
2290 script: &Rc<String>,
2291) -> Result<(ExpressionType, Semantics), JsRuleError> {
2292 let mut left = None;
2293 let mut s = Semantics::new_empty();
2294 for inner_pair in pair.into_inner() {
2295 let (right, right_s) = build_ast_from_bitwise_or_expression(inner_pair, script)?;
2296 s.merge(right_s);
2297 left = Some(get_ast_for_logical_expression(
2298 left,
2299 right,
2300 LogicalOperator::And,
2301 script,
2302 ));
2303 }
2304 Ok((left.unwrap(), s))
2305}
2306
2307fn build_ast_from_bitwise_or_expression(
2308 pair: Pair<Rule>,
2309 script: &Rc<String>,
2310) -> Result<(ExpressionType, Semantics), JsRuleError> {
2311 let mut left = None;
2312 let mut s = Semantics::new_empty();
2313 for inner_pair in pair.into_inner() {
2314 let (right, right_s) = build_ast_from_bitwise_xor_expression(inner_pair, script)?;
2315 s.merge(right_s);
2316 left = Some(get_ast_for_binary_expression(
2317 left,
2318 right,
2319 Some(BinaryOperator::BitwiseOr),
2320 script,
2321 ))
2322 }
2323 Ok((left.unwrap(), s))
2324}
2325
2326fn build_ast_from_bitwise_xor_expression(
2327 pair: Pair<Rule>,
2328 script: &Rc<String>,
2329) -> Result<(ExpressionType, Semantics), JsRuleError> {
2330 let mut left = None;
2331 let mut s = Semantics::new_empty();
2332 for inner_pair in pair.into_inner() {
2333 let (right, right_s) = build_ast_from_bitwise_and_expression(inner_pair, script)?;
2334 s.merge(right_s);
2335 left = Some(get_ast_for_binary_expression(
2336 left,
2337 right,
2338 Some(BinaryOperator::BitwiseXor),
2339 script,
2340 ))
2341 }
2342 Ok((left.unwrap(), s))
2343}
2344
2345fn build_ast_from_bitwise_and_expression(
2346 pair: Pair<Rule>,
2347 script: &Rc<String>,
2348) -> Result<(ExpressionType, Semantics), JsRuleError> {
2349 let mut left = None;
2350 let mut s = Semantics::new_empty();
2351 for inner_pair in pair.into_inner() {
2352 let (right, right_s) = build_ast_from_equality_expression(inner_pair, script)?;
2353 s.merge(right_s);
2354 left = Some(get_ast_for_binary_expression(
2355 left,
2356 right,
2357 Some(BinaryOperator::BitwiseAnd),
2358 script,
2359 ))
2360 }
2361 Ok((left.unwrap(), s))
2362}
2363
2364fn build_ast_from_equality_expression(
2365 pair: Pair<Rule>,
2366 script: &Rc<String>,
2367) -> Result<(ExpressionType, Semantics), JsRuleError> {
2368 if cfg!(debug_assertions) {
2369 if pair.as_rule() != Rule::equality_expression
2370 && pair.as_rule() != Rule::equality_expression__in
2371 && pair.as_rule() != Rule::equality_expression__yield
2372 && pair.as_rule() != Rule::equality_expression__in_yield
2373 {
2374 return Err(get_unexpected_error(
2375 "build_ast_from_equality_expression:0",
2376 &pair,
2377 ));
2378 }
2379 }
2380 let mut left = None;
2381 let mut s = Semantics::new_empty();
2382 let mut pair_iter = pair.into_inner();
2383 loop {
2384 if let Some(mut inner_pair) = pair_iter.next() {
2385 let mut operator = None;
2386 if inner_pair.as_rule() == Rule::equality_operator {
2387 operator = Some(match inner_pair.as_str() {
2388 "===" => BinaryOperator::StrictlyEqual,
2389 "!==" => BinaryOperator::StrictlyUnequal,
2390 "==" => BinaryOperator::LooselyEqual,
2391 "!=" => BinaryOperator::LooselyUnequal,
2392 _ => {
2393 return Err(get_unexpected_error(
2394 "build_ast_from_equality_expression",
2395 &inner_pair,
2396 ))
2397 }
2398 });
2399 inner_pair = pair_iter.next().unwrap();
2400 }
2401 let (right, right_s) = build_ast_from_relational_expression(inner_pair, script)?;
2402 s.merge(right_s);
2403 left = Some(get_ast_for_binary_expression(left, right, operator, script));
2404 } else {
2405 break;
2406 }
2407 }
2408 Ok((left.unwrap(), s))
2409}
2410
2411fn build_ast_from_relational_expression(
2412 pair: Pair<Rule>,
2413 script: &Rc<String>,
2414) -> Result<(ExpressionType, Semantics), JsRuleError> {
2415 if cfg!(debug_assertions) {
2416 if pair.as_rule() != Rule::relational_expression
2417 && pair.as_rule() != Rule::relational_expression__in
2418 && pair.as_rule() != Rule::relational_expression__yield
2419 && pair.as_rule() != Rule::relational_expression__in_yield
2420 {
2421 return Err(get_unexpected_error(
2422 "build_ast_from_relational_expression:0",
2423 &pair,
2424 ));
2425 }
2426 }
2427 let mut left = None;
2428 let mut s = Semantics::new_empty();
2429 let mut pair_iter = pair.into_inner();
2430 loop {
2431 if let Some(mut inner_pair) = pair_iter.next() {
2432 let mut operator = None;
2433 if inner_pair.as_rule() == Rule::relational_operator
2434 || inner_pair.as_rule() == Rule::relational_operator__in
2435 {
2436 operator = Some(match inner_pair.as_str() {
2437 "<=" => BinaryOperator::LessThanEqual,
2438 ">=" => BinaryOperator::GreaterThanEqual,
2439 "<" => BinaryOperator::LessThan,
2440 ">" => BinaryOperator::GreaterThan,
2441 "instanceof" => BinaryOperator::InstanceOf,
2442 "in" => BinaryOperator::In,
2443 _ => {
2444 return Err(get_unexpected_error(
2445 "build_ast_from_relational_expression",
2446 &inner_pair,
2447 ))
2448 }
2449 });
2450 inner_pair = pair_iter.next().unwrap();
2451 }
2452 let (right, right_s) = build_ast_from_shift_expression(inner_pair, script)?;
2453 s.merge(right_s);
2454 left = Some(get_ast_for_binary_expression(left, right, operator, script));
2455 } else {
2456 break;
2457 }
2458 }
2459 Ok((left.unwrap(), s))
2460}
2461
2462fn build_ast_from_shift_expression(
2463 pair: Pair<Rule>,
2464 script: &Rc<String>,
2465) -> Result<(ExpressionType, Semantics), JsRuleError> {
2466 if cfg!(debug_assertions) {
2467 if pair.as_rule() != Rule::shift_expression
2468 && pair.as_rule() != Rule::shift_expression__yield
2469 {
2470 return Err(get_unexpected_error(
2471 "build_ast_from_shift_expression:0",
2472 &pair,
2473 ));
2474 }
2475 }
2476 let mut left = None;
2477 let mut s = Semantics::new_empty();
2478 let mut pair_iter = pair.into_inner();
2479 loop {
2480 if let Some(mut inner_pair) = pair_iter.next() {
2481 let mut operator = None;
2482 if inner_pair.as_rule() == Rule::shift_operator {
2483 operator = Some(match inner_pair.as_str() {
2484 "<<" => BinaryOperator::BitwiseLeftShift,
2485 ">>>" => BinaryOperator::BitwiseUnsignedRightShift,
2486 ">>" => BinaryOperator::BitwiseRightShift,
2487 _ => {
2488 return Err(get_unexpected_error(
2489 "build_ast_from_shift_expression",
2490 &inner_pair,
2491 ))
2492 }
2493 });
2494 inner_pair = pair_iter.next().unwrap();
2495 }
2496 let (right, right_s) = build_ast_from_additive_expression(inner_pair, script)?;
2497 s.merge(right_s);
2498 left = Some(get_ast_for_binary_expression(left, right, operator, script));
2499 } else {
2500 break;
2501 }
2502 }
2503 Ok((left.unwrap(), s))
2504}
2505
2506fn build_ast_from_additive_expression(
2507 pair: Pair<Rule>,
2508 script: &Rc<String>,
2509) -> Result<(ExpressionType, Semantics), JsRuleError> {
2510 let mut left = None;
2511 let mut s = Semantics::new_empty();
2512 let mut pair_iter = pair.into_inner();
2513 loop {
2514 if let Some(mut inner_pair) = pair_iter.next() {
2515 let mut operator = None;
2516 if inner_pair.as_rule() == Rule::additive_operator {
2517 operator = Some(match inner_pair.as_str() {
2518 "+" => BinaryOperator::Add,
2519 "-" => BinaryOperator::Subtract,
2520 _ => {
2521 return Err(get_unexpected_error(
2522 "build_ast_from_additive_expression",
2523 &inner_pair,
2524 ))
2525 }
2526 });
2527 inner_pair = pair_iter.next().unwrap();
2528 }
2529 let (right, right_s) = build_ast_from_multiplicative_expression(inner_pair, script)?;
2530 s.merge(right_s);
2531 left = Some(get_ast_for_binary_expression(left, right, operator, script));
2532 } else {
2533 break;
2534 }
2535 }
2536 Ok((left.unwrap(), s))
2537}
2538
2539fn build_ast_from_multiplicative_expression(
2540 pair: Pair<Rule>,
2541 script: &Rc<String>,
2542) -> Result<(ExpressionType, Semantics), JsRuleError> {
2543 let mut left = None;
2544 let mut s = Semantics::new_empty();
2545 let mut pair_iter = pair.into_inner();
2546 loop {
2547 if let Some(mut inner_pair) = pair_iter.next() {
2548 let mut operator = None;
2549 if inner_pair.as_rule() == Rule::multiplicative_operator {
2550 operator = Some(match inner_pair.as_str() {
2551 "*" => BinaryOperator::Multiply,
2552 "/" => BinaryOperator::Divide,
2553 "%" => BinaryOperator::Modulo,
2554 _ => {
2555 return Err(get_unexpected_error(
2556 "build_ast_from_multiplicative_expression",
2557 &inner_pair,
2558 ))
2559 }
2560 });
2561 inner_pair = pair_iter.next().unwrap();
2562 }
2563 let (right, right_s) = build_ast_from_unary_expression(inner_pair, script)?;
2564 s.merge(right_s);
2565 left = Some(get_ast_for_binary_expression(left, right, operator, script));
2566 } else {
2567 break;
2568 }
2569 }
2570 Ok((left.unwrap(), s))
2571}
2572
2573fn build_ast_from_unary_expression(
2574 pair: Pair<Rule>,
2575 script: &Rc<String>,
2576) -> Result<(ExpressionType, Semantics), JsRuleError> {
2577 let meta = get_meta(&pair, script);
2578 let mut pair_iter = pair.into_inner();
2579 let first_pair = pair_iter.next().unwrap();
2580
2581 Ok(
2582 if first_pair.as_rule() == Rule::postfix_expression
2583 || first_pair.as_rule() == Rule::postfix_expression__yield
2584 {
2585 build_ast_from_postfix_expression(first_pair, script)?
2586 } else {
2587 let operator_str = first_pair.as_str();
2589 match operator_str {
2590 "++" | "--" => {
2591 let u_pair = pair_iter.next().unwrap();
2592 let u_pair_meta = get_meta(&u_pair, script);
2593 let (u, u_s) = build_ast_from_unary_expression(u_pair, script)?;
2594 if u_s.is_valid_simple_assignment_target.is_false() {
2595 return Err(get_validation_error_with_meta(
2596 "Invalid expression for prefix operator".to_string(),
2597 AstBuilderValidationErrorType::ReferenceError,
2598 u_pair_meta,
2599 ));
2600 } else {
2601 (
2602 ExpressionType::UpdateExpression {
2603 meta,
2604 operator: match operator_str {
2605 "++" => UpdateOperator::PlusPlus,
2606 "--" => UpdateOperator::MinusMinus,
2607 _ => unreachable!(),
2608 },
2609 argument: Box::new(u),
2610 prefix: true,
2611 },
2612 u_s,
2613 )
2614 }
2615 }
2616 _ => {
2617 let (u, u_s) =
2618 build_ast_from_unary_expression(pair_iter.next().unwrap(), script)?;
2619 (
2620 ExpressionType::UnaryExpression {
2621 meta,
2622 operator: match operator_str {
2623 "delete" => {
2624 if let ExpressionType::ExpressionWhichCanBePattern(
2625 ExpressionPatternType::Identifier(id),
2626 ) = &u
2627 {
2628 return Err(get_validation_error_with_meta(
2629 format!(
2630 "Cannot delete identifier reference: {}",
2631 id.name
2632 ),
2633 AstBuilderValidationErrorType::SyntaxError,
2634 id.meta.clone(),
2635 ));
2636 }
2637 UnaryOperator::Delete
2638 }
2639 "void" => UnaryOperator::Void,
2640 "typeof" => UnaryOperator::TypeOf,
2641 "+" => UnaryOperator::Plus,
2642 "-" => UnaryOperator::Minus,
2643 "~" => UnaryOperator::BitwiseNot,
2644 "!" => UnaryOperator::LogicalNot,
2645 _ => {
2646 return Err(get_unexpected_error(
2647 "build_ast_from_unary_expression:2",
2648 &first_pair,
2649 ))
2650 }
2651 },
2652 argument: Box::new(u),
2653 },
2654 u_s,
2655 )
2656 }
2657 }
2658 },
2659 )
2660}
2661
2662fn build_ast_from_postfix_expression(
2663 pair: Pair<Rule>,
2664 script: &Rc<String>,
2665) -> Result<(ExpressionType, Semantics), JsRuleError> {
2666 let meta = get_meta(&pair, script);
2667 let mut pair_iter = pair.into_inner();
2668 let lhs_pair = pair_iter.next().unwrap();
2669 let (lhs, lhs_s) = build_ast_from_left_hand_side_expression(lhs_pair, script)?;
2670 if lhs_s.is_valid_simple_assignment_target.is_false() {
2671 Err(get_validation_error_with_meta(
2672 "Invalid expression for postfix operator".to_string(),
2673 AstBuilderValidationErrorType::ReferenceError,
2674 lhs.get_meta().clone(),
2675 ))
2676 } else {
2677 Ok((
2678 if let Some(op_pair) = pair_iter.next() {
2679 ExpressionType::UpdateExpression {
2680 meta,
2681 operator: match op_pair.as_str() {
2682 "++" => UpdateOperator::PlusPlus,
2683 "--" => UpdateOperator::MinusMinus,
2684 _ => {
2685 return Err(get_unexpected_error(
2686 "build_ast_from_postfix_expression",
2687 &op_pair,
2688 ))
2689 }
2690 },
2691 argument: Box::new(lhs),
2692 prefix: false,
2693 }
2694 } else {
2695 lhs
2696 },
2697 lhs_s,
2698 ))
2699 }
2700}
2701
2702fn build_ast_from_call_expression(
2703 pair: Pair<Rule>,
2704 script: &Rc<String>,
2705) -> Result<(ExpressionType, Semantics), JsRuleError> {
2706 let mut pair_iter = pair.into_inner();
2707 let pair = pair_iter.next().unwrap();
2708 let meta = get_meta(&pair, script);
2709 let (mut obj, mut s) =
2710 if pair.as_rule() == Rule::super_call || pair.as_rule() == Rule::super_call__yield {
2711 let (a, a_s) = build_ast_from_arguments(pair.into_inner().next().unwrap(), script)?;
2712 (
2713 ExpressionType::CallExpression {
2714 meta,
2715 callee: ExpressionOrSuper::Super,
2716 arguments: a,
2717 },
2718 a_s,
2719 )
2720 } else {
2721 let arguments_pair = pair_iter.next().unwrap();
2722 let (m, mut s) = build_ast_from_member_expression(pair, script)?;
2723 let (a, a_s) = build_ast_from_arguments(arguments_pair, script)?;
2724 s.merge(a_s);
2725 (
2726 ExpressionType::CallExpression {
2727 meta,
2728 callee: ExpressionOrSuper::Expression(Box::new(m)),
2729 arguments: a,
2730 },
2731 s,
2732 )
2733 };
2734 for pair in pair_iter {
2735 let second_meta = get_meta(&pair, script);
2736 let meta = Meta {
2737 start_index: obj.get_meta().start_index,
2738 end_index: second_meta.end_index,
2739 script: script.clone(),
2740 };
2741 obj = match pair.as_rule() {
2742 Rule::expression__in_yield | Rule::expression__in => {
2743 let (e, e_s) = build_ast_from_expression(pair, script)?;
2744 s.merge(e_s);
2745 ExpressionType::MemberExpression(
2746 MemberExpressionType::ComputedMemberExpression {
2747 meta,
2748 object: ExpressionOrSuper::Expression(Box::new(obj)),
2749 property: Box::new(e),
2750 },
2751 )
2752 }
2753 Rule::identifier_name => ExpressionType::MemberExpression(
2754 MemberExpressionType::SimpleMemberExpression {
2755 meta,
2756 object: ExpressionOrSuper::Expression(Box::new(obj)),
2757 property: get_identifier_data(pair, script),
2758 },
2759 ),
2760 Rule::template_literal | Rule::template_literal__yield => {
2762 let (template, t_s) = build_ast_from_template_literal(pair, script)?;
2763 s.merge(t_s);
2764 let quasi = if let ExpressionType::TemplateLiteral(data) = template {
2765 data
2766 } else {
2767 return Err(get_validation_error_with_meta(
2768 "Expected template literal".to_string(),
2769 AstBuilderValidationErrorType::SyntaxError,
2770 meta.clone(),
2771 ));
2772 };
2773 ExpressionType::TaggedTemplateExpression {
2774 meta,
2775 tag: Box::new(obj),
2776 quasi,
2777 }
2778 }
2779 Rule::arguments | Rule::arguments__yield => {
2780 let (a, a_s) = build_ast_from_arguments(pair, script)?;
2781 s.merge(a_s);
2782 ExpressionType::CallExpression {
2783 meta,
2784 callee: ExpressionOrSuper::Expression(Box::new(obj)),
2785 arguments: a,
2786 }
2787 }
2788 _ => {
2789 return Err(get_unexpected_error(
2790 "build_ast_from_call_expression",
2791 &pair,
2792 ))
2793 }
2794 };
2795 }
2796 Ok((obj, s))
2797}
2798
2799fn get_binding_identifier_data(
2800 pair: Pair<Rule>,
2801 script: &Rc<String>,
2802) -> Result<(IdentifierData, Semantics), JsRuleError> {
2803 let mut id = get_identifier_data(pair, script);
2804 if id.name == "arguments" || id.name == "eval" || id.name == "yield" {
2805 Err(get_validation_error_with_meta(
2806 format!("Invalid binding identifier: {}", id.name),
2807 AstBuilderValidationErrorType::SyntaxError,
2808 id.meta,
2809 ))
2810 } else {
2811 id.is_binding_identifier = true;
2812 let mut s = Semantics::new_empty();
2813 s.bound_names.push(id.clone());
2814 Ok((id, s))
2815 }
2816}
2817
2818fn get_identifier_data(pair: Pair<Rule>, script: &Rc<String>) -> IdentifierData {
2819 IdentifierData {
2820 meta: get_meta(&pair, script),
2821 name: pair.as_str().trim().to_string(),
2822 is_binding_identifier: false,
2823 }
2824}
2825
2826fn build_ast_from_expression(
2827 pair: Pair<Rule>,
2828 script: &Rc<String>,
2829) -> Result<(ExpressionType, Semantics), JsRuleError> {
2830 let meta = get_meta(&pair, script);
2831 let mut node_children: Vec<Box<ExpressionType>> = vec![];
2832 let mut s = Semantics::new_empty();
2833 for inner_pair in pair.into_inner() {
2834 let (a, a_s) = build_ast_from_assignment_expression(inner_pair, script)?;
2835 s.merge(a_s);
2836 node_children.push(Box::new(a));
2837 }
2838 Ok((
2839 ExpressionType::SequenceExpression {
2840 meta,
2841 expressions: node_children,
2842 },
2843 s,
2844 ))
2845}
2846
2847fn build_ast_from_arguments(
2848 pair: Pair<Rule>,
2849 script: &Rc<String>,
2850) -> Result<(Vec<ExpressionOrSpreadElement>, Semantics), JsRuleError> {
2851 let mut arguments = vec![];
2852 let mut s = Semantics::new_empty();
2853 if let Some(argument_list_pair) = pair.into_inner().next() {
2854 for inner_pair in argument_list_pair.into_inner() {
2855 arguments.push(
2856 if inner_pair.as_rule() == Rule::rest_assignment_expression__in
2857 || inner_pair.as_rule() == Rule::rest_assignment_expression__in_yield
2858 {
2859 let (a, a_s) = build_ast_from_assignment_expression(
2860 inner_pair.into_inner().next().unwrap(),
2861 script,
2862 )?;
2863 s.merge(a_s);
2864 ExpressionOrSpreadElement::SpreadElement(Box::new(a))
2865 } else {
2866 let (a, a_s) = build_ast_from_assignment_expression(inner_pair, script)?;
2867 s.merge(a_s);
2868 ExpressionOrSpreadElement::Expression(Box::new(a))
2869 },
2870 );
2871 }
2872 }
2873 Ok((arguments, s))
2874}
2875
2876fn build_ast_from_member_expression(
2877 pair: Pair<Rule>,
2878 script: &Rc<String>,
2879) -> Result<(ExpressionType, Semantics), JsRuleError> {
2880 let meta = get_meta(&pair, script);
2881 let mut pair_iter = pair.into_inner();
2882 let pair_1 = pair_iter.next().unwrap();
2883 Ok(
2884 if pair_1.as_rule() == Rule::new_member_expression
2885 || pair_1.as_rule() == Rule::new_member_expression__yield
2886 {
2887 let member_expression_pair = pair_1.into_inner().next().unwrap();
2888 let arguments_pair = pair_iter.next().unwrap();
2889 let (m, mut s) = build_ast_from_member_expression(member_expression_pair, script)?;
2890 let (a, a_s) = build_ast_from_arguments(arguments_pair, script)?;
2891 s.merge(a_s);
2892 (
2893 ExpressionType::NewExpression {
2894 meta,
2895 callee: Box::new(m),
2896 arguments: a,
2897 },
2898 s,
2899 )
2900 } else {
2901 let mut s = Semantics::new_empty();
2902 let mut obj: ExpressionType = match pair_1.as_rule() {
2903 Rule::super_property | Rule::super_property__yield => {
2904 let super_pair = pair_1.into_inner().next().unwrap();
2905 if super_pair.as_rule() == Rule::identifier_name {
2906 ExpressionType::MemberExpression(
2907 MemberExpressionType::SimpleMemberExpression {
2908 meta,
2909 object: ExpressionOrSuper::Super,
2910 property: get_identifier_data(super_pair, script),
2911 },
2912 )
2913 } else {
2914 let (e, e_s) = build_ast_from_expression(super_pair, script)?;
2915 s.merge(e_s);
2916 ExpressionType::MemberExpression(
2917 MemberExpressionType::ComputedMemberExpression {
2918 meta,
2919 object: ExpressionOrSuper::Super,
2920 property: Box::new(e),
2921 },
2922 )
2923 }
2924 }
2925 Rule::meta_property => {
2926 let start = meta.start_index;
2927 let end = meta.end_index;
2928 ExpressionType::MetaProperty {
2929 meta,
2930 meta_object: IdentifierData {
2931 meta: Meta {
2932 start_index: start,
2933 end_index: start + 3,
2934 script: script.clone(),
2935 },
2936 name: "new".to_string(),
2937 is_binding_identifier: false,
2938 },
2939 property: IdentifierData {
2940 meta: Meta {
2941 start_index: start + 4,
2942 end_index: end,
2943 script: script.clone(),
2944 },
2945 name: "target".to_string(),
2946 is_binding_identifier: false,
2947 },
2948 }
2949 }
2950 Rule::primary_expression | Rule::primary_expression__yield => {
2951 let (p, p_s) = build_ast_from_primary_expression(pair_1, script)?;
2952 s.merge(p_s);
2953 p
2954 }
2955 _ => {
2956 return Err(get_unexpected_error(
2957 "build_ast_from_member_expression:1",
2958 &pair_1,
2959 ))
2960 }
2961 };
2962 for pair in pair_iter {
2963 let second_meta = get_meta(&pair, script);
2964 let meta = Meta {
2965 start_index: obj.get_meta().start_index,
2966 end_index: second_meta.end_index,
2967 script: script.clone(),
2968 };
2969 obj = match pair.as_rule() {
2970 Rule::expression__in_yield | Rule::expression__in => {
2971 let (st, st_s) = build_ast_from_expression(pair, script)?;
2972 s.merge(st_s);
2973 ExpressionType::MemberExpression(
2974 MemberExpressionType::ComputedMemberExpression {
2975 meta,
2976 object: ExpressionOrSuper::Expression(Box::new(obj)),
2977 property: Box::new(st),
2978 },
2979 )
2980 }
2981 Rule::identifier_name => ExpressionType::MemberExpression(
2982 MemberExpressionType::SimpleMemberExpression {
2983 meta,
2984 object: ExpressionOrSuper::Expression(Box::new(obj)),
2985 property: get_identifier_data(pair, script),
2986 },
2987 ),
2988 Rule::template_literal | Rule::template_literal__yield => {
2989 let (template, t_s) = build_ast_from_template_literal(pair, script)?;
2990 s.merge(t_s);
2991 let quasi = if let ExpressionType::TemplateLiteral(data) = template {
2992 data
2993 } else {
2994 return Err(get_validation_error_with_meta(
2995 "Expected template literal".to_string(),
2996 AstBuilderValidationErrorType::SyntaxError,
2997 meta.clone(),
2998 ));
2999 };
3000 ExpressionType::TaggedTemplateExpression {
3001 meta,
3002 tag: Box::new(obj),
3003 quasi,
3004 }
3005 }
3006 _ => {
3007 return Err(get_unexpected_error(
3008 "build_ast_from_member_expression:2",
3009 &pair,
3010 ))
3011 }
3012 };
3013 }
3014 (obj, s)
3015 },
3016 )
3017}
3018
3019fn build_ast_from_primary_expression(
3020 pair: Pair<Rule>,
3021 script: &Rc<String>,
3022) -> Result<(ExpressionType, Semantics), JsRuleError> {
3023 let inner_pair = pair.into_inner().next().unwrap();
3024 let meta = get_meta(&inner_pair, script);
3025 Ok(match inner_pair.as_rule() {
3026 Rule::identifier_reference | Rule::identifier_reference__yield => {
3027 let (i, i_s) = build_ast_from_identifier_reference(inner_pair, script)?;
3028 (i, i_s)
3029 }
3030 Rule::literal => (
3031 ExpressionType::Literal(build_ast_from_literal(inner_pair, script)?),
3032 Semantics::new_empty(),
3033 ),
3034 Rule::this_exp => (
3035 ExpressionType::ThisExpression { meta },
3036 Semantics::new_empty(),
3037 ),
3038 Rule::array_literal | Rule::array_literal__yield => {
3039 let (a, a_s) = build_ast_from_array_literal(inner_pair, script)?;
3040 (a, a_s)
3041 }
3042 Rule::object_literal | Rule::object_literal__yield => {
3043 build_ast_from_object_literal(inner_pair, script)?
3044 } Rule::generator_expression => {
3046 let (f, f_s) =
3047 build_ast_from_generator_declaration_or_generator_expression(inner_pair, script)?;
3048 (ExpressionType::FunctionOrGeneratorExpression(f), f_s)
3049 } Rule::function_expression => {
3051 let (f, f_s) =
3052 build_ast_from_function_declaration_or_function_expression(inner_pair, script)?;
3053 (ExpressionType::FunctionOrGeneratorExpression(f), f_s)
3054 }
3055 Rule::class_expression | Rule::class_expression__yield => {
3056 let (c, c_s) = build_ast_from_class_expression(inner_pair, script)?;
3057 (ExpressionType::ClassExpression(c), c_s)
3058 } Rule::regular_expression_literal => unimplemented!(), Rule::template_literal | Rule::template_literal__yield => {
3061 build_ast_from_template_literal(inner_pair, script)?
3062 } Rule::cover_parenthesized_expression_and_arrow_parameter_list
3064 | Rule::cover_parenthesized_expression_and_arrow_parameter_list__yield => {
3065 build_ast_from_cover_parenthesized_expression_and_arrow_parameter_list(
3066 inner_pair, script,
3067 )?
3068 }
3069 _ => {
3070 return Err(get_unexpected_error(
3071 "build_ast_from_primary_expression",
3072 &inner_pair,
3073 ))
3074 }
3075 })
3076}
3077
3078fn build_ast_from_cover_parenthesized_expression_and_arrow_parameter_list(
3079 pair: Pair<Rule>,
3080 script: &Rc<String>,
3081) -> Result<(ExpressionType, Semantics), JsRuleError> {
3082 let inner_pair = expect_inner(pair, "build_ast_from_cover_parenthesized_expression_and_arrow_parameter_list", script)?;
3083 build_ast_from_expression(inner_pair, script)
3084}
3085
3086fn build_ast_from_literal(
3087 pair: Pair<Rule>,
3088 script: &Rc<String>,
3089) -> Result<LiteralData, JsRuleError> {
3090 let inner_pair = expect_inner(pair, "build_ast_from_literal", script)?;
3091 let meta = get_meta(&inner_pair, script);
3092 Ok(match inner_pair.as_rule() {
3093 Rule::null_literal => LiteralData {
3094 meta,
3095 value: LiteralType::NullLiteral,
3096 },
3097 Rule::numeric_literal => LiteralData {
3098 meta,
3099 value: LiteralType::NumberLiteral(build_ast_from_numeric_literal(inner_pair)?),
3100 },
3101 Rule::string_literal => build_ast_from_string_literal(inner_pair, script)?,
3102 Rule::boolean_literal => {
3103 let bool = inner_pair.as_str();
3104 LiteralData {
3105 meta,
3106 value: LiteralType::BooleanLiteral(bool == "true"),
3107 }
3108 }
3109 _ => return Err(get_unexpected_error("build_ast_from_literal", &inner_pair)),
3110 })
3111}
3112
3113fn build_ast_from_string_literal(
3114 pair: Pair<Rule>,
3115 script: &Rc<String>,
3116) -> Result<LiteralData, JsRuleError> {
3117 let meta = get_meta(&pair, script);
3118 let s = pair.as_str();
3119 Ok(LiteralData {
3120 meta,
3121 value: LiteralType::StringLiteral(String::from(&s[1..s.len() - 1])),
3122 })
3123}
3124
3125fn build_ast_from_template_literal(
3130 pair: Pair<Rule>,
3131 script: &Rc<String>,
3132) -> Result<(ExpressionType, Semantics), JsRuleError> {
3133 let meta = get_meta(&pair, script);
3134 let mut quasis: Vec<TemplateElementData> = vec![];
3135 let mut expressions: Vec<Box<ExpressionType>> = vec![];
3136 let mut s = Semantics::new_empty();
3137
3138 for inner_pair in pair.into_inner() {
3139 match inner_pair.as_rule() {
3140 Rule::no_substitution_template => {
3141 let raw_str = inner_pair.as_str();
3143 let content = &raw_str[1..raw_str.len() - 1];
3145 let quasi_meta = get_meta(&inner_pair, script);
3146 quasis.push(TemplateElementData {
3147 meta: quasi_meta,
3148 tail: true,
3149 cooked_value: process_template_escapes(content),
3150 raw_value: content.to_string(),
3151 });
3152 }
3153 Rule::template_head => {
3154 let raw_str = inner_pair.as_str();
3156 let content = &raw_str[1..raw_str.len() - 2];
3158 let quasi_meta = get_meta(&inner_pair, script);
3159 quasis.push(TemplateElementData {
3160 meta: quasi_meta,
3161 tail: false,
3162 cooked_value: process_template_escapes(content),
3163 raw_value: content.to_string(),
3164 });
3165 }
3166 Rule::template_middle => {
3167 let raw_str = inner_pair.as_str();
3169 let content = &raw_str[1..raw_str.len() - 2];
3171 let quasi_meta = get_meta(&inner_pair, script);
3172 quasis.push(TemplateElementData {
3173 meta: quasi_meta,
3174 tail: false,
3175 cooked_value: process_template_escapes(content),
3176 raw_value: content.to_string(),
3177 });
3178 }
3179 Rule::template_tail => {
3180 let raw_str = inner_pair.as_str();
3182 let content = &raw_str[1..raw_str.len() - 1];
3184 let quasi_meta = get_meta(&inner_pair, script);
3185 quasis.push(TemplateElementData {
3186 meta: quasi_meta,
3187 tail: true,
3188 cooked_value: process_template_escapes(content),
3189 raw_value: content.to_string(),
3190 });
3191 }
3192 Rule::expression__in | Rule::expression__in_yield => {
3193 let (expr, expr_s) = build_ast_from_expression(inner_pair, script)?;
3194 s.merge(expr_s);
3195 expressions.push(Box::new(expr));
3196 }
3197 _ => {
3198 return Err(get_unexpected_error(
3199 "build_ast_from_template_literal",
3200 &inner_pair,
3201 ))
3202 }
3203 }
3204 }
3205
3206 Ok((
3207 ExpressionType::TemplateLiteral(TemplateLiteralData {
3208 meta,
3209 quasis,
3210 expressions,
3211 }),
3212 s,
3213 ))
3214}
3215
3216fn process_template_escapes(s: &str) -> String {
3218 let mut result = String::with_capacity(s.len());
3219 let mut chars = s.chars().peekable();
3220
3221 while let Some(c) = chars.next() {
3222 if c == '\\' {
3223 match chars.next() {
3224 Some('n') => result.push('\n'),
3225 Some('r') => result.push('\r'),
3226 Some('t') => result.push('\t'),
3227 Some('\\') => result.push('\\'),
3228 Some('`') => result.push('`'),
3229 Some('$') => result.push('$'),
3230 Some('0') => result.push('\0'),
3231 Some('\'') => result.push('\''),
3232 Some('"') => result.push('"'),
3233 Some('x') => {
3234 let mut hex = String::new();
3236 for _ in 0..2 {
3237 if let Some(&c) = chars.peek() {
3238 if c.is_ascii_hexdigit() {
3239 hex.push(chars.next().unwrap());
3240 }
3241 }
3242 }
3243 if hex.len() == 2 {
3244 if let Ok(val) = u8::from_str_radix(&hex, 16) {
3245 result.push(val as char);
3246 }
3247 }
3248 }
3249 Some('u') => {
3250 if chars.peek() == Some(&'{') {
3252 chars.next(); let mut hex = String::new();
3254 while let Some(&c) = chars.peek() {
3255 if c == '}' {
3256 chars.next();
3257 break;
3258 }
3259 if c.is_ascii_hexdigit() {
3260 hex.push(chars.next().unwrap());
3261 } else {
3262 break;
3263 }
3264 }
3265 if let Ok(val) = u32::from_str_radix(&hex, 16) {
3266 if let Some(ch) = char::from_u32(val) {
3267 result.push(ch);
3268 }
3269 }
3270 } else {
3271 let mut hex = String::new();
3272 for _ in 0..4 {
3273 if let Some(&c) = chars.peek() {
3274 if c.is_ascii_hexdigit() {
3275 hex.push(chars.next().unwrap());
3276 }
3277 }
3278 }
3279 if hex.len() == 4 {
3280 if let Ok(val) = u16::from_str_radix(&hex, 16) {
3281 result.push(char::from_u32(val as u32).unwrap_or('\u{FFFD}'));
3282 }
3283 }
3284 }
3285 }
3286 Some(other) => {
3287 result.push(other);
3289 }
3290 None => {
3291 result.push('\\');
3293 }
3294 }
3295 } else {
3296 result.push(c);
3297 }
3298 }
3299
3300 result
3301}
3302
3303fn build_ast_from_str_numeric_literal(
3304 pair: Pair<Rule>,
3305) -> Result<ExtendedNumberLiteralType, JsRuleError> {
3306 let inner_pair = pair.into_inner().next().unwrap();
3307 Ok(match inner_pair.as_rule() {
3308 Rule::binary_integer_literal => {
3309 ExtendedNumberLiteralType::Std(get_ast_for_binary_integer_literal(inner_pair))
3310 }
3311 Rule::octal_integer_literal => {
3312 ExtendedNumberLiteralType::Std(get_ast_for_octal_integer_literal(inner_pair))
3313 }
3314 Rule::hex_integer_literal => {
3315 ExtendedNumberLiteralType::Std(get_ast_for_hex_integer_literal(inner_pair))
3316 }
3317 Rule::str_decimal_literal => build_ast_str_decimal_literal(inner_pair)?,
3318 _ => {
3319 return Err(get_unexpected_error(
3320 "build_ast_from_str_numeric_literal",
3321 &inner_pair,
3322 ))
3323 }
3324 })
3325}
3326
3327fn build_ast_str_decimal_literal(
3328 pair: Pair<Rule>,
3329) -> Result<ExtendedNumberLiteralType, JsRuleError> {
3330 let mut pair_iter = pair.into_inner();
3331 let mut inner_pair = pair_iter.next().unwrap();
3332 let is_negative = if inner_pair.as_rule() == Rule::str_negative_op {
3333 inner_pair = pair_iter.next().unwrap();
3334 true
3335 } else {
3336 false
3337 };
3338 build_ast_str_unsigned_decimal_literal(inner_pair, is_negative)
3339}
3340
3341fn build_ast_str_unsigned_decimal_literal(
3342 pair: Pair<Rule>,
3343 is_negative: bool,
3344) -> Result<ExtendedNumberLiteralType, JsRuleError> {
3345 let mut num: f64 = 0.0;
3346 let mut is_float = false;
3347 for decimal_pair in pair.into_inner() {
3348 num = match decimal_pair.as_rule() {
3349 Rule::str_decimal_literal_infinity => {
3350 return Ok(if is_negative {
3351 ExtendedNumberLiteralType::NegativeInfinity
3352 } else {
3353 ExtendedNumberLiteralType::Infinity
3354 });
3355 }
3356 Rule::decimal_digits_integer_part => parse_decimal_integer_literal(decimal_pair),
3357 Rule::decimal_digits => {
3358 is_float = true;
3359 num + parse_decimal_digits(decimal_pair)
3360 }
3361 Rule::exponent_part => num * parse_exponent_part(decimal_pair),
3362 _ => {
3363 return Err(get_unexpected_error(
3364 "build_ast_str_unsigned_decimal_literal",
3365 &decimal_pair,
3366 ))
3367 }
3368 }
3369 }
3370 if is_negative {
3371 num *= -1.0;
3372 }
3373 Ok(if !is_float {
3374 ExtendedNumberLiteralType::Std(NumberLiteralType::IntegerLiteral(num as i64))
3375 } else {
3376 ExtendedNumberLiteralType::Std(NumberLiteralType::FloatLiteral(num))
3377 })
3378}
3379
3380fn get_ast_for_binary_integer_literal(pair: Pair<Rule>) -> NumberLiteralType {
3381 NumberLiteralType::IntegerLiteral(isize::from_str_radix(&pair.as_str()[2..], 2).unwrap() as i64)
3382}
3383
3384fn get_ast_for_octal_integer_literal(pair: Pair<Rule>) -> NumberLiteralType {
3385 NumberLiteralType::IntegerLiteral(isize::from_str_radix(&pair.as_str()[2..], 8).unwrap() as i64)
3386}
3387
3388fn get_ast_for_hex_integer_literal(pair: Pair<Rule>) -> NumberLiteralType {
3389 NumberLiteralType::IntegerLiteral(isize::from_str_radix(&pair.as_str()[2..], 16).unwrap() as i64)
3390}
3391
3392fn parse_decimal_integer_literal(decimal_pair: Pair<Rule>) -> f64 {
3393 isize::from_str_radix(decimal_pair.as_str(), 10).unwrap() as f64
3394}
3395
3396fn parse_decimal_digits(decimal_pair: Pair<Rule>) -> f64 {
3397 let d = decimal_pair.as_str();
3398 isize::from_str_radix(d, 10).unwrap() as f64 / 10_f64.powf(d.len() as f64)
3399}
3400
3401fn parse_exponent_part(decimal_pair: Pair<Rule>) -> f64 {
3402 10_f64.powf(isize::from_str_radix(&decimal_pair.as_str()[1..], 10).unwrap() as f64)
3403}
3404
3405fn build_ast_decimal_literal(pair: Pair<Rule>) -> Result<NumberLiteralType, JsRuleError> {
3406 let mut num: f64 = 0.0;
3407 let mut is_float = false;
3408 for decimal_pair in pair.into_inner() {
3409 num = match decimal_pair.as_rule() {
3410 Rule::decimal_integer_literal => parse_decimal_integer_literal(decimal_pair),
3411 Rule::decimal_digits => {
3412 is_float = true;
3413 num + parse_decimal_digits(decimal_pair)
3414 }
3415 Rule::exponent_part => num * parse_exponent_part(decimal_pair),
3416 _ => {
3417 return Err(get_unexpected_error(
3418 "build_ast_decimal_literal",
3419 &decimal_pair,
3420 ))
3421 }
3422 }
3423 }
3424 Ok(if !is_float {
3425 NumberLiteralType::IntegerLiteral(num as i64)
3426 } else {
3427 NumberLiteralType::FloatLiteral(num)
3428 })
3429}
3430
3431fn build_ast_from_numeric_literal(pair: Pair<Rule>) -> Result<NumberLiteralType, JsRuleError> {
3432 let inner_pair = pair.into_inner().next().unwrap();
3433 Ok(match inner_pair.as_rule() {
3434 Rule::binary_integer_literal => get_ast_for_binary_integer_literal(inner_pair),
3435 Rule::octal_integer_literal => get_ast_for_octal_integer_literal(inner_pair),
3436 Rule::hex_integer_literal => get_ast_for_hex_integer_literal(inner_pair),
3437 Rule::decimal_literal => build_ast_decimal_literal(inner_pair)?,
3438 _ => {
3439 return Err(get_unexpected_error(
3440 "build_ast_from_numeric_literal",
3441 &inner_pair,
3442 ))
3443 }
3444 })
3445}
3446
3447fn build_ast_from_array_literal(
3448 pair: Pair<Rule>,
3449 script: &Rc<String>,
3450) -> Result<(ExpressionType, Semantics), JsRuleError> {
3451 let meta = get_meta(&pair, script);
3452 let mut arguments = vec![];
3453 let mut s = Semantics::new_empty();
3454 for inner_pair in pair.into_inner() {
3455 match inner_pair.as_rule() {
3456 Rule::elision => {
3457 for _ in 0..(inner_pair.as_str().matches(',').count()) {
3458 arguments.push(None);
3459 }
3460 }
3461 Rule::assignment_expression__in | Rule::assignment_expression__in_yield => {
3462 let (a, a_s) = build_ast_from_assignment_expression(inner_pair, script)?;
3463 s.merge(a_s);
3464 arguments.push(Some(ExpressionOrSpreadElement::Expression(Box::new(a))));
3465 }
3466 Rule::spread_element | Rule::spread_element__yield => {
3467 let spread_inner = expect_inner(inner_pair, "spread_element", script)?;
3468 let (a, a_s) = build_ast_from_assignment_expression(spread_inner, script)?;
3469 s.merge(a_s);
3470 arguments.push(Some(ExpressionOrSpreadElement::SpreadElement(Box::new(a))));
3471 }
3472 _ => {
3473 return Err(get_unexpected_error(
3474 "build_ast_from_array_literal",
3475 &inner_pair,
3476 ))
3477 }
3478 }
3479 }
3480 Ok((
3481 ExpressionType::ArrayExpression {
3482 meta,
3483 elements: arguments,
3484 },
3485 s,
3486 ))
3487}
3488
3489fn build_ast_from_object_literal(
3490 pair: Pair<Rule>,
3491 script: &Rc<String>,
3492) -> Result<(ExpressionType, Semantics), JsRuleError> {
3493 let meta = get_meta(&pair, script);
3494 let mut s = Semantics::new_empty();
3495 let mut properties = vec![];
3496 for property_pair in pair.into_inner() {
3497 let (p, p_s) = build_ast_from_property_definition(property_pair, script)?;
3498 s.merge(p_s);
3499 properties.push(p);
3500 }
3501 Ok((ExpressionType::ObjectExpression { meta, properties }, s))
3502}
3503
3504fn build_ast_from_property_definition(
3505 pair: Pair<Rule>,
3506 script: &Rc<String>,
3507) -> Result<(PropertyData<Box<ExpressionType>>, Semantics), JsRuleError> {
3508 let meta = get_meta(&pair, script);
3509 let mut s = Semantics::new_empty();
3510 let mut inner_pair_iter = pair.into_inner();
3511 let inner_pair = inner_pair_iter.next().unwrap();
3512 let p = match inner_pair.as_rule() {
3513 Rule::property_name | Rule::property_name__yield => {
3514 let (p, p_s) = build_ast_from_property_name(inner_pair, script)?;
3515 let (a, a_s) =
3516 build_ast_from_assignment_expression(inner_pair_iter.next().unwrap(), script)?;
3517 s.merge(p_s).merge(a_s);
3518 PropertyData::new_with_any_expression_key(
3519 meta,
3520 p,
3521 Box::new(a),
3522 PropertyKind::Init,
3523 false,
3524 false,
3525 )
3526 }
3527 Rule::cover_initialized_name | Rule::cover_initialized_name__yield => {
3528 let error = format!("Initialization is only possible for object destruction pattern not in object literal: {}", inner_pair.as_str());
3529 return Err(get_validation_error(
3530 error,
3531 AstBuilderValidationErrorType::SyntaxError,
3532 &inner_pair,
3533 &script,
3534 ));
3535 }
3536 Rule::method_definition | Rule::method_definition__yield => {
3537 let meta = get_meta(&inner_pair, script);
3538 let (m, m_s) = build_ast_from_method_definition(inner_pair, script)?;
3539 if m_s.has_direct_super.is_true() {
3540 return Err(get_validation_error_with_meta(
3541 "Invalid reference to super".to_string(),
3542 AstBuilderValidationErrorType::SyntaxError,
3543 meta,
3544 ));
3545 }
3546 s.merge(m_s);
3547 m
3548 }
3549 Rule::identifier_reference | Rule::identifier_reference__yield => {
3550 let id = get_identifier_data(inner_pair, script);
3551 let id2 = id.clone();
3552 PropertyData::new_with_identifier_key(
3553 meta,
3554 id,
3555 Box::new(ExpressionPatternType::Identifier(id2).convert_to_expression()),
3556 PropertyKind::Init,
3557 false,
3558 true,
3559 )
3560 }
3561 _ => {
3562 return Err(get_unexpected_error(
3563 "build_ast_from_property_definition",
3564 &inner_pair,
3565 ))
3566 }
3567 };
3568 Ok((p, s))
3569}
3570
3571fn build_ast_from_method_definition(
3572 pair: Pair<Rule>,
3573 script: &Rc<String>,
3574) -> Result<(PropertyData<Box<ExpressionType>>, Semantics), JsRuleError> {
3575 let meta = get_meta(&pair, script);
3576 let mut s = Semantics::new_empty();
3577 let mut inner_iter = pair.into_inner();
3578 let inner_pair = inner_iter.next().unwrap();
3579 let m = match inner_pair.as_rule() {
3580 Rule::property_name | Rule::property_name__yield => {
3581 let (p, p_s) = build_ast_from_property_name(inner_pair, script)?;
3582 let (fp, fp_s) = build_ast_from_formal_parameters(inner_iter.next().unwrap(), script)?;
3583 let (fb, fb_s) = build_ast_from_function_body(inner_iter.next().unwrap(), script)?;
3584 validate_bound_names_have_no_duplicates_and_also_not_present_in_var_declared_names_or_lexically_declared_names(&fp_s.bound_names,&vec![],&fb_s.lexically_declared_names)?;
3585 s.merge(p_s).merge(fp_s).merge(fb_s);
3586 let meta2 = meta.clone();
3587 PropertyData::new_with_any_expression_key(
3588 meta,
3589 p,
3590 Box::new(ExpressionType::FunctionOrGeneratorExpression(
3591 FunctionData {
3592 meta: meta2,
3593 id: None,
3594 params: FormalParameters::new(fp),
3595 body: Box::new(fb),
3596 generator: false,
3597 },
3598 )),
3599 PropertyKind::Init,
3600 true,
3601 false,
3602 )
3603 }
3604 Rule::generator_method | Rule::generator_method__yield => {
3605 let mut inner_inner_iter = inner_pair.into_inner();
3606 let (p, p_s) = build_ast_from_property_name(inner_inner_iter.next().unwrap(), script)?;
3607 let (fp, fp_s) =
3608 build_ast_from_formal_parameters(inner_inner_iter.next().unwrap(), script)?;
3609 let (fb, fb_s) =
3610 build_ast_from_generator_body(inner_inner_iter.next().unwrap(), script)?;
3611 if fb_s.has_direct_super.is_true() {
3612 return Err(get_validation_error_with_meta(
3613 "Invalid reference to 'super'".to_string(),
3614 AstBuilderValidationErrorType::SyntaxError,
3615 meta.clone(),
3616 ));
3617 }
3618 validate_bound_names_have_no_duplicates_and_also_not_present_in_var_declared_names_or_lexically_declared_names(&fp_s.bound_names,&vec![],&fb_s.lexically_declared_names)?;
3619 s.merge(p_s).merge(fp_s).merge(fb_s);
3620 let meta2 = meta.clone();
3621 PropertyData::new_with_any_expression_key(
3622 meta,
3623 p,
3624 Box::new(ExpressionType::FunctionOrGeneratorExpression(
3625 FunctionData {
3626 meta: meta2,
3627 id: None,
3628 params: FormalParameters::new(fp),
3629 body: Box::new(fb),
3630 generator: true,
3631 },
3632 )),
3633 PropertyKind::Init,
3634 true,
3635 false,
3636 )
3637 }
3638 Rule::getter => {
3639 let (p, p_s) = build_ast_from_property_name(inner_iter.next().unwrap(), script)?;
3640 let (fb, fb_s) = build_ast_from_function_body(inner_iter.next().unwrap(), script)?;
3641 s.merge(p_s).merge(fb_s);
3642 let meta2 = meta.clone();
3643 PropertyData::new_with_any_expression_key(
3644 meta,
3645 p,
3646 Box::new(ExpressionType::FunctionOrGeneratorExpression(
3647 FunctionData {
3648 meta: meta2,
3649 id: None,
3650 params: FormalParameters::new(vec![]),
3651 body: Box::new(fb),
3652 generator: false,
3653 },
3654 )),
3655 PropertyKind::Get,
3656 false,
3657 false,
3658 )
3659 }
3660 Rule::setter => {
3661 let (p, p_s) = build_ast_from_property_name(inner_iter.next().unwrap(), script)?;
3662 let (fp, fp_s) = build_ast_from_single_formal_parameter(inner_iter.next().unwrap(), script)?;
3664 let (fb, fb_s) = build_ast_from_function_body(inner_iter.next().unwrap(), script)?;
3665 validate_bound_names_have_no_duplicates_and_also_not_present_in_var_declared_names_or_lexically_declared_names(&fp_s.bound_names,&vec![],&fb_s.lexically_declared_names)?;
3666 s.merge(p_s).merge(fp_s).merge(fb_s);
3667 let meta2 = meta.clone();
3668 PropertyData::new_with_any_expression_key(
3669 meta,
3670 p,
3671 Box::new(ExpressionType::FunctionOrGeneratorExpression(
3672 FunctionData {
3673 meta: meta2,
3674 id: None,
3675 params: FormalParameters::new(fp),
3676 body: Box::new(fb),
3677 generator: false,
3678 },
3679 )),
3680 PropertyKind::Set,
3681 false,
3682 false,
3683 )
3684 }
3685 _ => {
3686 return Err(get_unexpected_error(
3687 "build_ast_from_method_definition",
3688 &inner_pair,
3689 ))
3690 }
3691 };
3692 Ok((m, s))
3693}
3694
3695fn build_ast_from_identifier_reference(
3696 pair: Pair<Rule>,
3697 script: &Rc<String>,
3698) -> Result<(ExpressionType, Semantics), JsRuleError> {
3699 let id = pair.as_str();
3700 if id == "yield" {
3701 Err(get_validation_error(
3702 format!("Invalid identifier reference: {}", id),
3703 AstBuilderValidationErrorType::SyntaxError,
3704 &pair,
3705 &script,
3706 ))
3707 } else {
3708 let s = Semantics::new_empty();
3709 Ok((
3710 ExpressionPatternType::Identifier(get_identifier_data(pair, script))
3711 .convert_to_expression(),
3712 s,
3713 ))
3714 }
3715}
3716
3717fn build_ast_from_class_declaration(
3720 pair: Pair<Rule>,
3721 script: &Rc<String>,
3722) -> Result<(ClassData, Semantics), JsRuleError> {
3723 let meta = get_meta(&pair, script);
3724 let mut pair_iter = pair.into_inner();
3725 let mut s = Semantics::new_empty();
3726
3727 let id_pair = pair_iter.next().ok_or_else(|| {
3729 get_validation_error_with_meta(
3730 "Expected class name".to_string(),
3731 AstBuilderValidationErrorType::SyntaxError,
3732 meta.clone(),
3733 )
3734 })?;
3735 let (id, id_s) = get_binding_identifier_data(id_pair, script)?;
3736 s.merge(id_s);
3737
3738 let class_tail_pair = pair_iter.next().ok_or_else(|| {
3740 get_validation_error_with_meta(
3741 "Expected class body".to_string(),
3742 AstBuilderValidationErrorType::SyntaxError,
3743 meta.clone(),
3744 )
3745 })?;
3746 let (super_class, body, tail_s) = build_ast_from_class_tail(class_tail_pair, script)?;
3747 s.merge(tail_s);
3748
3749 Ok((
3750 ClassData {
3751 meta,
3752 id: Some(id),
3753 super_class,
3754 body,
3755 },
3756 s,
3757 ))
3758}
3759
3760fn build_ast_from_class_expression(
3763 pair: Pair<Rule>,
3764 script: &Rc<String>,
3765) -> Result<(ClassData, Semantics), JsRuleError> {
3766 let meta = get_meta(&pair, script);
3767 let mut pair_iter = pair.into_inner();
3768 let mut s = Semantics::new_empty();
3769
3770 let first_pair = pair_iter.next();
3772 let (id, class_tail_pair) = if let Some(fp) = first_pair {
3773 if fp.as_rule() == Rule::binding_identifier || fp.as_rule() == Rule::binding_identifier__yield
3774 {
3775 let (id, _id_s) = get_binding_identifier_data(fp, script)?;
3776 let tail = pair_iter.next().ok_or_else(|| {
3778 get_validation_error_with_meta(
3779 "Expected class body".to_string(),
3780 AstBuilderValidationErrorType::SyntaxError,
3781 meta.clone(),
3782 )
3783 })?;
3784 (Some(id), tail)
3785 } else {
3786 (None, fp)
3788 }
3789 } else {
3790 return Err(get_validation_error_with_meta(
3791 "Expected class body".to_string(),
3792 AstBuilderValidationErrorType::SyntaxError,
3793 meta.clone(),
3794 ));
3795 };
3796
3797 let (super_class, body, tail_s) = build_ast_from_class_tail(class_tail_pair, script)?;
3798 s.merge(tail_s);
3799
3800 Ok((
3801 ClassData {
3802 meta,
3803 id,
3804 super_class,
3805 body,
3806 },
3807 s,
3808 ))
3809}
3810
3811fn build_ast_from_class_tail(
3814 pair: Pair<Rule>,
3815 script: &Rc<String>,
3816) -> Result<(Option<Box<ExpressionType>>, ClassBodyData, Semantics), JsRuleError> {
3817 let meta = get_meta(&pair, script);
3818 let mut s = Semantics::new_empty();
3819 let mut super_class = None;
3820 let mut methods: Vec<MethodDefinitionData> = vec![];
3821
3822 for inner_pair in pair.into_inner() {
3823 match inner_pair.as_rule() {
3824 Rule::class_heritage | Rule::class_heritage__yield => {
3825 let lhs_pair = inner_pair.into_inner().next().ok_or_else(|| {
3827 get_validation_error_with_meta(
3828 "Expected superclass expression".to_string(),
3829 AstBuilderValidationErrorType::SyntaxError,
3830 meta.clone(),
3831 )
3832 })?;
3833 let (expr, expr_s) = build_ast_from_left_hand_side_expression(lhs_pair, script)?;
3834 s.merge(expr_s);
3835 super_class = Some(Box::new(expr));
3836 }
3837 Rule::class_body | Rule::class_body__yield => {
3838 for element_pair in inner_pair.into_inner() {
3840 if let Some(method) =
3841 build_ast_from_class_element(element_pair, script, &mut s)?
3842 {
3843 methods.push(method);
3844 }
3845 }
3846 }
3847 _ => {
3848 return Err(get_unexpected_error("build_ast_from_class_tail", &inner_pair))
3849 }
3850 }
3851 }
3852
3853 Ok((
3854 super_class,
3855 ClassBodyData { meta, body: methods },
3856 s,
3857 ))
3858}
3859
3860fn build_ast_from_class_element(
3863 pair: Pair<Rule>,
3864 script: &Rc<String>,
3865 s: &mut Semantics,
3866) -> Result<Option<MethodDefinitionData>, JsRuleError> {
3867 let meta = get_meta(&pair, script);
3868 let mut inner_iter = pair.into_inner();
3869
3870 let first_pair = match inner_iter.next() {
3872 Some(p) => p,
3873 None => return Ok(None), };
3875
3876 let (is_static, method_pair) = if first_pair.as_rule() == Rule::class_static {
3877 let mp = inner_iter.next().ok_or_else(|| {
3878 get_validation_error_with_meta(
3879 "Expected method definition after 'static'".to_string(),
3880 AstBuilderValidationErrorType::SyntaxError,
3881 meta.clone(),
3882 )
3883 })?;
3884 (true, mp)
3885 } else {
3886 (false, first_pair)
3887 };
3888
3889 let (prop_data, method_s) = build_ast_from_method_definition(method_pair, script)?;
3891 s.merge(method_s);
3892
3893 let PropertyData {
3895 meta: prop_meta,
3896 key,
3897 value,
3898 kind,
3899 method: _,
3900 shorthand: _,
3901 computed,
3902 } = prop_data;
3903
3904 let func_data = match *value {
3906 ExpressionType::FunctionOrGeneratorExpression(f) => f,
3907 _ => {
3908 return Err(get_validation_error_with_meta(
3909 "Expected function in method definition".to_string(),
3910 AstBuilderValidationErrorType::SyntaxError,
3911 prop_meta.clone(),
3912 ));
3913 }
3914 };
3915
3916 let method_kind = match kind {
3918 PropertyKind::Init => {
3919 if let ExpressionType::ExpressionWhichCanBePattern(ExpressionPatternType::Identifier(
3921 ref id,
3922 )) = *key
3923 {
3924 if id.name == "constructor" && !is_static {
3925 MethodDefinitionKind::Constructor
3926 } else {
3927 MethodDefinitionKind::Method
3928 }
3929 } else {
3930 MethodDefinitionKind::Method
3931 }
3932 }
3933 PropertyKind::Get => MethodDefinitionKind::Get,
3934 PropertyKind::Set => MethodDefinitionKind::Set,
3935 };
3936
3937 Ok(Some(MethodDefinitionData {
3938 meta: prop_meta,
3939 key,
3940 value: func_data,
3941 kind: method_kind,
3942 computed,
3943 static_flag: is_static,
3944 }))
3945}