diff --git a/ast/comments.go b/ast/comments.go index 5e40bd4..20135d8 100644 --- a/ast/comments.go +++ b/ast/comments.go @@ -15,7 +15,7 @@ const ( TRAILING // After the pertinent expression KEY // After a key or keyword COLON // After a colon in a field declaration - FINAL // Final comments in a block, not belonging to a specific expression + FINAL // Final comments in a block, not belonging to a specific expression or the comment after a trailing , in an array or object literal TBD ) diff --git a/parser/comments_test.go b/parser/comments_test.go index 1aee3bf..a2b6029 100644 --- a/parser/comments_test.go +++ b/parser/comments_test.go @@ -265,7 +265,9 @@ func TestParser_comments(t *testing.T) { "a2", // "ab" ]; `, nil) - is(parser.commentMap.Size(), 1) // Should have been 2, but we need an empty expression node + is(parser.commentMap.Size(), 2) + is(checkComments((*parser.commentMap)[program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.ArrayLiteral).Value[1]], []string{" \"a\""}, ast.LEADING), nil) + is(checkComments((*parser.commentMap)[program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.ArrayLiteral)], []string{" \"ab\""}, ast.FINAL), nil) // Arrays pt 6 parser, program = test(`[a, /*test*/ b, c];`, nil) @@ -273,11 +275,23 @@ func TestParser_comments(t *testing.T) { is(checkComments((*parser.commentMap)[program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.ArrayLiteral).Value[1]], []string{"test"}, ast.LEADING), nil) is(parser.commentMap.Size(), 1) - // Arrays pt 7 - Not working correctly yet. - parser, program = test(`[a,,/*test2*/];`, nil) + // Arrays pt 7 - Empty node + parser, program = test(`[a,,/*test2*/,];`, nil) is(len(program.Body), 1) - //is(checkComments((*parser.commentMap)[program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.ArrayLiteral).Value[0]], []string{"test"}, false), nil) - //is(parser.commentMap.Size(), 1) + is(checkComments((*parser.commentMap)[program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.ArrayLiteral).Value[2]], []string{"test2"}, ast.LEADING), nil) + is(parser.commentMap.Size(), 1) + + // Arrays pt 8 - Trailing node + parser, program = test(`[a,,,/*test2*/];`, nil) + is(len(program.Body), 1) + is(checkComments((*parser.commentMap)[program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.ArrayLiteral)], []string{"test2"}, ast.FINAL), nil) + is(parser.commentMap.Size(), 1) + + // Arrays pt 9 - Leading node + parser, program = test(`[/*test2*/a,,,];`, nil) + is(len(program.Body), 1) + is(checkComments((*parser.commentMap)[program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.ArrayLiteral).Value[0]], []string{"test2"}, ast.LEADING), nil) + is(parser.commentMap.Size(), 1) // Object literal parser, program = test("obj = {a: 1, b: 2 /*test2*/, c: 3}", nil) @@ -315,6 +329,11 @@ func TestParser_comments(t *testing.T) { is(checkComments((*parser.commentMap)[program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.AssignExpression).Right.(*ast.ObjectLiteral).Value[2].Value], []string{"test2"}, ast.TRAILING), nil) is(parser.commentMap.Size(), 1) + // Object literal, pt 7 - trailing comment + parser, program = test("obj = {x: 1, y: 2, z: 3,/*test2*/}", nil) + is(parser.commentMap.Size(), 1) + is(checkComments((*parser.commentMap)[program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.AssignExpression).Right.(*ast.ObjectLiteral)], []string{"test2"}, ast.FINAL), nil) + // Line breaks parser, program = test(` t1 = "BLA DE VLA" @@ -581,7 +600,6 @@ for(i = 0 ;i < 1 ; i++/*comment*/) { a } `, nil) - parser.commentMap.Display() is(parser.commentMap.Size(), 1) is(checkComments((*parser.commentMap)[program.Body[0].(*ast.ForStatement).Update.(*ast.UnaryExpression)], []string{"comment"}, ast.TRAILING), nil) diff --git a/parser/expression.go b/parser/expression.go index 8c65e6c..4bb66a4 100644 --- a/parser/expression.go +++ b/parser/expression.go @@ -336,7 +336,7 @@ func (self *_parser) parseObjectLiteral() ast.Expression { Value: value, } - self.commentMap.AddComments(exp, comments2, ast.LEADING) + self.commentMap.AddComments(exp, comments2, ast.FINAL) self.consumeComments(exp, ast.FINAL) return exp @@ -345,21 +345,29 @@ func (self *_parser) parseObjectLiteral() ast.Expression { func (self *_parser) parseArrayLiteral() ast.Expression { idx0 := self.expect(token.LEFT_BRACKET) var comments2 []*ast.Comment + var comments []*ast.Comment var value []ast.Expression for self.token != token.RIGHT_BRACKET && self.token != token.EOF { + // Find leading comments for both empty and non-empty expressions + comments = self.findComments(false) + if self.token == token.COMMA { self.next() - // TODO This kind of comment requires a special empty expression node. - // TODO For now it is not saved. - self.findComments(false) + // This kind of comment requires a special empty expression node. + empty := &ast.EmptyExpression{self.idx, self.idx} + + self.commentMap.AddComments(empty, comments, ast.LEADING) + self.commentMap.AddComments(empty, comments2, ast.LEADING) + + value = append(value, empty) + + // This comment belongs to the following expression, or trailing + comments2 = self.findComments(false) - value = append(value, nil) continue } - // This comment belongs to the expression before the comma - comments := self.findComments(false) exp := self.parseAssignmentExpression() self.commentMap.AddComments(exp, comments, ast.LEADING) self.commentMap.AddComments(exp, comments2, ast.LEADING) @@ -369,21 +377,21 @@ func (self *_parser) parseArrayLiteral() ast.Expression { self.expect(token.COMMA) } - // This comment belongs to the following expression + // This comment belongs to the following expression, or trailing comments2 = self.findComments(false) - //self.commentMap.AddComments(exp, comments2) - } idx1 := self.expect(token.RIGHT_BRACKET) - // TODO This is where comments after a possible trailing comma should be added - - // TODO COMMENT - return &ast.ArrayLiteral{ + array := &ast.ArrayLiteral{ LeftBracket: idx0, RightBracket: idx1, Value: value, } + + // This is where comments after a possible trailing comma are added + self.commentMap.AddComments(array, comments2, ast.FINAL) + + return array } func (self *_parser) parseArgumentList() (argumentList []ast.Expression, idx0, idx1 file.Idx) {