fix(es/parser): Fix parsing of > in typescript mode (#7407)

**Related issue:**

 - Closes #7403.
This commit is contained in:
Donny/강동윤 2023-05-18 17:18:27 +09:00 committed by GitHub
parent 9440f4b196
commit 57ad722d06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1251 additions and 15 deletions

View File

@ -637,6 +637,15 @@ impl<'a> Lexer<'a> {
let c = self.cur().unwrap(); let c = self.cur().unwrap();
self.bump(); self.bump();
if self.syntax.typescript() && self.ctx.in_type && !self.ctx.should_not_lex_lt_or_gt_as_type
{
if c == '<' {
return Ok(Some(tok!('<')));
} else if c == '>' {
return Ok(Some(tok!('>')));
}
}
// XML style comment. `<!--` // XML style comment. `<!--`
if c == '<' && self.is(b'!') && self.peek() == Some('-') && self.peek_ahead() == Some('-') { if c == '<' && self.is(b'!') && self.peek() == Some('-') && self.peek_ahead() == Some('-') {
self.skip_line_comment(3); self.skip_line_comment(3);

View File

@ -217,8 +217,8 @@ impl<'a> Iterator for Lexer<'a> {
start = self.input.cur_pos(); start = self.input.cur_pos();
}; };
let c = match self.input.cur() { match self.input.cur() {
Some(c) => c, Some(..) => {}
// End of input. // End of input.
None => { None => {
if let Some(comments) = self.comments.as_mut() { if let Some(comments) = self.comments.as_mut() {
@ -324,16 +324,6 @@ impl<'a> Iterator for Lexer<'a> {
return self.read_tmpl_token(start_pos_of_tpl).map(Some); return self.read_tmpl_token(start_pos_of_tpl).map(Some);
} }
if self.syntax.typescript() && self.ctx.in_type {
if c == '<' {
self.input.bump();
return Ok(Some(tok!('<')));
} else if c == '>' {
self.input.bump();
return Ok(Some(tok!('>')));
}
}
self.read_token() self.read_token()
})(); })();

View File

@ -383,6 +383,8 @@ pub struct Context {
in_type: bool, in_type: bool,
/// Typescript extension. /// Typescript extension.
should_not_lex_lt_or_gt_as_type: bool,
/// Typescript extension.
in_declare: bool, in_declare: bool,
/// If true, `:` should not be treated as a type annotation. /// If true, `:` should not be treated as a type annotation.

View File

@ -565,6 +565,15 @@ impl<I: Tokens> Parser<I> {
/// `is_new_expr`: true iff we are parsing production 'NewExpression'. /// `is_new_expr`: true iff we are parsing production 'NewExpression'.
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))] #[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn parse_member_expr_or_new_expr(&mut self, is_new_expr: bool) -> PResult<Box<Expr>> { fn parse_member_expr_or_new_expr(&mut self, is_new_expr: bool) -> PResult<Box<Expr>> {
let ctx = Context {
should_not_lex_lt_or_gt_as_type: true,
..self.ctx()
};
self.with_ctx(ctx)
.parse_member_expr_or_new_expr_inner(is_new_expr)
}
fn parse_member_expr_or_new_expr_inner(&mut self, is_new_expr: bool) -> PResult<Box<Expr>> {
trace_cur!(self, parse_member_expr_or_new_expr); trace_cur!(self, parse_member_expr_or_new_expr);
let start = cur_pos!(self); let start = cur_pos!(self);
@ -622,7 +631,12 @@ impl<I: Tokens> Parser<I> {
let type_args = if self.input.syntax().typescript() && is!(self, '<') { let type_args = if self.input.syntax().typescript() && is!(self, '<') {
self.try_parse_ts(|p| { self.try_parse_ts(|p| {
let args = p.parse_ts_type_args()?; let ctx = Context {
should_not_lex_lt_or_gt_as_type: false,
..p.ctx()
};
let args = p.with_ctx(ctx).parse_ts_type_args()?;
if !is!(p, '(') { if !is!(p, '(') {
// This will fail // This will fail
expect!(p, '('); expect!(p, '(');
@ -680,6 +694,7 @@ impl<I: Tokens> Parser<I> {
None None
}; };
let obj = if let Some(type_args) = type_args { let obj = if let Some(type_args) = type_args {
trace_cur!(self, parse_member_expr_or_new_expr__with_type_args);
Box::new(Expr::TsInstantiation(TsInstantiation { Box::new(Expr::TsInstantiation(TsInstantiation {
expr: obj, expr: obj,
type_args, type_args,
@ -1102,6 +1117,7 @@ impl<I: Tokens> Parser<I> {
}) })
} }
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
pub(super) fn parse_subscripts( pub(super) fn parse_subscripts(
&mut self, &mut self,
mut obj: Callee, mut obj: Callee,
@ -1118,6 +1134,7 @@ impl<I: Tokens> Parser<I> {
} }
/// returned bool is true if this method should be called again. /// returned bool is true if this method should be called again.
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn parse_subscript( fn parse_subscript(
&mut self, &mut self,
start: BytePos, start: BytePos,
@ -1125,6 +1142,7 @@ impl<I: Tokens> Parser<I> {
no_call: bool, no_call: bool,
no_computed_member: bool, no_computed_member: bool,
) -> PResult<(Box<Expr>, bool)> { ) -> PResult<(Box<Expr>, bool)> {
trace_cur!(self, parse_subscript);
let _ = cur!(self, false); let _ = cur!(self, false);
if self.input.syntax().typescript() { if self.input.syntax().typescript() {
@ -1169,7 +1187,11 @@ impl<I: Tokens> Parser<I> {
let mut_obj_opt = &mut obj_opt; let mut_obj_opt = &mut obj_opt;
let result = self.try_parse_ts(|p| { let ctx: Context = Context {
should_not_lex_lt_or_gt_as_type: true,
..self.ctx()
};
let result = self.with_ctx(ctx).try_parse_ts(|p| {
if !no_call if !no_call
&& p.at_possible_async(match &mut_obj_opt { && p.at_possible_async(match &mut_obj_opt {
Some(Callee::Expr(ref expr)) => expr, Some(Callee::Expr(ref expr)) => expr,
@ -1210,6 +1232,18 @@ impl<I: Tokens> Parser<I> {
) )
.map(|expr| (Box::new(Expr::TaggedTpl(expr)), true)) .map(|expr| (Box::new(Expr::TaggedTpl(expr)), true))
.map(Some) .map(Some)
} else if is!(p, '=') {
Ok(Some((
Box::new(Expr::TsInstantiation(TsInstantiation {
span: span!(p, start),
expr: match mut_obj_opt {
Some(Callee::Expr(obj)) => obj.take(),
_ => unreachable!(),
},
type_args,
})),
true,
)))
} else if no_call { } else if no_call {
unexpected!(p, "`") unexpected!(p, "`")
} else { } else {
@ -1500,6 +1534,7 @@ impl<I: Tokens> Parser<I> {
} }
/// Parse call, dot, and `[]`-subscript expressions. /// Parse call, dot, and `[]`-subscript expressions.
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
pub(super) fn parse_lhs_expr(&mut self) -> PResult<Box<Expr>> { pub(super) fn parse_lhs_expr(&mut self) -> PResult<Box<Expr>> {
trace_cur!(self, parse_lhs_expr); trace_cur!(self, parse_lhs_expr);

View File

@ -231,7 +231,11 @@ impl<I: Tokens> Parser<I> {
let type_name = self.parse_ts_entity_name(/* allow_reserved_words */ true)?; let type_name = self.parse_ts_entity_name(/* allow_reserved_words */ true)?;
trace_cur!(self, parse_ts_type_ref__type_args); trace_cur!(self, parse_ts_type_ref__type_args);
let type_params = if !self.input.had_line_break_before_cur() && is!(self, '<') { let type_params = if !self.input.had_line_break_before_cur() && is!(self, '<') {
Some(self.parse_ts_type_args()?) let ctx = Context {
should_not_lex_lt_or_gt_as_type: false,
..self.ctx()
};
Some(self.with_ctx(ctx).parse_ts_type_args()?)
} else { } else {
None None
}; };
@ -568,7 +572,9 @@ impl<I: Tokens> Parser<I> {
} }
} }
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
pub(super) fn try_parse_ts_type_args(&mut self) -> Option<Box<TsTypeParamInstantiation>> { pub(super) fn try_parse_ts_type_args(&mut self) -> Option<Box<TsTypeParamInstantiation>> {
trace_cur!(self, try_parse_ts_type_args);
debug_assert!(self.input.syntax().typescript()); debug_assert!(self.input.syntax().typescript());
self.try_parse_ts(|p| { self.try_parse_ts(|p| {

View File

@ -0,0 +1 @@
fn(z<Number, Object>(y))

View File

@ -0,0 +1,124 @@
{
"type": "Script",
"span": {
"start": 1,
"end": 25,
"ctxt": 0
},
"body": [
{
"type": "ExpressionStatement",
"span": {
"start": 1,
"end": 25,
"ctxt": 0
},
"expression": {
"type": "CallExpression",
"span": {
"start": 1,
"end": 25,
"ctxt": 0
},
"callee": {
"type": "Identifier",
"span": {
"start": 1,
"end": 3,
"ctxt": 0
},
"value": "fn",
"optional": false
},
"arguments": [
{
"spread": null,
"expression": {
"type": "CallExpression",
"span": {
"start": 4,
"end": 24,
"ctxt": 0
},
"callee": {
"type": "Identifier",
"span": {
"start": 4,
"end": 5,
"ctxt": 0
},
"value": "z",
"optional": false
},
"arguments": [
{
"spread": null,
"expression": {
"type": "Identifier",
"span": {
"start": 22,
"end": 23,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
],
"typeArguments": {
"type": "TsTypeParameterInstantiation",
"span": {
"start": 5,
"end": 21,
"ctxt": 0
},
"params": [
{
"type": "TsTypeReference",
"span": {
"start": 6,
"end": 12,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 6,
"end": 12,
"ctxt": 0
},
"value": "Number",
"optional": false
},
"typeParams": null
},
{
"type": "TsTypeReference",
"span": {
"start": 14,
"end": 20,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 14,
"end": 20,
"ctxt": 0
},
"value": "Object",
"optional": false
},
"typeParams": null
}
]
}
}
}
],
"typeArguments": null
}
}
],
"interpreter": null
}

View File

@ -0,0 +1 @@
fn(x < y, x < y, x >>>= y)

View File

@ -0,0 +1,137 @@
{
"type": "Script",
"span": {
"start": 1,
"end": 27,
"ctxt": 0
},
"body": [
{
"type": "ExpressionStatement",
"span": {
"start": 1,
"end": 27,
"ctxt": 0
},
"expression": {
"type": "CallExpression",
"span": {
"start": 1,
"end": 27,
"ctxt": 0
},
"callee": {
"type": "Identifier",
"span": {
"start": 1,
"end": 3,
"ctxt": 0
},
"value": "fn",
"optional": false
},
"arguments": [
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 4,
"end": 9,
"ctxt": 0
},
"operator": "<",
"left": {
"type": "Identifier",
"span": {
"start": 4,
"end": 5,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 8,
"end": 9,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
},
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 11,
"end": 16,
"ctxt": 0
},
"operator": "<",
"left": {
"type": "Identifier",
"span": {
"start": 11,
"end": 12,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 15,
"end": 16,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
},
{
"spread": null,
"expression": {
"type": "AssignmentExpression",
"span": {
"start": 18,
"end": 26,
"ctxt": 0
},
"operator": ">>>=",
"left": {
"type": "Identifier",
"span": {
"start": 18,
"end": 19,
"ctxt": 0
},
"value": "x",
"optional": false,
"typeAnnotation": null
},
"right": {
"type": "Identifier",
"span": {
"start": 25,
"end": 26,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
}
],
"typeArguments": null
}
}
],
"interpreter": null
}

View File

@ -0,0 +1 @@
fn(z<Number, Object> = y)

View File

@ -0,0 +1,128 @@
{
"type": "Script",
"span": {
"start": 1,
"end": 26,
"ctxt": 0
},
"body": [
{
"type": "ExpressionStatement",
"span": {
"start": 1,
"end": 26,
"ctxt": 0
},
"expression": {
"type": "CallExpression",
"span": {
"start": 1,
"end": 26,
"ctxt": 0
},
"callee": {
"type": "Identifier",
"span": {
"start": 1,
"end": 3,
"ctxt": 0
},
"value": "fn",
"optional": false
},
"arguments": [
{
"spread": null,
"expression": {
"type": "AssignmentExpression",
"span": {
"start": 4,
"end": 25,
"ctxt": 0
},
"operator": "=",
"left": {
"type": "TsInstantiation",
"span": {
"start": 4,
"end": 21,
"ctxt": 0
},
"expression": {
"type": "Identifier",
"span": {
"start": 4,
"end": 5,
"ctxt": 0
},
"value": "z",
"optional": false
},
"typeArguments": {
"type": "TsTypeParameterInstantiation",
"span": {
"start": 5,
"end": 21,
"ctxt": 0
},
"params": [
{
"type": "TsTypeReference",
"span": {
"start": 6,
"end": 12,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 6,
"end": 12,
"ctxt": 0
},
"value": "Number",
"optional": false
},
"typeParams": null
},
{
"type": "TsTypeReference",
"span": {
"start": 14,
"end": 20,
"ctxt": 0
},
"typeName": {
"type": "Identifier",
"span": {
"start": 14,
"end": 20,
"ctxt": 0
},
"value": "Object",
"optional": false
},
"typeParams": null
}
]
}
},
"right": {
"type": "Identifier",
"span": {
"start": 24,
"end": 25,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
}
],
"typeArguments": null
}
}
],
"interpreter": null
}

View File

@ -0,0 +1 @@
fn(x < y, x > y)

View File

@ -0,0 +1,104 @@
{
"type": "Script",
"span": {
"start": 1,
"end": 17,
"ctxt": 0
},
"body": [
{
"type": "ExpressionStatement",
"span": {
"start": 1,
"end": 17,
"ctxt": 0
},
"expression": {
"type": "CallExpression",
"span": {
"start": 1,
"end": 17,
"ctxt": 0
},
"callee": {
"type": "Identifier",
"span": {
"start": 1,
"end": 3,
"ctxt": 0
},
"value": "fn",
"optional": false
},
"arguments": [
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 4,
"end": 9,
"ctxt": 0
},
"operator": "<",
"left": {
"type": "Identifier",
"span": {
"start": 4,
"end": 5,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 8,
"end": 9,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
},
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 11,
"end": 16,
"ctxt": 0
},
"operator": ">",
"left": {
"type": "Identifier",
"span": {
"start": 11,
"end": 12,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 15,
"end": 16,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
}
],
"typeArguments": null
}
}
],
"interpreter": null
}

View File

@ -0,0 +1 @@
fn(x < y, x >= y)

View File

@ -0,0 +1,104 @@
{
"type": "Script",
"span": {
"start": 1,
"end": 18,
"ctxt": 0
},
"body": [
{
"type": "ExpressionStatement",
"span": {
"start": 1,
"end": 18,
"ctxt": 0
},
"expression": {
"type": "CallExpression",
"span": {
"start": 1,
"end": 18,
"ctxt": 0
},
"callee": {
"type": "Identifier",
"span": {
"start": 1,
"end": 3,
"ctxt": 0
},
"value": "fn",
"optional": false
},
"arguments": [
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 4,
"end": 9,
"ctxt": 0
},
"operator": "<",
"left": {
"type": "Identifier",
"span": {
"start": 4,
"end": 5,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 8,
"end": 9,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
},
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 11,
"end": 17,
"ctxt": 0
},
"operator": ">=",
"left": {
"type": "Identifier",
"span": {
"start": 11,
"end": 12,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 16,
"end": 17,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
}
],
"typeArguments": null
}
}
],
"interpreter": null
}

View File

@ -0,0 +1 @@
fn(x < y, x >> y)

View File

@ -0,0 +1,104 @@
{
"type": "Script",
"span": {
"start": 1,
"end": 18,
"ctxt": 0
},
"body": [
{
"type": "ExpressionStatement",
"span": {
"start": 1,
"end": 18,
"ctxt": 0
},
"expression": {
"type": "CallExpression",
"span": {
"start": 1,
"end": 18,
"ctxt": 0
},
"callee": {
"type": "Identifier",
"span": {
"start": 1,
"end": 3,
"ctxt": 0
},
"value": "fn",
"optional": false
},
"arguments": [
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 4,
"end": 9,
"ctxt": 0
},
"operator": "<",
"left": {
"type": "Identifier",
"span": {
"start": 4,
"end": 5,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 8,
"end": 9,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
},
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 11,
"end": 17,
"ctxt": 0
},
"operator": ">>",
"left": {
"type": "Identifier",
"span": {
"start": 11,
"end": 12,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 16,
"end": 17,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
}
],
"typeArguments": null
}
}
],
"interpreter": null
}

View File

@ -0,0 +1 @@
fn(x < y, x >>= y)

View File

@ -0,0 +1,105 @@
{
"type": "Script",
"span": {
"start": 1,
"end": 19,
"ctxt": 0
},
"body": [
{
"type": "ExpressionStatement",
"span": {
"start": 1,
"end": 19,
"ctxt": 0
},
"expression": {
"type": "CallExpression",
"span": {
"start": 1,
"end": 19,
"ctxt": 0
},
"callee": {
"type": "Identifier",
"span": {
"start": 1,
"end": 3,
"ctxt": 0
},
"value": "fn",
"optional": false
},
"arguments": [
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 4,
"end": 9,
"ctxt": 0
},
"operator": "<",
"left": {
"type": "Identifier",
"span": {
"start": 4,
"end": 5,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 8,
"end": 9,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
},
{
"spread": null,
"expression": {
"type": "AssignmentExpression",
"span": {
"start": 11,
"end": 18,
"ctxt": 0
},
"operator": ">>=",
"left": {
"type": "Identifier",
"span": {
"start": 11,
"end": 12,
"ctxt": 0
},
"value": "x",
"optional": false,
"typeAnnotation": null
},
"right": {
"type": "Identifier",
"span": {
"start": 17,
"end": 18,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
}
],
"typeArguments": null
}
}
],
"interpreter": null
}

View File

@ -0,0 +1 @@
fn(x < y, x >>>= y)

View File

@ -0,0 +1,105 @@
{
"type": "Script",
"span": {
"start": 1,
"end": 20,
"ctxt": 0
},
"body": [
{
"type": "ExpressionStatement",
"span": {
"start": 1,
"end": 20,
"ctxt": 0
},
"expression": {
"type": "CallExpression",
"span": {
"start": 1,
"end": 20,
"ctxt": 0
},
"callee": {
"type": "Identifier",
"span": {
"start": 1,
"end": 3,
"ctxt": 0
},
"value": "fn",
"optional": false
},
"arguments": [
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 4,
"end": 9,
"ctxt": 0
},
"operator": "<",
"left": {
"type": "Identifier",
"span": {
"start": 4,
"end": 5,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 8,
"end": 9,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
},
{
"spread": null,
"expression": {
"type": "AssignmentExpression",
"span": {
"start": 11,
"end": 19,
"ctxt": 0
},
"operator": ">>>=",
"left": {
"type": "Identifier",
"span": {
"start": 11,
"end": 12,
"ctxt": 0
},
"value": "x",
"optional": false,
"typeAnnotation": null
},
"right": {
"type": "Identifier",
"span": {
"start": 18,
"end": 19,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
}
],
"typeArguments": null
}
}
],
"interpreter": null
}

View File

@ -0,0 +1 @@
fn(x < y, x < y, x >>= y)

View File

@ -0,0 +1,137 @@
{
"type": "Script",
"span": {
"start": 1,
"end": 26,
"ctxt": 0
},
"body": [
{
"type": "ExpressionStatement",
"span": {
"start": 1,
"end": 26,
"ctxt": 0
},
"expression": {
"type": "CallExpression",
"span": {
"start": 1,
"end": 26,
"ctxt": 0
},
"callee": {
"type": "Identifier",
"span": {
"start": 1,
"end": 3,
"ctxt": 0
},
"value": "fn",
"optional": false
},
"arguments": [
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 4,
"end": 9,
"ctxt": 0
},
"operator": "<",
"left": {
"type": "Identifier",
"span": {
"start": 4,
"end": 5,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 8,
"end": 9,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
},
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 11,
"end": 16,
"ctxt": 0
},
"operator": "<",
"left": {
"type": "Identifier",
"span": {
"start": 11,
"end": 12,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 15,
"end": 16,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
},
{
"spread": null,
"expression": {
"type": "AssignmentExpression",
"span": {
"start": 18,
"end": 25,
"ctxt": 0
},
"operator": ">>=",
"left": {
"type": "Identifier",
"span": {
"start": 18,
"end": 19,
"ctxt": 0
},
"value": "x",
"optional": false,
"typeAnnotation": null
},
"right": {
"type": "Identifier",
"span": {
"start": 24,
"end": 25,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
}
],
"typeArguments": null
}
}
],
"interpreter": null
}

View File

@ -0,0 +1 @@
fn(x < y, x < y, x >>> y)

View File

@ -0,0 +1,136 @@
{
"type": "Script",
"span": {
"start": 1,
"end": 26,
"ctxt": 0
},
"body": [
{
"type": "ExpressionStatement",
"span": {
"start": 1,
"end": 26,
"ctxt": 0
},
"expression": {
"type": "CallExpression",
"span": {
"start": 1,
"end": 26,
"ctxt": 0
},
"callee": {
"type": "Identifier",
"span": {
"start": 1,
"end": 3,
"ctxt": 0
},
"value": "fn",
"optional": false
},
"arguments": [
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 4,
"end": 9,
"ctxt": 0
},
"operator": "<",
"left": {
"type": "Identifier",
"span": {
"start": 4,
"end": 5,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 8,
"end": 9,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
},
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 11,
"end": 16,
"ctxt": 0
},
"operator": "<",
"left": {
"type": "Identifier",
"span": {
"start": 11,
"end": 12,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 15,
"end": 16,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
},
{
"spread": null,
"expression": {
"type": "BinaryExpression",
"span": {
"start": 18,
"end": 25,
"ctxt": 0
},
"operator": ">>>",
"left": {
"type": "Identifier",
"span": {
"start": 18,
"end": 19,
"ctxt": 0
},
"value": "x",
"optional": false
},
"right": {
"type": "Identifier",
"span": {
"start": 24,
"end": 25,
"ctxt": 0
},
"value": "y",
"optional": false
}
}
}
],
"typeArguments": null
}
}
],
"interpreter": null
}