aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/js_parser.zig26
-rw-r--r--test/bun.js/transpiler.test.js157
2 files changed, 109 insertions, 74 deletions
diff --git a/src/js_parser.zig b/src/js_parser.zig
index 9f422d9b8..b671682a9 100644
--- a/src/js_parser.zig
+++ b/src/js_parser.zig
@@ -739,10 +739,10 @@ pub const ImportScanner = struct {
// Skip to the underlying reference
var value = decl.value;
- if (decl.value) |val| {
+ if (decl.value != null) {
while (true) {
- if (@as(Expr.Tag, val.data) == .e_dot) {
- value = val.data.e_dot.target;
+ if (@as(Expr.Tag, value.?.data) == .e_dot) {
+ value = value.?.data.e_dot.target;
} else {
break;
}
@@ -8097,7 +8097,8 @@ fn NewParser_(
const kind = S.Local.Kind.k_const;
const name = p.lexer.identifier;
- var value = p.e(E.Identifier{ .ref = p.storeNameInRef(name) catch unreachable }, p.lexer.loc());
+ const target = p.e(E.Identifier{ .ref = p.storeNameInRef(name) catch unreachable }, p.lexer.loc());
+ var value = target;
try p.lexer.expect(.t_identifier);
if (strings.eqlComptime(name, "require") and p.lexer.token == .t_open_paren) {
@@ -8106,17 +8107,17 @@ fn NewParser_(
const path = p.e(p.lexer.toEString(), p.lexer.loc());
try p.lexer.expect(.t_string_literal);
try p.lexer.expect(.t_close_paren);
- const args = try ExprNodeList.one(p.allocator, path);
- value.data = .{ .e_call = Expr.Data.Store.All.append(E.Call, E.Call{ .target = value, .close_paren_loc = p.lexer.loc(), .args = args }) };
+ if (!opts.is_typescript_declare) {
+ const args = try ExprNodeList.one(p.allocator, path);
+ value = p.e(E.Call{ .target = target, .close_paren_loc = p.lexer.loc(), .args = args }, loc);
+ }
} else {
// "import Foo = Bar"
// "import Foo = Bar.Baz"
- while (p.lexer.token == .t_dot) {
+ var prev_value = value;
+ while (p.lexer.token == .t_dot) : (prev_value = value) {
try p.lexer.next();
- value.data = .{ .e_dot = Expr.Data.Store.All.append(
- E.Dot,
- E.Dot{ .target = value, .name = p.lexer.identifier, .name_loc = p.lexer.loc() },
- ) };
+ value = p.e(E.Dot{ .target = prev_value, .name = p.lexer.identifier, .name_loc = p.lexer.loc() }, loc);
try p.lexer.expect(.t_identifier);
}
}
@@ -15717,8 +15718,9 @@ fn NewParser_(
pub fn ignoreUsage(p: *P, ref: Ref) void {
if (!p.is_control_flow_dead) {
+ assert(@as(usize, ref.innerIndex()) < p.symbols.items.len);
p.symbols.items[ref.innerIndex()].use_count_estimate -|= 1;
- var use = p.symbol_uses.get(ref) orelse p.panic("Expected symbol_uses to exist {s}\n{s}", .{ ref, p.symbol_uses });
+ var use = p.symbol_uses.get(ref) orelse return;
use.count_estimate -|= 1;
if (use.count_estimate == 0) {
_ = p.symbol_uses.swapRemove(ref);
diff --git a/test/bun.js/transpiler.test.js b/test/bun.js/transpiler.test.js
index f8da4c18c..51e1e669d 100644
--- a/test/bun.js/transpiler.test.js
+++ b/test/bun.js/transpiler.test.js
@@ -1,6 +1,101 @@
import { expect, it, describe } from "bun:test";
describe("Bun.Transpiler", () => {
+ const transpiler = new Bun.Transpiler({
+ loader: "tsx",
+ define: {
+ "process.env.NODE_ENV": JSON.stringify("development"),
+ user_undefined: "undefined",
+ },
+ macro: {
+ react: {
+ bacon: `${import.meta.dir}/macro-check.js`,
+ },
+ },
+ platform: "browser",
+ });
+
+ const ts = {
+ parsed: (code, trim = true, autoExport = false) => {
+ if (autoExport) {
+ code = "export default (" + code + ")";
+ }
+
+ var out = transpiler.transformSync(code, "ts");
+ if (autoExport && out.startsWith("export default ")) {
+ out = out.substring("export default ".length);
+ }
+
+ if (trim) {
+ out = out.trim();
+
+ if (out.endsWith(";")) {
+ out = out.substring(0, out.length - 1);
+ }
+
+ return out.trim();
+ }
+
+ return out;
+ },
+
+ expectPrinted: (code, out) => {
+ expect(ts.parsed(code, true, true)).toBe(out);
+ },
+
+ expectPrinted_: (code, out) => {
+ expect(ts.parsed(code, !out.endsWith(";\n"), false)).toBe(out);
+ },
+
+ expectParseError: (code, message) => {
+ try {
+ ts.parsed(code, false, false);
+ } catch (er) {
+ var err = er;
+ if (er instanceof AggregateError) {
+ err = err.errors[0];
+ }
+
+ expect(er.message).toBe(message);
+
+ return;
+ }
+
+ throw new Error("Expected parse error for code\n\t" + code);
+ },
+ };
+
+ describe("TypeScript", () => {
+ it("import Foo = Baz.Bar", () => {
+ ts.expectPrinted_(
+ "import Foo = Baz.Bar;\nexport default Foo;",
+ "const Foo = Baz.Bar;\nexport default Foo"
+ );
+ });
+
+ it("import Foo = require('bar')", () => {
+ ts.expectPrinted_(
+ "import React = require('react')",
+ 'const React = require("react")'
+ );
+ });
+
+ it("import type Foo = require('bar')", () => {
+ ts.expectPrinted_("import type Foo = require('bar')", "");
+ });
+
+ it("unused import = gets removed", () => {
+ ts.expectPrinted_("import Foo = Baz.Bar;", "");
+ });
+
+ it("export import Foo = Baz.Bar", () => {
+ ts.expectPrinted_(
+ "export import Foo = Baz.Bar;",
+ "export const Foo = Baz.Bar"
+ );
+ });
+ });
+
describe("exports.replace", () => {
const transpiler = new Bun.Transpiler({
exports: {
@@ -111,19 +206,6 @@ describe("Bun.Transpiler", () => {
});
});
- const transpiler = new Bun.Transpiler({
- loader: "tsx",
- define: {
- "process.env.NODE_ENV": JSON.stringify("development"),
- user_undefined: "undefined",
- },
- macro: {
- react: {
- bacon: `${import.meta.dir}/macro-check.js`,
- },
- },
- platform: "browser",
- });
const bunTranspiler = new Bun.Transpiler({
loader: "tsx",
define: {
@@ -496,55 +578,6 @@ export var ComponentThatHasSpreadCausesDeopt = jsx(Hello, {
throw new Error("Expected parse error for code\n\t" + code);
};
- const ts = {
- parsed: (code, trim = true, autoExport = false) => {
- if (autoExport) {
- code = "export default (" + code + ")";
- }
-
- var out = transpiler.transformSync(code, "ts");
- if (autoExport && out.startsWith("export default ")) {
- out = out.substring("export default ".length);
- }
-
- if (trim) {
- out = out.trim();
-
- if (out.endsWith(";")) {
- out = out.substring(0, out.length - 1);
- }
-
- return out.trim();
- }
-
- return out;
- },
-
- expectPrinted: (code, out) => {
- expect(ts.parsed(code, true, true)).toBe(out);
- },
-
- expectPrinted_: (code, out) => {
- expect(ts.parsed(code, !out.endsWith(";\n"), false)).toBe(out);
- },
-
- expectParseError: (code, message) => {
- try {
- ts.parsed(code, false, false);
- } catch (er) {
- var err = er;
- if (er instanceof AggregateError) {
- err = err.errors[0];
- }
-
- expect(er.message).toBe(message);
-
- return;
- }
-
- throw new Error("Expected parse error for code\n\t" + code);
- },
- };
describe("parser", () => {
it("arrays", () => {