diff options
Diffstat (limited to 'src/js_parser.zig')
-rw-r--r-- | src/js_parser.zig | 66 |
1 files changed, 61 insertions, 5 deletions
diff --git a/src/js_parser.zig b/src/js_parser.zig index 746b72b76..5bd0fc8e1 100644 --- a/src/js_parser.zig +++ b/src/js_parser.zig @@ -7,7 +7,14 @@ const options = @import("options.zig"); const alloc = @import("alloc.zig"); usingnamespace @import("strings.zig"); -const Comment = js_ast._Comment; +usingnamespace js_ast.G; +const S = js_ast.S; +const B = js_ast.B; +const T = js_lexer.T; +const E = js_ast.E; +const Stmt = js_ast.Stmt; +const Expr = js_ast.Expr; +const Binding = js_ast.Binding; const locModuleScope = logger.Loc.Empty; const TempRef = struct { @@ -537,10 +544,10 @@ const P = struct { } pub fn pushScopeForVisitPass(p: *P, kind: js_ast.Scope.Kind, loc: logger.Loc) !void { - const order = try p.unshiftScopeOrder(); + var order = try p.unshiftScopeOrder(); // Sanity-check that the scopes generated by the first and second passes match - if (nql(order.loc, loc) or nql(order.scope.kind, kind)) { + if (!order.loc.eql(loc) or order.scope.kind != kind) { std.debug.panic("Expected scope ({s}, {d}) in {s}, found scope ({s}, {d})", .{ kind, loc.start, p.source.path.pretty, order.scope.kind, order.loc.start }); } @@ -591,6 +598,43 @@ const P = struct { } } + pub fn parseStmt(p: *P, opts: *ParseStatementOptions) js_ast.Stmt { + var loc = p.lexer.loc(); + var stmt: js_ast.Stmt = undefined; + + switch (p.lexer.token) { + js_lexer.T.t_semicolon => { + p.lexer.next(); + return js_ast.Stmt.init(js_ast.S.Empty{}, loc); + }, + + js_lexer.T.t_export => { + var previousExportKeyword = p.es6_export_keyword; + if (opts.is_module_scope) { + p.es6_export_keyword = p.lexer.range(); + } else if (!opts.is_namespace_scope) { + p.lexer.unexpected(); + } + p.lexer.next(); + + // TypeScript decorators only work on class declarations + // "@decorator export class Foo {}" + // "@decorator export abstract class Foo {}" + // "@decorator export default class Foo {}" + // "@decorator export default abstract class Foo {}" + // "@decorator export declare class Foo {}" + // "@decorator export declare abstract class Foo {}" + if (opts.ts_decorators != null and p.lexer.token != js_lexer.T.t_class and p.lexer.token != js_lexer.T.t_default and !p.lexer.isContextualKeyword("abstract") and !p.lexer.isContextualKeyword("declare")) { + p.lexer.expected(js_lexer.T.t_class); + } + }, + + else => {}, + } + + return stmt; + } + pub fn parseStmtsUpTo(p: *P, eend: js_lexer.T, opts: *ParseStatementOptions) ![]js_ast.Stmt { var stmts = List(js_ast.Stmt).init(p.allocator); try stmts.ensureCapacity(1); @@ -599,8 +643,20 @@ const P = struct { opts.lexical_decl = .allow_all; var isDirectivePrologue = true; - while (true) { - // var comments = p.lexer + run: while (true) { + if (p.lexer.comments_to_preserve_before) |comments| { + for (comments) |comment| { + try stmts.append(Stmt.init(S.Comment{ + .text = comment.text, + }, p.lexer.loc())); + } + } + + if (p.lexer.token == .t_end_of_file) { + break :run; + } + + var stmt = p.parseStmt(opts); } return stmts.toOwnedSlice(); |