From aa1cc58b506f9a8e10fd4aaa9a8e144295f2d912 Mon Sep 17 00:00:00 2001 From: tyamagu2 Date: Wed, 19 Jul 2023 17:39:59 +0900 Subject: [PATCH 1/5] fix: typo --- parser/expression.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parser/expression.go b/parser/expression.go index dd8606e5..bfff9653 100644 --- a/parser/expression.go +++ b/parser/expression.go @@ -884,7 +884,7 @@ func (p *parser) parseLogicalOrExpression() ast.Expression { return left } -func (p *parser) parseConditionlExpression() ast.Expression { +func (p *parser) parseConditionalExpression() ast.Expression { left := p.parseLogicalOrExpression() if p.token == token.QUESTION_MARK { @@ -911,7 +911,7 @@ func (p *parser) parseConditionlExpression() ast.Expression { } func (p *parser) parseAssignmentExpression() ast.Expression { - left := p.parseConditionlExpression() + left := p.parseConditionalExpression() var operator token.Token switch p.token { case token.ASSIGN: From 23294ce2afe80671a44f74fd59e2a0bdae10d1db Mon Sep 17 00:00:00 2001 From: tyamagu2 Date: Wed, 19 Jul 2023 17:40:21 +0900 Subject: [PATCH 2/5] fix: idx1 of conditional expression Fix Idx1 of ConditionalExpression so that it points to the next character after alternate expression --- ast/node.go | 2 +- parser/parser_test.go | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ast/node.go b/ast/node.go index db377704..6f30ef6d 100644 --- a/ast/node.go +++ b/ast/node.go @@ -178,7 +178,7 @@ func (ce *ConditionalExpression) Idx0() file.Idx { // Idx1 implements Node. func (ce *ConditionalExpression) Idx1() file.Idx { - return ce.Test.Idx1() + return ce.Alternate.Idx1() } // expression implements Expression. diff --git a/parser/parser_test.go b/parser/parser_test.go index 13f7328b..1744f944 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -1056,6 +1056,13 @@ func TestPosition(t *testing.T) { node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.AssignExpression).Right.(*ast.ArrayLiteral) is(node.Idx0(), 5) is(parser.slice(node.Idx0(), node.Idx1()), "[1, 2]") + + parser = newParser("", "x = true ? 1 : 2", 1, nil) + program, err = parser.parse() + is(err, nil) + node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.AssignExpression).Right.(*ast.ConditionalExpression) + is(node.Idx0(), 5) + is(parser.slice(node.Idx0(), node.Idx1()), "true ? 1 : 2") }) } From 0c03a2daf2cde60c78071830cdb33e8af6c12172 Mon Sep 17 00:00:00 2001 From: tyamagu2 Date: Wed, 19 Jul 2023 17:56:22 +0900 Subject: [PATCH 3/5] fix: idx1 of sequence expression Fix Idx1 of SequenceExpression to return Idx1 of the last sequence element, not first. --- ast/node.go | 2 +- parser/parser_test.go | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ast/node.go b/ast/node.go index 6f30ef6d..a9d35f37 100644 --- a/ast/node.go +++ b/ast/node.go @@ -397,7 +397,7 @@ func (se *SequenceExpression) Idx0() file.Idx { // Idx1 implements Node. func (se *SequenceExpression) Idx1() file.Idx { - return se.Sequence[0].Idx1() + return se.Sequence[len(se.Sequence)-1].Idx1() } // expression implements Expression. diff --git a/parser/parser_test.go b/parser/parser_test.go index 1744f944..99dc3f8c 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -1063,6 +1063,14 @@ func TestPosition(t *testing.T) { node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.AssignExpression).Right.(*ast.ConditionalExpression) is(node.Idx0(), 5) is(parser.slice(node.Idx0(), node.Idx1()), "true ? 1 : 2") + + parser = newParser("", "(function(){ x = 1, y = 2; })", 1, nil) + program, err = parser.parse() + is(err, nil) + block = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.FunctionLiteral).Body.(*ast.BlockStatement) + node = block.List[0].(*ast.ExpressionStatement).Expression.(*ast.SequenceExpression) + is(node.Idx0(), 14) + is(parser.slice(node.Idx0(), node.Idx1()), "x = 1, y = 2") }) } From 1257cb39b5fcf84b7c8cd5e4f687d482ab9ab6e0 Mon Sep 17 00:00:00 2001 From: tyamagu2 Date: Wed, 19 Jul 2023 18:04:57 +0900 Subject: [PATCH 4/5] fix: starting position of postfix unary expression Fix Idx0 of unary expression to point to the start of operand in case of a postfix operator --- ast/node.go | 3 +++ parser/parser_test.go | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ast/node.go b/ast/node.go index a9d35f37..5fbce841 100644 --- a/ast/node.go +++ b/ast/node.go @@ -451,6 +451,9 @@ type UnaryExpression struct { // Idx0 implements Node. func (ue *UnaryExpression) Idx0() file.Idx { + if ue.Postfix { + return ue.Operand.Idx0() + } return ue.Idx } diff --git a/parser/parser_test.go b/parser/parser_test.go index 99dc3f8c..3f545492 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -1071,6 +1071,21 @@ func TestPosition(t *testing.T) { node = block.List[0].(*ast.ExpressionStatement).Expression.(*ast.SequenceExpression) is(node.Idx0(), 14) is(parser.slice(node.Idx0(), node.Idx1()), "x = 1, y = 2") + + parser = newParser("", "x = ~x", 1, nil) + program, err = parser.parse() + is(err, nil) + node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.AssignExpression).Right.(*ast.UnaryExpression) + is(node.Idx0(), 5) + is(parser.slice(node.Idx0(), node.Idx1()), "~x") + + parser = newParser("", "(function(){ xyz++; })", 1, nil) + program, err = parser.parse() + is(err, nil) + block = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.FunctionLiteral).Body.(*ast.BlockStatement) + node = block.List[0].(*ast.ExpressionStatement).Expression.(*ast.UnaryExpression) + is(node.Idx0(), 14) + is(parser.slice(node.Idx0(), node.Idx1()), "xyz++") }) } From c9cddc35034837eab59a7e30d954725734f18940 Mon Sep 17 00:00:00 2001 From: tyamagu2 Date: Wed, 19 Jul 2023 18:13:47 +0900 Subject: [PATCH 5/5] fix: idx1 of variable expression without initializer Fix Idx1 of VariableExpression so that it points to the character right after the name literal if the expression does not have an initializer. --- ast/node.go | 2 +- parser/parser_test.go | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ast/node.go b/ast/node.go index 5fbce841..4ac013e3 100644 --- a/ast/node.go +++ b/ast/node.go @@ -483,7 +483,7 @@ func (ve *VariableExpression) Idx0() file.Idx { // Idx1 implements Node. func (ve *VariableExpression) Idx1() file.Idx { if ve.Initializer == nil { - return file.Idx(int(ve.Idx) + len(ve.Name) + 1) + return file.Idx(int(ve.Idx) + len(ve.Name)) } return ve.Initializer.Idx1() } diff --git a/parser/parser_test.go b/parser/parser_test.go index 3f545492..e026030c 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -1086,6 +1086,20 @@ func TestPosition(t *testing.T) { node = block.List[0].(*ast.ExpressionStatement).Expression.(*ast.UnaryExpression) is(node.Idx0(), 14) is(parser.slice(node.Idx0(), node.Idx1()), "xyz++") + + parser = newParser("", "(function(){ var abc, xyz = 1; })", 1, nil) + program, err = parser.parse() + is(err, nil) + block = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.FunctionLiteral).Body.(*ast.BlockStatement) + node = block.List[0].(*ast.VariableStatement) + is(node.Idx0(), 14) + is(parser.slice(node.Idx0(), node.Idx1()), "var abc, xyz = 1") + node = block.List[0].(*ast.VariableStatement).List[0].(*ast.VariableExpression) + is(node.Idx0(), 18) + is(parser.slice(node.Idx0(), node.Idx1()), "abc") + node = block.List[0].(*ast.VariableStatement).List[1].(*ast.VariableExpression) + is(node.Idx0(), 23) + is(parser.slice(node.Idx0(), node.Idx1()), "xyz = 1") }) }