Skip to content

Commit

Permalink
JS: keep bang-comments
Browse files Browse the repository at this point in the history
  • Loading branch information
tdewolff committed Jul 31, 2023
1 parent 0053f21 commit 15b4f6a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 21 deletions.
28 changes: 22 additions & 6 deletions js/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ type JSONer interface {

// AST is the full ECMAScript abstract syntax tree.
type AST struct {
Comments [][]byte // first comments in file
BlockStmt // module
BlockStmt // module
}

func (ast *AST) String() string {
Expand Down Expand Up @@ -370,6 +369,25 @@ type IExpr interface {

////////////////////////////////////////////////////////////////

// Comment block or line, usually a bang comment.
type Comment struct {
Value []byte
}

func (n Comment) String() string {
return "Stmt(" + string(n.Value) + ")"
}

// JS converts the node back to valid JavaScript
func (n Comment) JS() string {
return string(n.Value)
}

// JS converts the node back to valid JavaScript (writes to io.Writer)
func (n Comment) JSWriteTo(w io.Writer) (i int, err error) {
return w.Write(n.Value)
}

// BlockStmt is a block statement.
type BlockStmt struct {
List []IStmt
Expand Down Expand Up @@ -1721,12 +1739,10 @@ func (n DirectivePrologueStmt) JS() string {

// JS converts the node back to valid JavaScript (writes to io.Writer)
func (n DirectivePrologueStmt) JSWriteTo(w io.Writer) (i int, err error) {
var wn int
wn, err = w.Write(n.Value)
i += wn
return
return w.Write(n.Value)
}

func (n Comment) stmtNode() {}
func (n BlockStmt) stmtNode() {}
func (n EmptyStmt) stmtNode() {}
func (n ExprStmt) stmtNode() {}
Expand Down
29 changes: 14 additions & 15 deletions js/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,22 @@ func Parse(r *parse.Input, o Options) (*AST, error) {
await: true,
}

// process shebang
// catch shebang in first line
var shebang []byte
if r.Peek(0) == '#' && r.Peek(1) == '!' {
r.Move(2)
p.l.consumeSingleLineComment() // consume till end-of-line
ast.Comments = append(ast.Comments, r.Shift())
shebang = r.Shift()
}

p.tt, p.data = p.l.Next()
for p.tt == CommentToken || p.tt == CommentLineTerminatorToken {
ast.Comments = append(ast.Comments, p.data)
p.tt, p.data = p.l.Next()
if p.tt == WhitespaceToken || p.tt == LineTerminatorToken {
p.tt, p.data = p.l.Next()
}
}
if p.tt == WhitespaceToken || p.tt == LineTerminatorToken {
p.next()
}
// prevLT may be wrong but that is not a problem
// parse JS module
p.next()
ast.BlockStmt = p.parseModule()

if 0 < len(shebang) {
ast.BlockStmt.List = append([]IStmt{&Comment{shebang}}, ast.BlockStmt.List...)
}

if p.err == nil {
p.err = p.l.Err()
} else {
Expand All @@ -82,7 +77,7 @@ func Parse(r *parse.Input, o Options) (*AST, error) {
func (p *Parser) next() {
p.prevLT = false
p.tt, p.data = p.l.Next()
for p.tt == WhitespaceToken || p.tt == LineTerminatorToken || p.tt == CommentToken || p.tt == CommentLineTerminatorToken {
for p.tt == WhitespaceToken || p.tt == LineTerminatorToken || (p.tt == CommentToken || p.tt == CommentLineTerminatorToken) && (p.exprLevel != 0 || len(p.data) < 3 || p.data[2] != '!') {
if p.tt == LineTerminatorToken || p.tt == CommentLineTerminatorToken {
p.prevLT = true
}
Expand Down Expand Up @@ -555,6 +550,10 @@ func (p *Parser) parseStmt(allowDeclaration bool) (stmt IStmt) {
stmt = &DebuggerStmt{}
case SemicolonToken, ErrorToken:
stmt = &EmptyStmt{}
case CommentToken, CommentLineTerminatorToken:
// bang comment
stmt = &Comment{p.data}
p.next()
default:
if p.isIdentifierReference(p.tt) {
// labelled statement or expression
Expand Down
3 changes: 3 additions & 0 deletions js/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ func TestParse(t *testing.T) {
// grammar
{"", ""},
{"\n", ""},
{"#!/usr/bin/env node", "Stmt(#!/usr/bin/env node)"},
{"/* comment */", ""},
{"/*! comment */", "Stmt(/*! comment */)"},
{"5 + /*! comment */ 6", "Stmt(5+6)"},
{"{}", "Stmt({ })"},
{`"use strict"`, `Stmt("use strict")`},
{"var a = b;", "Decl(var Binding(a = b))"},
Expand Down

0 comments on commit 15b4f6a

Please sign in to comment.