1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
import { LoaderKeys } from "../../../api/schema";
// This is a list of extra syntax replacements to do. Kind of like macros
// These are only run on code itself, not string contents or comments.
export const replacements: ReplacementRule[] = [
{ from: /\bthrow new TypeError\b/g, to: "$throwTypeError" },
{ from: /\bthrow new RangeError\b/g, to: "$throwRangeError" },
{ from: /\bthrow new OutOfMemoryError\b/g, to: "$throwOutOfMemoryError" },
{ from: /\bnew TypeError\b/g, to: "$makeTypeError" },
];
// These rules are run on the entire file, including within strings.
export const globalReplacements: ReplacementRule[] = [
{
from: /\bnotImplementedIssue\(\s*([0-9]+)\s*,\s*((?:"[^"]*"|'[^']+'))\s*\)/g,
to: "new TypeError(`${$2} is not implemented yet. See https://github.com/oven-sh/bun/issues/$1`)",
},
{
from: /\bnotImplementedIssueFn\(\s*([0-9]+)\s*,\s*((?:"[^"]*"|'[^']+'))\s*\)/g,
to: "() => $throwTypeError(`${$2} is not implemented yet. See https://github.com/oven-sh/bun/issues/$1`)",
},
];
// This is a list of globals we should access using @ notation
// undefined -> __intrinsic__undefined -> @undefined
export const globalsToPrefix = [
"AbortSignal",
"Array",
"ArrayBuffer",
"Buffer",
"Bun",
"Infinity",
"Loader",
"Promise",
"ReadableByteStreamController",
"ReadableStream",
"ReadableStreamBYOBReader",
"ReadableStreamBYOBRequest",
"ReadableStreamDefaultController",
"ReadableStreamDefaultReader",
"TransformStream",
"TransformStreamDefaultController",
"Uint8Array",
"WritableStream",
"WritableStreamDefaultController",
"WritableStreamDefaultWriter",
"isFinite",
"isNaN",
"undefined",
];
// These enums map to $<enum>IdToLabel and $<enum>LabelToId
// Make sure to define in ./builtins.d.ts
export const enums = {
Loader: LoaderKeys,
ImportKind: [
"entry-point",
"import-statement",
"require-call",
"dynamic-import",
"require-resolve",
"import-rule",
"url-token",
"internal",
],
};
// These identifiers have typedef but not present at runtime (converted with replacements)
// If they are present in the bundle after runtime, we warn at the user.
// TODO: implement this check.
export const warnOnIdentifiersNotPresentAtRuntime = [
//
"OutOfMemoryError",
"notImplementedIssue",
"notImplementedIssueFn",
];
export interface ReplacementRule {
from: RegExp;
to: string;
global?: boolean;
}
/** Applies source code replacements as defined in `replacements` */
export function applyReplacements(src: string) {
let result = src.replace(/\$([a-zA-Z0-9_]+)\b/gm, `__intrinsic__$1`);
for (const replacement of replacements) {
result = result.replace(replacement.from, replacement.to.replaceAll("$", "__intrinsic__"));
}
return result;
}
/** Applies source code replacements as defined in `globalReplacements` */
export function applyGlobalReplacements(src: string) {
let result = src;
for (const replacement of globalReplacements) {
result = result.replace(replacement.from, replacement.to.replaceAll("$", "__intrinsic__"));
}
return result;
}
|