Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions src/bun_core/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,13 +662,6 @@ pub const unsafe fn container_of<P, F>(field: *const F, offset: usize) -> *mut P
unsafe { field.byte_sub(offset).cast::<P>().cast_mut() }
}

/// `*const`-out variant of [`container_of`]. Same safety contract.
#[inline(always)]
pub const unsafe fn container_of_const<P, F>(field: *const F, offset: usize) -> *const P {
// SAFETY: per fn contract.
unsafe { field.byte_sub(offset).cast::<P>() }
}

/// Recover a typed `&mut T` from a C-callback's opaque user-data pointer.
///
/// This is the canonical spelling for the ubiquitous trampoline pattern where
Expand Down
12 changes: 0 additions & 12 deletions src/bun_core/string/immutable/unicode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,18 +906,6 @@ pub fn utf16_codepoint(input: &[u16]) -> UTF16Replacement {
}
}

/// `b"..."` for u8, `$crate::w!("...")` for u16.
/// New callers should use byte/wide literals directly.
#[macro_export]
macro_rules! literal {
(u8, $s:literal) => {
concat!($s, "\0").as_bytes()
};
(u16, $s:literal) => {
$crate::w!($s)
};
}

pub(super) use crate::strings_impl::push_codepoint_utf16;

// `unreachable_pub`: these are re-exported externally via the parent's
Expand Down
5 changes: 1 addition & 4 deletions src/bun_core/string/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
//! Merged into `bun_core` to break the `bun_core ↔ bun_string` dep edge;
//! the `bun_string` crate is now a thin re-export shim over this module.

// `#[macro_export]` macros defined in submodules (`w!`, `literal!`) land at
// the *crate* root (`bun_core::`).
// Re-export them here so `crate::string::w` / `bun_core::w` paths resolve.
pub use crate::{literal, w};
pub use crate::w;

#[path = "escapeRegExp.rs"]
pub mod escape_reg_exp;
Expand Down
7 changes: 0 additions & 7 deletions src/http/ssl_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,6 @@ impl core::ops::Deref for SharedPtr {
}
}

impl From<Arc<SSLConfig>> for SharedPtr {
#[inline]
fn from(a: Arc<SSLConfig>) -> Self {
Self(a)
}
}

impl SSLConfig {
pub(crate) const ZERO: SSLConfig = SSLConfig {
server_name: core::ptr::null(),
Expand Down
1 change: 0 additions & 1 deletion src/jsc/bindings/AsymmetricKeyValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class AsymmetricKeyValue {
bool operator!() const { return !key; }

~AsymmetricKeyValue();
AsymmetricKeyValue(EVP_PKEY* key, bool owned);
AsymmetricKeyValue(CryptoKey&);
};

Expand Down
5 changes: 2 additions & 3 deletions src/jsc/bindings/BunHeapProfiler.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "root.h"
#include "BunHeapProfiler.h"
#include "headers-handwritten.h"
#include <JavaScriptCore/HeapProfiler.h>
#include <JavaScriptCore/HeapSnapshotBuilder.h>
Expand Down Expand Up @@ -111,7 +110,7 @@ static WTF::String formatBytes(size_t bytes)
return sb.toString();
}

WTF::String generateHeapProfile(JSC::VM& vm)
static WTF::String generateHeapProfile(JSC::VM& vm)
Comment thread
robobun marked this conversation as resolved.
{
vm.ensureHeapProfiler();
auto& heapProfiler = *vm.heapProfiler();
Expand Down Expand Up @@ -936,7 +935,7 @@ WTF::String generateHeapProfile(JSC::VM& vm)
return output.toString();
}

WTF::String generateHeapSnapshotV8(JSC::VM& vm)
static WTF::String generateHeapSnapshotV8(JSC::VM& vm)
{
vm.ensureHeapProfiler();
auto& heapProfiler = *vm.heapProfiler();
Expand Down
17 changes: 0 additions & 17 deletions src/jsc/bindings/BunHeapProfiler.h

This file was deleted.

31 changes: 0 additions & 31 deletions src/jsc/bindings/ErrorCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1299,14 +1299,6 @@ JSC::EncodedJSValue CRYPTO_INVALID_KEYTYPE(JSC::ThrowScope& throwScope, JSC::JSG
return {};
}

JSC::EncodedJSValue CRYPTO_INVALID_KEYTYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject)
{
auto message = "Invalid key type"_s;
throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_KEYTYPE, message));
throwScope.release();
return {};
}

JSC::EncodedJSValue CRYPTO_UNKNOWN_CIPHER(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::StringView& cipherName)
{
// Node dropped the cipher name from the message (exact-match asserted by
Expand Down Expand Up @@ -1549,14 +1541,6 @@ JSC::EncodedJSValue CRYPTO_HASH_UPDATE_FAILED(JSC::ThrowScope& throwScope, JSC::
return {};
}

JSC::EncodedJSValue CRYPTO_TIMING_SAFE_EQUAL_LENGTH(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject)
{
auto message = "Input buffers must have the same byte length"_s;
scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH, message));
scope.release();
return {};
}

JSC::EncodedJSValue CRYPTO_UNKNOWN_DH_GROUP(JSC::ThrowScope& scope, JSGlobalObject* globalObject)
{
auto message = "Unknown DH group"_s;
Expand All @@ -1579,14 +1563,6 @@ JSC::EncodedJSValue MISSING_PASSPHRASE(JSC::ThrowScope& throwScope, JSC::JSGloba
return {};
}

JSC::EncodedJSValue KEY_GENERATION_JOB_FAILED(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject)
{
auto message = "Key generation job failed"_s;
throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_KEY_GENERATION_JOB_FAILED, message));
throwScope.release();
return {};
}

JSC::EncodedJSValue INCOMPATIBLE_OPTION_PAIR(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, ASCIILiteral opt1, ASCIILiteral opt2)
{
WTF::StringBuilder builder;
Expand Down Expand Up @@ -1630,13 +1606,6 @@ JSC::EncodedJSValue INVALID_MIME_SYNTAX(JSC::ThrowScope& scope, JSC::JSGlobalObj
return {};
}

EncodedJSValue CLOSED_MESSAGE_PORT(ThrowScope& scope, JSGlobalObject* globalObject)
{
scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CLOSED_MESSAGE_PORT, "Cannot send data on closed MessagePort"_s));
scope.release();
return {};
}

JSC::EncodedJSValue INVALID_THIS(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, ASCIILiteral expectedType)
{
WTF::StringBuilder builder;
Expand Down
4 changes: 0 additions & 4 deletions src/jsc/bindings/ErrorCode.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,8 @@ JSC::EncodedJSValue CRYPTO_INVALID_DIGEST(JSC::ThrowScope& throwScope, JSC::JSGl
JSC::EncodedJSValue CRYPTO_HASH_FINALIZED(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject);
JSC::EncodedJSValue CRYPTO_HASH_UPDATE_FAILED(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject);
JSC::EncodedJSValue MISSING_PASSPHRASE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, WTF::ASCIILiteral message);
JSC::EncodedJSValue CRYPTO_TIMING_SAFE_EQUAL_LENGTH(JSC::ThrowScope&, JSC::JSGlobalObject*);
JSC::EncodedJSValue CRYPTO_UNKNOWN_DH_GROUP(JSC::ThrowScope&, JSC::JSGlobalObject*);
JSC::EncodedJSValue CRYPTO_INVALID_KEYTYPE(JSC::ThrowScope&, JSC::JSGlobalObject*, WTF::ASCIILiteral message);
JSC::EncodedJSValue CRYPTO_INVALID_KEYTYPE(JSC::ThrowScope&, JSC::JSGlobalObject*);
JSC::EncodedJSValue CRYPTO_UNKNOWN_CIPHER(JSC::ThrowScope&, JSC::JSGlobalObject*, const WTF::StringView& cipherName);
JSC::EncodedJSValue CRYPTO_INVALID_AUTH_TAG(JSC::ThrowScope&, JSC::JSGlobalObject*, const WTF::String& message);
JSC::EncodedJSValue CRYPTO_INVALID_IV(JSC::ThrowScope&, JSC::JSGlobalObject*);
Expand All @@ -149,11 +147,9 @@ JSC::EncodedJSValue CRYPTO_INVALID_KEYLEN(JSC::ThrowScope&, JSC::JSGlobalObject*
JSC::EncodedJSValue CRYPTO_INVALID_STATE(JSC::ThrowScope&, JSC::JSGlobalObject*, WTF::ASCIILiteral message);
JSC::EncodedJSValue CRYPTO_INVALID_MESSAGELEN(JSC::ThrowScope&, JSC::JSGlobalObject*);
JSC::EncodedJSValue OSSL_EVP_INVALID_DIGEST(JSC::ThrowScope&, JSC::JSGlobalObject*);
JSC::EncodedJSValue KEY_GENERATION_JOB_FAILED(JSC::ThrowScope&, JSC::JSGlobalObject*);
JSC::EncodedJSValue INCOMPATIBLE_OPTION_PAIR(JSC::ThrowScope&, JSC::JSGlobalObject*, ASCIILiteral opt1, ASCIILiteral opt2);
JSC::EncodedJSValue MISSING_OPTION(JSC::ThrowScope&, JSC::JSGlobalObject*, ASCIILiteral message);
JSC::EncodedJSValue INVALID_MIME_SYNTAX(JSC::ThrowScope&, JSC::JSGlobalObject*, const String& part, const String& input, int position);
JSC::EncodedJSValue CLOSED_MESSAGE_PORT(JSC::ThrowScope&, JSC::JSGlobalObject*);
JSC::EncodedJSValue INVALID_THIS(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, ASCIILiteral expectedType);
JSC::EncodedJSValue DLOPEN_DISABLED(JSC::ThrowScope&, JSC::JSGlobalObject*, ASCIILiteral message);

Expand Down
5 changes: 0 additions & 5 deletions src/jsc/bindings/JSBufferList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,4 @@ void JSBufferListConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject*

const ClassInfo JSBufferListConstructor::s_info = { "BufferList"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSBufferListConstructor) };

JSValue getBufferList(Zig::GlobalObject* globalObject)
{
return static_cast<Zig::GlobalObject*>(globalObject)->JSBufferList();
}

} // namespace Zig
2 changes: 0 additions & 2 deletions src/jsc/bindings/JSBufferList.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,4 @@ class JSBufferListConstructor final : public JSC::InternalFunction {
void finishCreation(JSC::VM&, JSC::JSGlobalObject* globalObject, JSBufferListPrototype* prototype);
};

JSValue getBufferList(Zig::GlobalObject* globalObject);

}
12 changes: 1 addition & 11 deletions src/jsc/bindings/JSDOMWrapperCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ WEBCORE_EXPORT JSC::Structure* getCachedDOMStructure(const JSDOMGlobalObject&, c
WEBCORE_EXPORT JSC::Structure* cacheDOMStructure(JSDOMGlobalObject&, JSC::Structure*, const JSC::ClassInfo*);

template<typename WrapperClass> JSC::Structure* getDOMStructure(JSC::VM&, JSDOMGlobalObject&);
template<typename WrapperClass> JSC::Structure* deprecatedGetDOMStructure(JSC::JSGlobalObject*);
template<typename WrapperClass> JSC::JSObject* getDOMPrototype(JSC::VM&, JSC::JSGlobalObject*);
template<typename WrapperClass> JSC::JSObject* getDOMPrototype(JSC::VM&, JSDOMGlobalObject&);

JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, JSC::ArrayBuffer*);
void* wrapperKey(JSC::ArrayBuffer*);
Expand All @@ -58,16 +57,13 @@ bool clearInlineCachedWrapper(DOMWrapperWorld&, void*, JSDOMObject*);
bool clearInlineCachedWrapper(DOMWrapperWorld&, ScriptWrappable*, JSDOMObject* wrapper);
bool clearInlineCachedWrapper(DOMWrapperWorld&, JSC::ArrayBuffer*, JSC::JSArrayBuffer* wrapper);

template<typename DOMClass> JSC::JSObject* getOrCreateWrapper(DOMWrapperWorld&, DOMClass&);

template<typename DOMClass> JSC::JSObject* getCachedWrapper(DOMWrapperWorld&, DOMClass&);
template<typename DOMClass> inline JSC::JSObject* getCachedWrapper(DOMWrapperWorld& world, Ref<DOMClass>& object) { return getCachedWrapper(world, object.get()); }
template<typename DOMClass, typename WrapperClass> void cacheWrapper(DOMWrapperWorld&, DOMClass*, WrapperClass*);
template<typename DOMClass, typename WrapperClass> void uncacheWrapper(DOMWrapperWorld&, DOMClass*, WrapperClass*);
template<typename DOMClass, typename T> auto createWrapper(JSDOMGlobalObject*, Ref<T>&&) -> typename std::enable_if<std::is_same<DOMClass, T>::value, typename JSDOMWrapperConverterTraits<DOMClass>::WrapperClass*>::type;
template<typename DOMClass, typename T> auto createWrapper(JSDOMGlobalObject*, Ref<T>&&) -> typename std::enable_if<!std::is_same<DOMClass, T>::value, typename JSDOMWrapperConverterTraits<DOMClass>::WrapperClass*>::type;

template<typename DOMClass> JSC::JSValue wrap(JSC::JSGlobalObject*, DOMWrapperWorld&, DOMClass&);
template<typename DOMClass> JSC::JSValue wrap(JSC::JSGlobalObject*, JSDOMGlobalObject*, DOMClass&);

// Inline functions and template definitions.
Expand All @@ -87,12 +83,6 @@ template<typename WrapperClass> inline JSC::Structure* getDOMStructure(JSC::VM&
return cacheDOMStructure(globalObject, WrapperClass::createStructure(vm, &globalObject, WrapperClass::createPrototype(vm, globalObject)), WrapperClass::info());
}

template<typename WrapperClass> inline JSC::Structure* deprecatedGetDOMStructure(JSC::JSGlobalObject* lexicalGlobalObject)
{
// FIXME: This function is wrong. It uses the wrong global object for creating the prototype structure.
return getDOMStructure<WrapperClass>(JSC::getVM(lexicalGlobalObject), *deprecatedGlobalObjectForPrototype(lexicalGlobalObject));
}

template<typename WrapperClass> inline JSC::JSObject* getDOMPrototype(JSC::VM& vm, JSDOMGlobalObject& globalObject)
{
return asObject(getDOMStructure<WrapperClass>(vm, globalObject)->storedPrototype());
Expand Down
1 change: 0 additions & 1 deletion src/jsc/bindings/JSMockFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ class MockWithImplementationCleanupData : public JSC::JSInternalFieldObjectImpl<

JS_EXPORT_PRIVATE static MockWithImplementationCleanupData* create(VM&, Structure*);
static MockWithImplementationCleanupData* create(JSC::JSGlobalObject* globalObject, JSMockFunction* fn, JSValue impl, JSValue tail, JSValue fallback);
static MockWithImplementationCleanupData* createWithInitialValues(VM&, Structure*);
static Structure* createStructure(VM&, JSGlobalObject*, JSValue);

static std::array<JSValue, numberOfInternalFields> initialValues()
Expand Down
1 change: 0 additions & 1 deletion src/jsc/bindings/JSNextTickQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ class JSNextTickQueue : public JSC::JSInternalFieldObjectImpl<3> {

JS_EXPORT_PRIVATE static JSNextTickQueue* create(VM&, Structure*);
static JSNextTickQueue* create(JSC::JSGlobalObject* globalObject);
static JSNextTickQueue* createWithInitialValues(VM&, Structure*);
static Structure* createStructure(VM&, JSGlobalObject*, JSValue);

static std::array<JSValue, numberOfInternalFields> initialValues()
Expand Down
11 changes: 0 additions & 11 deletions src/jsc/bindings/JSX509CertificateConstructor.cpp

This file was deleted.

15 changes: 0 additions & 15 deletions src/jsc/bindings/JSX509CertificateConstructor.h

This file was deleted.

1 change: 0 additions & 1 deletion src/jsc/bindings/ModuleLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ class PendingVirtualModuleResult : public JSC::JSInternalFieldObjectImpl<3> {

JS_EXPORT_PRIVATE static PendingVirtualModuleResult* create(VM&, Structure*);
static PendingVirtualModuleResult* create(JSC::JSGlobalObject* globalObject, const WTF::String& specifier, const WTF::String& referrer, bool wasModuleMock);
static PendingVirtualModuleResult* createWithInitialValues(VM&, Structure*);
static Structure* createStructure(VM&, JSGlobalObject*, JSValue);

JSC::JSPromise* internalPromise();
Expand Down
3 changes: 1 addition & 2 deletions src/ptr/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ pub use weak_ptr::WeakPtr;
// (lowest tier, every crate can reach them); re-exported here so callers can
// spell `bun_ptr::container_of` / `bun_ptr::from_field_ptr!`.
pub use bun_core::{
IntrusiveField, container_of, container_of_const, from_field_ptr, impl_field_parent,
intrusive_field,
IntrusiveField, container_of, from_field_ptr, impl_field_parent, intrusive_field,
};

// C-callback `void *user_data` → `&mut T` recovery — same tiering rationale
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Guards against reintroduction of symbols removed as dead code from the
// top-level C++ bindings and bun_core. Each entry was verified to have zero
// callers across src/ and build/debug/codegen/ before deletion; this test
// fails if any reappear.
//
// This is a source-tree lint: it reads files from src/ and does not touch the
// built binary, so it belongs in test/internal/source-lints/ per the README.

import { expect, test } from "bun:test";
import { existsSync, readFileSync } from "node:fs";
import path from "node:path";

const repoRoot = path.resolve(import.meta.dir, "..", "..", "..");

function src(p: string): string {
return readFileSync(path.join(repoRoot, p), "utf8");
}

test("empty JSX509CertificateConstructor.{h,cpp} and BunHeapProfiler.h do not reappear", () => {
// JSX509CertificateConstructor.{h,cpp} contained only includes and an empty
// `namespace Bun { }` block; the real constructor class is defined inline in
// JSX509Certificate.cpp. BunHeapProfiler.h was only included by its own .cpp;
// generateHeapProfile is now file-static.
const deleted = [
"src/jsc/bindings/JSX509CertificateConstructor.h",
"src/jsc/bindings/JSX509CertificateConstructor.cpp",
"src/jsc/bindings/BunHeapProfiler.h",
];
const resurrected = deleted.filter(p => existsSync(path.join(repoRoot, p)));
expect(resurrected).toEqual([]);
});

test("dead Bun::ERR:: throw wrappers and binding declarations do not reappear", () => {
const checks: Array<[string, RegExp]> = [
// Bun::ERR:: wrappers with zero C++ callers (the corresponding ErrorCode
// enum values remain; only these convenience throw functions are dead).
["src/jsc/bindings/ErrorCode.h", /EncodedJSValue CRYPTO_TIMING_SAFE_EQUAL_LENGTH\(/],
["src/jsc/bindings/ErrorCode.h", /EncodedJSValue KEY_GENERATION_JOB_FAILED\(/],
["src/jsc/bindings/ErrorCode.h", /EncodedJSValue CLOSED_MESSAGE_PORT\(/],
["src/jsc/bindings/ErrorCode.h", /CRYPTO_INVALID_KEYTYPE\(JSC::ThrowScope&, JSC::JSGlobalObject\*\);/],
["src/jsc/bindings/ErrorCode.cpp", /EncodedJSValue CRYPTO_TIMING_SAFE_EQUAL_LENGTH\(/],
["src/jsc/bindings/ErrorCode.cpp", /EncodedJSValue KEY_GENERATION_JOB_FAILED\(/],
["src/jsc/bindings/ErrorCode.cpp", /EncodedJSValue CLOSED_MESSAGE_PORT\(/],
[
"src/jsc/bindings/ErrorCode.cpp",
/CRYPTO_INVALID_KEYTYPE\(JSC::ThrowScope& throwScope, JSC::JSGlobalObject\* globalObject\)\n/,
],
// Forward-declared template that was never defined or instantiated.
["src/jsc/bindings/JSDOMWrapperCache.h", /deprecatedGetDOMStructure/],
["src/jsc/bindings/JSDOMWrapperCache.h", /getOrCreateWrapper/],
// Static factory methods declared but never defined (would link-error if called).
["src/jsc/bindings/ModuleLoader.h", /createWithInitialValues/],
["src/jsc/bindings/JSNextTickQueue.h", /createWithInitialValues/],
["src/jsc/bindings/JSMockFunction.h", /createWithInitialValues/],
// Constructor declared but never defined.
["src/jsc/bindings/AsymmetricKeyValue.h", /AsymmetricKeyValue\(EVP_PKEY\* key, bool owned\);/],
// Free function with zero callers; ZigGlobalObject::JSBufferList() is used directly.
["src/jsc/bindings/JSBufferList.h", /getBufferList/],
["src/jsc/bindings/JSBufferList.cpp", /getBufferList/],
];
const resurrected = checks.filter(([file, re]) => re.test(src(file))).map(([file, re]) => `${file}: ${re.source}`);
expect(resurrected).toEqual([]);
});

test("bun_core dead helpers do not reappear", () => {
const checks: Array<[string, RegExp]> = [
// *const-out variant of container_of with zero callers; the *mut-out
// container_of covers every call site.
["src/bun_core/lib.rs", /pub const unsafe fn container_of_const\b/],
["src/ptr/lib.rs", /\bcontainer_of_const\b/],
// #[macro_export] literal! macro with zero invocations; callers use byte
// literals or w!() directly.
["src/bun_core/string/immutable/unicode.rs", /macro_rules! literal \{/],
["src/bun_core/string/mod.rs", /pub use crate::\{literal,/],
// From<Arc<SSLConfig>> for SharedPtr: Arc<SSLConfig> is never constructed
// outside ssl_config.rs; construction sites use SharedPtr::new or the
// tuple constructor directly.
["src/http/ssl_config.rs", /impl From<Arc<SSLConfig>> for SharedPtr/],
];
const resurrected = checks.filter(([file, re]) => re.test(src(file))).map(([file, re]) => `${file}: ${re.source}`);
expect(resurrected).toEqual([]);
});
Loading