diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 22e77d8bff70c0..418f672e34c24e 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -1308,9 +1308,9 @@ function wrapSafe(filename, content, cjsModuleInstance, codeCache) { ); // Cache the source map for the module if present. - const { sourceMapURL } = script; + const { sourceMapURL, sourceURL } = script; if (sourceMapURL) { - maybeCacheSourceMap(filename, content, this, false, undefined, sourceMapURL); + maybeCacheSourceMap(filename, content, this, false, sourceURL, sourceMapURL); } return { @@ -1332,7 +1332,7 @@ function wrapSafe(filename, content, cjsModuleInstance, codeCache) { // Cache the source map for the module if present. if (result.sourceMapURL) { - maybeCacheSourceMap(filename, content, this, false, undefined, result.sourceMapURL); + maybeCacheSourceMap(filename, content, this, false, result.sourceURL, result.sourceMapURL); } return result; diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 85c4960c8e3b11..a5fa374936353c 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -280,7 +280,7 @@ class ModuleLoader { const wrap = new ModuleWrap(url, undefined, source, 0, 0); // Cache the source map for the module if present. if (wrap.sourceMapURL) { - maybeCacheSourceMap(url, source, null, false, undefined, wrap.sourceMapURL); + maybeCacheSourceMap(url, source, null, false, wrap.sourceURL, wrap.sourceMapURL); } const { registerModule } = require('internal/modules/esm/utils'); // TODO(joyeecheung): refactor so that the default options are shared across diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 7312bd0b09f41a..1552d1ef6f841d 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -177,7 +177,7 @@ translators.set('module', function moduleStrategy(url, source, isMain) { const module = new ModuleWrap(url, undefined, source, 0, 0); // Cache the source map for the module if present. if (module.sourceMapURL) { - maybeCacheSourceMap(url, source, null, false, undefined, module.sourceMapURL); + maybeCacheSourceMap(url, source, null, false, module.sourceURL, module.sourceMapURL); } const { registerModule } = require('internal/modules/esm/utils'); registerModule(module, { @@ -227,7 +227,7 @@ function loadCJSModule(module, source, url, filename) { } // Cache the source map for the cjs module if present. if (compileResult.sourceMapURL) { - maybeCacheSourceMap(url, source, null, false, undefined, compileResult.sourceMapURL); + maybeCacheSourceMap(url, source, null, false, compileResult.sourceURL, compileResult.sourceMapURL); } const compiledWrapper = compileResult.function; diff --git a/lib/internal/source_map/source_map_cache.js b/lib/internal/source_map/source_map_cache.js index 53c3374fc09176..25fe56e6c38926 100644 --- a/lib/internal/source_map/source_map_cache.js +++ b/lib/internal/source_map/source_map_cache.js @@ -123,10 +123,10 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance, isGeneratedSo return; } - // FIXME: callers should obtain sourceURL from v8 and pass it - // rather than leaving it undefined and extract by regex. - if (sourceURL === undefined) { - sourceURL = extractSourceURLMagicComment(content); + if (sourceURL !== undefined) { + // SourceURL magic comment content might be a file path or URL. + // Normalize the sourceURL to be a file URL if it is a file path. + sourceURL = normalizeReferrerURL(sourceURL); } const data = dataFromUrl(filename, sourceMapURL); @@ -149,9 +149,6 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance, isGeneratedSo sourceURL, }; generatedSourceMapCache.set(filename, entry); - if (sourceURL) { - generatedSourceMapCache.set(sourceURL, entry); - } } else { // If there is no cjsModuleInstance and is not generated source assume we are in a // "modules/esm" context. @@ -178,7 +175,7 @@ function maybeCacheGeneratedSourceMap(content) { return; } try { - maybeCacheSourceMap(sourceURL, content, null, true, sourceURL); + maybeCacheSourceMap(sourceURL, content, null, true); } catch (err) { // This can happen if the filename is not a valid URL. // If we fail to cache the source map, we should not fail the whole process. diff --git a/lib/internal/vm.js b/lib/internal/vm.js index 0b9865ea9a0cf6..cc0cdd54ed7414 100644 --- a/lib/internal/vm.js +++ b/lib/internal/vm.js @@ -25,6 +25,7 @@ const { const { getOptionValue, } = require('internal/options'); +const { maybeCacheSourceMap } = require('internal/source_map/source_map_cache'); const { privateSymbols: { contextify_context_private_symbol, @@ -151,6 +152,7 @@ function internalCompileFunction( } registerImportModuleDynamically(result.function, importModuleDynamically); + maybeCacheSourceMap(filename, code, result.function, false, result.sourceURL, result.sourceMapURL); return result; } diff --git a/lib/internal/vm/module.js b/lib/internal/vm/module.js index cd4f3a65f8466c..b8ae4e10bda33a 100644 --- a/lib/internal/vm/module.js +++ b/lib/internal/vm/module.js @@ -77,6 +77,7 @@ const kPerContextModuleId = Symbol('kPerContextModuleId'); const kLink = Symbol('kLink'); const { isContext } = require('internal/vm'); +const { maybeCacheSourceMap } = require('internal/source_map/source_map_cache'); function isModule(object) { if (typeof object !== 'object' || object === null || !ObjectPrototypeHasOwnProperty(object, kWrap)) { @@ -141,6 +142,7 @@ class Module { importModuleDynamicallyWrap(options.importModuleDynamically) : undefined, }; + maybeCacheSourceMap(identifier, sourceText, this, false, this[kWrap].sourceURL, this[kWrap].sourceMapURL); } else { assert(syntheticEvaluationSteps); this[kWrap] = new ModuleWrap(identifier, context, diff --git a/lib/vm.js b/lib/vm.js index 34814c430d3253..138b2118eaa359 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -63,6 +63,7 @@ const { isContext: _isContext, registerImportModuleDynamically, } = require('internal/vm'); +const { maybeCacheSourceMap } = require('internal/source_map/source_map_cache'); const { vm_dynamic_import_main_context_default, } = internalBinding('symbols'); @@ -126,6 +127,7 @@ class Script extends ContextifyScript { } registerImportModuleDynamically(this, importModuleDynamically); + maybeCacheSourceMap(filename, code, this, false, this.sourceURL, this.sourceMapURL); } runInThisContext(options) { diff --git a/src/env_properties.h b/src/env_properties.h index 05d8fcf576c51a..287e669012e2d8 100644 --- a/src/env_properties.h +++ b/src/env_properties.h @@ -300,6 +300,7 @@ V(sni_context_string, "sni_context") \ V(source_string, "source") \ V(source_map_url_string, "sourceMapURL") \ + V(source_url_string, "sourceURL") \ V(stack_string, "stack") \ V(standard_name_string, "standardName") \ V(start_time_string, "startTime") \ diff --git a/src/module_wrap.cc b/src/module_wrap.cc index 92b34f5a8b99c2..b5f05a6b62dfc4 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -265,6 +265,13 @@ void ModuleWrap::New(const FunctionCallbackInfo& args) { return; } + if (that->Set(context, + realm->env()->source_url_string(), + module->GetUnboundModuleScript()->GetSourceURL()) + .IsNothing()) { + return; + } + if (that->Set(context, realm->env()->source_map_url_string(), module->GetUnboundModuleScript()->GetSourceMappingURL()) diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 0f94ea501cea64..f317b1301dd2fb 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -905,6 +905,13 @@ void ContextifyScript::New(const FunctionCallbackInfo& args) { return; } + if (args.This() + ->Set(env->context(), + env->source_url_string(), + v8_script->GetSourceURL()) + .IsNothing()) + return; + if (args.This() ->Set(env->context(), env->source_map_url_string(), @@ -1373,6 +1380,15 @@ Local ContextifyContext::CompileFunctionAndCacheResult( Local result = Object::New(isolate); if (result->Set(parsing_context, env->function_string(), fn).IsNothing()) return Object::New(env->isolate()); + + // ScriptOrigin::ResourceName() returns SourceURL magic comment content if + // present. + if (result + ->Set(parsing_context, + env->source_url_string(), + fn->GetScriptOrigin().ResourceName()) + .IsNothing()) + return Object::New(env->isolate()); if (result ->Set(parsing_context, env->source_map_url_string(), @@ -1650,11 +1666,15 @@ static void CompileFunctionForCJSLoader( std::vector> names = { env->cached_data_rejected_string(), env->source_map_url_string(), + env->source_url_string(), env->function_string(), }; std::vector> values = { Boolean::New(isolate, cache_rejected), fn->GetScriptOrigin().SourceMapUrl(), + // ScriptOrigin::ResourceName() returns SourceURL magic comment content if + // present. + fn->GetScriptOrigin().ResourceName(), fn, }; Local result = Object::New( diff --git a/src/node_errors.cc b/src/node_errors.cc index ff091fd20d915b..4b560b8b4feffc 100644 --- a/src/node_errors.cc +++ b/src/node_errors.cc @@ -57,7 +57,20 @@ static std::string GetSourceMapErrorSource(Isolate* isolate, bool* added_exception_line) { v8::TryCatch try_catch(isolate); HandleScope handle_scope(isolate); - Environment* env = Environment::GetCurrent(context); + Realm* realm = Realm::GetCurrent(context); + + Local get_source; + if (realm != nullptr) { + // If we are in a Realm, call the realm specific getSourceMapErrorSource + // callback to avoid passing the JS objects (the exception and trace) across + // the realm boundary. + get_source = realm->get_source_map_error_source(); + } else { + Environment* env = Environment::GetCurrent(context); + // The context is created with ContextifyContext, call the principal + // realm's getSourceMapErrorSource callback. + get_source = env->principal_realm()->get_source_map_error_source(); + } // The ScriptResourceName of the message may be different from the one we use // to compile the script. V8 replaces it when it detects magic comments in @@ -69,8 +82,8 @@ static std::string GetSourceMapErrorSource(Isolate* isolate, Local argv[] = {script_resource_name, v8::Int32::New(isolate, linenum), v8::Int32::New(isolate, columnum)}; - MaybeLocal maybe_ret = env->get_source_map_error_source()->Call( - context, Undefined(isolate), arraysize(argv), argv); + MaybeLocal maybe_ret = + get_source->Call(context, Undefined(isolate), arraysize(argv), argv); Local ret; if (!maybe_ret.ToLocal(&ret)) { // Ignore the caught exceptions. diff --git a/test/common/assertSnapshot.js b/test/common/assertSnapshot.js index 88f40281e069b7..cb3b9fd332b24b 100644 --- a/test/common/assertSnapshot.js +++ b/test/common/assertSnapshot.js @@ -8,6 +8,11 @@ const assert = require('node:assert/strict'); const stackFramesRegexp = /(?<=\n)(\s+)((.+?)\s+\()?(?:\(?(.+?):(\d+)(?::(\d+))?)\)?(\s+\{)?(\[\d+m)?(\n|$)/g; const windowNewlineRegexp = /\r/g; +function replaceExperimentalWarning(str) { + return str.replace(/\(node:\d+\) ExperimentalWarning: (.*)\n/g, '') + .replace('(Use `node --trace-warnings ...` to show where the warning was created)\n', ''); +} + function replaceNodeVersion(str) { return str.replaceAll(process.version, '*'); } @@ -16,6 +21,10 @@ function replaceStackTrace(str, replacement = '$1*$7$8\n') { return str.replace(stackFramesRegexp, replacement); } +function replaceInternalStackTrace(str) { + return str.replaceAll(/(\W+).*node:internal.*/g, '$1*'); +} + function replaceWindowsLineEndings(str) { return str.replace(windowNewlineRegexp, ''); } @@ -24,8 +33,20 @@ function replaceWindowsPaths(str) { return common.isWindows ? str.replaceAll(path.win32.sep, path.posix.sep) : str; } -function replaceFullPaths(str) { - return str.replaceAll(process.cwd(), ''); +function replaceWindowsDriveLetter(str) { + if (!common.isWindows) { + return str; + } + const currentDriveLetter = path.parse(process.cwd()).root.substring(0, 1).toLowerCase(); + const regex = new RegExp(`${currentDriveLetter}:`, 'gi'); + return str.replaceAll(regex, ''); +} + +function transformCwd(replacement = '') { + const cwd = process.cwd(); + return (str) => { + return str.replaceAll(cwd, replacement); + }; } function transform(...args) { @@ -87,11 +108,14 @@ async function spawnAndAssert(filename, transform = (x) => x, { tty = false, ... module.exports = { assertSnapshot, getSnapshotPath, - replaceFullPaths, + replaceExperimentalWarning, replaceNodeVersion, replaceStackTrace, + replaceInternalStackTrace, replaceWindowsLineEndings, replaceWindowsPaths, + replaceWindowsDriveLetter, spawnAndAssert, transform, + transformCwd, }; diff --git a/test/fixtures/source-map/output/source_map_disabled_by_api.snapshot b/test/fixtures/source-map/output/source_map_disabled_by_api.snapshot index 655cd6695e1116..f538904873393e 100644 --- a/test/fixtures/source-map/output/source_map_disabled_by_api.snapshot +++ b/test/fixtures/source-map/output/source_map_disabled_by_api.snapshot @@ -1,12 +1,12 @@ Error: an error! - at functionD (*enclosing-call-site-min.js:1:156) - at functionC (*enclosing-call-site-min.js:1:97) - at functionB (*enclosing-call-site-min.js:1:60) - at functionA (*enclosing-call-site-min.js:1:26) - at Object. (*enclosing-call-site-min.js:1:199) + at functionD (*/test/fixtures/source-map/enclosing-call-site-min.js:1:156) + at functionC (*/test/fixtures/source-map/enclosing-call-site-min.js:1:97) + at functionB (*/test/fixtures/source-map/enclosing-call-site-min.js:1:60) + at functionA (*/test/fixtures/source-map/enclosing-call-site-min.js:1:26) + at Object. (*/test/fixtures/source-map/enclosing-call-site-min.js:1:199) Error: an error! - at functionD (*enclosing-call-site.js:16:17) - at functionC (*enclosing-call-site.js:10:3) - at functionB (*enclosing-call-site.js:6:3) - at functionA (*enclosing-call-site.js:2:3) - at Object. (*enclosing-call-site.js:24:3) + at functionD (*/test/fixtures/source-map/enclosing-call-site.js:16:17) + at functionC (*/test/fixtures/source-map/enclosing-call-site.js:10:3) + at functionB (*/test/fixtures/source-map/enclosing-call-site.js:6:3) + at functionA (*/test/fixtures/source-map/enclosing-call-site.js:2:3) + at Object. (*/test/fixtures/source-map/enclosing-call-site.js:24:3) diff --git a/test/fixtures/source-map/output/source_map_enabled_by_api.snapshot b/test/fixtures/source-map/output/source_map_enabled_by_api.snapshot index 082b3f310ed4f9..9fe43a29865b35 100644 --- a/test/fixtures/source-map/output/source_map_enabled_by_api.snapshot +++ b/test/fixtures/source-map/output/source_map_enabled_by_api.snapshot @@ -1,12 +1,12 @@ Error: an error! - at functionD (*enclosing-call-site.js:16:17) - at functionC (*enclosing-call-site.js:10:3) - at functionB (*enclosing-call-site.js:6:3) - at functionA (*enclosing-call-site.js:2:3) - at Object. (*enclosing-call-site.js:24:3) + at functionD (*/test/fixtures/source-map/enclosing-call-site.js:16:17) + at functionC (*/test/fixtures/source-map/enclosing-call-site.js:10:3) + at functionB (*/test/fixtures/source-map/enclosing-call-site.js:6:3) + at functionA (*/test/fixtures/source-map/enclosing-call-site.js:2:3) + at Object. (*/test/fixtures/source-map/enclosing-call-site.js:24:3) Error: an error! - at functionD (*enclosing-call-site-min.js:1:156) - at functionC (*enclosing-call-site-min.js:1:97) - at functionB (*enclosing-call-site-min.js:1:60) - at functionA (*enclosing-call-site-min.js:1:26) - at Object. (*enclosing-call-site-min.js:1:199) + at functionD (*/test/fixtures/source-map/enclosing-call-site-min.js:1:156) + at functionC (*/test/fixtures/source-map/enclosing-call-site-min.js:1:97) + at functionB (*/test/fixtures/source-map/enclosing-call-site-min.js:1:60) + at functionA (*/test/fixtures/source-map/enclosing-call-site-min.js:1:26) + at Object. (*/test/fixtures/source-map/enclosing-call-site-min.js:1:199) diff --git a/test/fixtures/source-map/output/source_map_enclosing_function.snapshot b/test/fixtures/source-map/output/source_map_enclosing_function.snapshot index 976cd4fdbbc6e9..b60f988be3214e 100644 --- a/test/fixtures/source-map/output/source_map_enclosing_function.snapshot +++ b/test/fixtures/source-map/output/source_map_enclosing_function.snapshot @@ -1,13 +1,13 @@ -*enclosing-call-site.js:26 +*/test/fixtures/source-map/enclosing-call-site.js:26 throw err ^ Error: an error! - at functionD (*enclosing-call-site.js:16:17) - at functionC (*enclosing-call-site.js:10:3) - at functionB (*enclosing-call-site.js:6:3) - at functionA (*enclosing-call-site.js:2:3) - at Object. (*enclosing-call-site.js:24:3) + at functionD (*/test/fixtures/source-map/enclosing-call-site.js:16:17) + at functionC (*/test/fixtures/source-map/enclosing-call-site.js:10:3) + at functionB (*/test/fixtures/source-map/enclosing-call-site.js:6:3) + at functionA (*/test/fixtures/source-map/enclosing-call-site.js:2:3) + at Object. (*/test/fixtures/source-map/enclosing-call-site.js:24:3) Node.js * diff --git a/test/fixtures/source-map/output/source_map_eval.js b/test/fixtures/source-map/output/source_map_eval.js index 5492c179248180..5270de68826103 100644 --- a/test/fixtures/source-map/output/source_map_eval.js +++ b/test/fixtures/source-map/output/source_map_eval.js @@ -7,4 +7,5 @@ Error.stackTraceLimit = 3; const fs = require('fs'); const content = fs.readFileSync(require.resolve('../tabs.js'), 'utf8'); +// SourceURL magic comment is hardcoded in the source content. eval(content); diff --git a/test/fixtures/source-map/output/source_map_eval.snapshot b/test/fixtures/source-map/output/source_map_eval.snapshot index a4fcdb25282dfa..87afb545b56636 100644 --- a/test/fixtures/source-map/output/source_map_eval.snapshot +++ b/test/fixtures/source-map/output/source_map_eval.snapshot @@ -1,11 +1,11 @@ -*tabs.coffee:26 +/synthethized/workspace/tabs.coffee:26 alert "I knew it!" ^ ReferenceError: alert is not defined - at Object.eval (*tabs.coffee:26:2) - at eval (*tabs.coffee:1:14) - at Object. (*output*source_map_eval.js:10:1) + at Object.eval (/synthethized/workspace/tabs.coffee:26:2) + at eval (/synthethized/workspace/tabs.coffee:1:14) + at Object. (*/test/fixtures/source-map/output/source_map_eval.js:11:1) Node.js * diff --git a/test/fixtures/source-map/output/source_map_no_source_file.snapshot b/test/fixtures/source-map/output/source_map_no_source_file.snapshot index cf9329747ba692..6d0e0cf6db727e 100644 --- a/test/fixtures/source-map/output/source_map_no_source_file.snapshot +++ b/test/fixtures/source-map/output/source_map_no_source_file.snapshot @@ -1,9 +1,9 @@ -*no-source.js:2 +*/test/fixtures/source-map/no-source.js:2 throw new Error('foo'); ^ Error: foo - at Throw (*file-not-exists.ts:2:9) - at Object. (*file-not-exists.ts:5:1) + at Throw (*/test/fixtures/source-map/file-not-exists.ts:2:9) + at Object. (*/test/fixtures/source-map/file-not-exists.ts:5:1) Node.js * diff --git a/test/fixtures/source-map/output/source_map_prepare_stack_trace.snapshot b/test/fixtures/source-map/output/source_map_prepare_stack_trace.snapshot index 9e9740a26fc34e..57bac36a2e5214 100644 --- a/test/fixtures/source-map/output/source_map_prepare_stack_trace.snapshot +++ b/test/fixtures/source-map/output/source_map_prepare_stack_trace.snapshot @@ -1,10 +1,10 @@ Error: an error! - at functionD (*enclosing-call-site.js:16:17) - at functionB (*enclosing-call-site.js:6:3) - at functionA (*enclosing-call-site.js:2:3) - at Object. (*enclosing-call-site.js:24:3) + at functionD (*/test/fixtures/source-map/enclosing-call-site.js:16:17) + at functionB (*/test/fixtures/source-map/enclosing-call-site.js:6:3) + at functionA (*/test/fixtures/source-map/enclosing-call-site.js:2:3) + at Object. (*/test/fixtures/source-map/enclosing-call-site.js:24:3) Error: an error! - at functionD (*enclosing-call-site-min.js:1:156) - at functionB (*enclosing-call-site-min.js:1:60) - at functionA (*enclosing-call-site-min.js:1:26) - at Object. (*enclosing-call-site-min.js:1:199) + at functionD (*/test/fixtures/source-map/enclosing-call-site-min.js:1:156) + at functionB (*/test/fixtures/source-map/enclosing-call-site-min.js:1:60) + at functionA (*/test/fixtures/source-map/enclosing-call-site-min.js:1:26) + at Object. (*/test/fixtures/source-map/enclosing-call-site-min.js:1:199) diff --git a/test/fixtures/source-map/output/source_map_reference_error_tabs.snapshot b/test/fixtures/source-map/output/source_map_reference_error_tabs.snapshot index 97d02f176c0cb7..2043bd0a88e897 100644 --- a/test/fixtures/source-map/output/source_map_reference_error_tabs.snapshot +++ b/test/fixtures/source-map/output/source_map_reference_error_tabs.snapshot @@ -1,10 +1,10 @@ -*tabs.coffee:26 +*/test/fixtures/source-map/tabs.coffee:26 alert "I knew it!" ^ ReferenceError: alert is not defined - at Object. (*tabs.coffee:26:2) - at Object. (*tabs.coffee:1:14) + at Object. (*/test/fixtures/source-map/tabs.coffee:26:2) + at Object. (*/test/fixtures/source-map/tabs.coffee:1:14) Node.js * diff --git a/test/fixtures/source-map/output/source_map_sourcemapping_url_string.snapshot b/test/fixtures/source-map/output/source_map_sourcemapping_url_string.snapshot index 6a109c904e1155..52d4e6a28ee5ce 100644 --- a/test/fixtures/source-map/output/source_map_sourcemapping_url_string.snapshot +++ b/test/fixtures/source-map/output/source_map_sourcemapping_url_string.snapshot @@ -1,3 +1,3 @@ Error: an exception. - at Object. (*typescript-sourcemapping_url_string.ts:3:7) + at Object. (*/test/fixtures/source-map/typescript-sourcemapping_url_string.ts:3:7) * diff --git a/test/fixtures/source-map/output/source_map_throw_catch.snapshot b/test/fixtures/source-map/output/source_map_throw_catch.snapshot index 5eaffbfbf7874f..6e80e500c8cf17 100644 --- a/test/fixtures/source-map/output/source_map_throw_catch.snapshot +++ b/test/fixtures/source-map/output/source_map_throw_catch.snapshot @@ -1,4 +1,4 @@ reachable Error: an exception - at branch (*typescript-throw.ts:18:11) - at Object. (*typescript-throw.ts:24:1) + at branch (*/test/fixtures/source-map/typescript-throw.ts:18:11) + at Object. (*/test/fixtures/source-map/typescript-throw.ts:24:1) diff --git a/test/fixtures/source-map/output/source_map_throw_first_tick.snapshot b/test/fixtures/source-map/output/source_map_throw_first_tick.snapshot index fba8c95cc1103f..e129d73ef1581c 100644 --- a/test/fixtures/source-map/output/source_map_throw_first_tick.snapshot +++ b/test/fixtures/source-map/output/source_map_throw_first_tick.snapshot @@ -1,11 +1,11 @@ reachable -*typescript-throw.ts:18 +*/test/fixtures/source-map/typescript-throw.ts:18 throw Error('an exception'); ^ Error: an exception - at branch (*typescript-throw.ts:18:11) - at Object. (*typescript-throw.ts:24:1) + at branch (*/test/fixtures/source-map/typescript-throw.ts:18:11) + at Object. (*/test/fixtures/source-map/typescript-throw.ts:24:1) Node.js * diff --git a/test/fixtures/source-map/output/source_map_throw_icu.snapshot b/test/fixtures/source-map/output/source_map_throw_icu.snapshot index 425495062e6423..4b2853479b9576 100644 --- a/test/fixtures/source-map/output/source_map_throw_icu.snapshot +++ b/test/fixtures/source-map/output/source_map_throw_icu.snapshot @@ -1,10 +1,10 @@ -*icu.jsx:3 +*/test/fixtures/source-map/icu.jsx:3 ("あ 🐕 🐕", throw Error("an error")); ^ Error: an error - at Object.createElement (*icu.jsx:3:23) - at Object. (*icu.jsx:9:5) + at Object.createElement (*/test/fixtures/source-map/icu.jsx:3:23) + at Object. (*/test/fixtures/source-map/icu.jsx:9:5) Node.js * diff --git a/test/fixtures/source-map/output/source_map_throw_set_immediate.snapshot b/test/fixtures/source-map/output/source_map_throw_set_immediate.snapshot index e5054d01b8f91b..4cf4d52a16ea93 100644 --- a/test/fixtures/source-map/output/source_map_throw_set_immediate.snapshot +++ b/test/fixtures/source-map/output/source_map_throw_set_immediate.snapshot @@ -1,11 +1,11 @@ -*uglify-throw-original.js:5 +*/test/fixtures/source-map/uglify-throw-original.js:5 throw Error('goodbye'); ^ Error: goodbye - at Hello (*uglify-throw-original.js:5:9) - at Immediate. (*uglify-throw-original.js:9:3) - at process.processImmediate (node:internal*timers:478:21) + at Hello (*/test/fixtures/source-map/uglify-throw-original.js:5:9) + at Immediate. (*/test/fixtures/source-map/uglify-throw-original.js:9:3) + * Node.js * diff --git a/test/fixtures/source-map/output/source_map_vm_function.js b/test/fixtures/source-map/output/source_map_vm_function.js new file mode 100644 index 00000000000000..01fe273f0b34dd --- /dev/null +++ b/test/fixtures/source-map/output/source_map_vm_function.js @@ -0,0 +1,18 @@ +// Flags: --enable-source-maps + +'use strict'; +require('../../../common'); +const vm = require('vm'); + +const fs = require('fs'); +const filename = require.resolve('../tabs.js'); +const content = fs.readFileSync(filename, 'utf8'); + +const context = vm.createContext({}); +vm.runInContext('Error.stackTraceLimit = 3', context); + +const fn = vm.compileFunction(content, [], { + filename, + parsingContext: context, +}) +fn(); diff --git a/test/fixtures/source-map/output/source_map_vm_function.snapshot b/test/fixtures/source-map/output/source_map_vm_function.snapshot new file mode 100644 index 00000000000000..6a5d3bb7d64b2a --- /dev/null +++ b/test/fixtures/source-map/output/source_map_vm_function.snapshot @@ -0,0 +1,11 @@ +*/test/fixtures/source-map/tabs.coffee:26 + alert "I knew it!" + ^ + + +ReferenceError: alert is not defined + at (*/test/fixtures/source-map/tabs.coffee:26:2) + at (*/test/fixtures/source-map/tabs.coffee:1:14) + at Object. (*/test/fixtures/source-map/output/source_map_vm_function.js:18:1) + +Node.js * diff --git a/test/fixtures/source-map/output/source_map_vm_module.js b/test/fixtures/source-map/output/source_map_vm_module.js new file mode 100644 index 00000000000000..117e31bd03b856 --- /dev/null +++ b/test/fixtures/source-map/output/source_map_vm_module.js @@ -0,0 +1,22 @@ +// Flags: --enable-source-maps --experimental-vm-modules + +'use strict'; +const common = require('../../../common'); +const vm = require('vm'); +Error.stackTraceLimit = 3; + +const fs = require('fs'); +const filename = require.resolve('../tabs.js'); +const content = fs.readFileSync(filename, 'utf8'); + +const context = vm.createContext({}); +vm.runInContext('Error.stackTraceLimit = 3', context); + +(async () => { + const mod = new vm.SourceTextModule(content, { + context, + identifier: filename, + }); + await mod.link(common.mustNotCall()); + await mod.evaluate(); +})(); diff --git a/test/fixtures/source-map/output/source_map_vm_module.snapshot b/test/fixtures/source-map/output/source_map_vm_module.snapshot new file mode 100644 index 00000000000000..76c8a437116fba --- /dev/null +++ b/test/fixtures/source-map/output/source_map_vm_module.snapshot @@ -0,0 +1,11 @@ +*/test/fixtures/source-map/tabs.coffee:26 + alert "I knew it!" + ^ + + +ReferenceError: alert is not defined + at (*/test/fixtures/source-map/tabs.coffee:26:2) + at (*/test/fixtures/source-map/tabs.coffee:1:14) + * + +Node.js * diff --git a/test/fixtures/source-map/output/source_map_vm_script.js b/test/fixtures/source-map/output/source_map_vm_script.js new file mode 100644 index 00000000000000..f6eff3282c0294 --- /dev/null +++ b/test/fixtures/source-map/output/source_map_vm_script.js @@ -0,0 +1,28 @@ +// Flags: --enable-source-maps + +'use strict'; +require('../../../common'); +const vm = require('vm'); +Error.stackTraceLimit = 3; + +const fs = require('fs'); +const filename = require.resolve('../tabs.js'); +const content = fs.readFileSync(filename, 'utf8'); + +const context = vm.createContext({}); +vm.runInContext('Error.stackTraceLimit = 3', context); + +// Scripts created implicitly with `vm.runInContext`. +try { + vm.runInContext(content, context, { + filename, + }); +} catch (e) { + console.error(e); +} + +// Scripts created explicitly with `vm.Script`. +const script = new vm.Script(content, { + filename, +}); +script.runInContext(context); diff --git a/test/fixtures/source-map/output/source_map_vm_script.snapshot b/test/fixtures/source-map/output/source_map_vm_script.snapshot new file mode 100644 index 00000000000000..dfce0837dfb7ea --- /dev/null +++ b/test/fixtures/source-map/output/source_map_vm_script.snapshot @@ -0,0 +1,20 @@ +*/test/fixtures/source-map/tabs.coffee:26 + alert "I knew it!" + ^ + + +ReferenceError: alert is not defined + at (*/test/fixtures/source-map/tabs.coffee:26:2) + at (*/test/fixtures/source-map/tabs.coffee:1:14) + at Script.runInContext (node:vm:150:12) +*/test/fixtures/source-map/tabs.coffee:26 + alert "I knew it!" + ^ + + +ReferenceError: alert is not defined + at (*/test/fixtures/source-map/tabs.coffee:26:2) + at (*/test/fixtures/source-map/tabs.coffee:1:14) + at Script.runInContext (node:vm:150:12) + +Node.js * diff --git a/test/fixtures/source-map/tabs.coffee b/test/fixtures/source-map/tabs.coffee index abc5baab636e8a..dd03beeedf4ee8 100644 --- a/test/fixtures/source-map/tabs.coffee +++ b/test/fixtures/source-map/tabs.coffee @@ -27,3 +27,8 @@ if true # Array comprehensions: cubes = (math.cube num for num in list) + +# To reproduce: +# cd test/fixtures/source-map +# npx --package=coffeescript@2.5.1 -- coffee -M --compile tabs.coffee +# sed -i -e "s/$(pwd | sed -e "s/\//\\\\\//g")/\\/synthethized\\/workspace/g" tabs.js diff --git a/test/fixtures/source-map/tabs.js b/test/fixtures/source-map/tabs.js index 4e8ebf149dfd16..c13ea80a74922f 100644 --- a/test/fixtures/source-map/tabs.js +++ b/test/fixtures/source-map/tabs.js @@ -50,7 +50,12 @@ return results; })(); + // To reproduce: +// cd test/fixtures/source-map +// npx --package=coffeescript@2.5.1 -- coffee -M --compile tabs.coffee +// sed -i -e "s/$(pwd | sed -e "s/\//\\\\\//g")/\\/synthethized\\/workspace/g" tabs.js + }).call(this); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRhYnMuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBYTtFQUFBO0FBQUEsTUFBQSxLQUFBLEVBQUEsSUFBQSxFQUFBLElBQUEsRUFBQSxHQUFBLEVBQUEsTUFBQSxFQUFBLFFBQUEsRUFBQSxJQUFBLEVBQUE7O0VBQ2IsTUFBQSxHQUFXOztFQUNYLFFBQUEsR0FBVzs7RUFHWCxJQUFnQixRQUFoQjs7SUFBQSxNQUFBLEdBQVMsQ0FBQyxHQUFWO0dBTGE7OztFQVFiLE1BQUEsR0FBUyxRQUFBLENBQUMsQ0FBRCxDQUFBO1dBQU8sQ0FBQSxHQUFJO0VBQVgsRUFSSTs7O0VBV2IsSUFBQSxHQUFPLENBQUMsQ0FBRCxFQUFJLENBQUosRUFBTyxDQUFQLEVBQVUsQ0FBVixFQUFhLENBQWIsRUFYTTs7O0VBY2IsSUFBQSxHQUNDO0lBQUEsSUFBQSxFQUFRLElBQUksQ0FBQyxJQUFiO0lBQ0EsTUFBQSxFQUFRLE1BRFI7SUFFQSxJQUFBLEVBQVEsUUFBQSxDQUFDLENBQUQsQ0FBQTthQUFPLENBQUEsR0FBSSxNQUFBLENBQU8sQ0FBUDtJQUFYO0VBRlIsRUFmWTs7O0VBb0JiLElBQUEsR0FBTyxRQUFBLENBQUMsTUFBRCxFQUFBLEdBQVMsT0FBVCxDQUFBO1dBQ04sS0FBQSxDQUFNLE1BQU4sRUFBYyxPQUFkO0VBRE0sRUFwQk07OztFQXdCYixJQUFHLElBQUg7SUFDQyxLQUFBLENBQU0sWUFBTixFQUREO0dBeEJhOzs7RUE0QmIsS0FBQTs7QUFBUztJQUFBLEtBQUEsc0NBQUE7O21CQUFBLElBQUksQ0FBQyxJQUFMLENBQVUsR0FBVjtJQUFBLENBQUE7OztBQTVCSSIsInNvdXJjZXNDb250ZW50IjpbIiMgQXNzaWdubWVudDpcbm51bWJlciAgID0gNDJcbm9wcG9zaXRlID0gdHJ1ZVxuXG4jIENvbmRpdGlvbnM6XG5udW1iZXIgPSAtNDIgaWYgb3Bwb3NpdGVcblxuIyBGdW5jdGlvbnM6XG5zcXVhcmUgPSAoeCkgLT4geCAqIHhcblxuIyBBcnJheXM6XG5saXN0ID0gWzEsIDIsIDMsIDQsIDVdXG5cbiMgT2JqZWN0czpcbm1hdGggPVxuXHRyb290OiAgIE1hdGguc3FydFxuXHRzcXVhcmU6IHNxdWFyZVxuXHRjdWJlOiAgICh4KSAtPiB4ICogc3F1YXJlIHhcblxuIyBTcGxhdHM6XG5yYWNlID0gKHdpbm5lciwgcnVubmVycy4uLikgLT5cblx0cHJpbnQgd2lubmVyLCBydW5uZXJzXG5cbiMgRXhpc3RlbmNlOlxuaWYgdHJ1ZVxuXHRhbGVydCBcIkkga25ldyBpdCFcIlxuXG4jIEFycmF5IGNvbXByZWhlbnNpb25zOlxuY3ViZXMgPSAobWF0aC5jdWJlIG51bSBmb3IgbnVtIGluIGxpc3QpXG4iXX0= -//# sourceURL=/Users/bencoe/oss/coffee-script-test/tabs.coffee +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRhYnMuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBYTtFQUFBO0FBQUEsTUFBQSxLQUFBLEVBQUEsSUFBQSxFQUFBLElBQUEsRUFBQSxHQUFBLEVBQUEsTUFBQSxFQUFBLFFBQUEsRUFBQSxJQUFBLEVBQUE7O0VBQ2IsTUFBQSxHQUFXOztFQUNYLFFBQUEsR0FBVzs7RUFHWCxJQUFnQixRQUFoQjs7SUFBQSxNQUFBLEdBQVMsQ0FBQyxHQUFWO0dBTGE7OztFQVFiLE1BQUEsR0FBUyxRQUFBLENBQUMsQ0FBRCxDQUFBO1dBQU8sQ0FBQSxHQUFJO0VBQVgsRUFSSTs7O0VBV2IsSUFBQSxHQUFPLENBQUMsQ0FBRCxFQUFJLENBQUosRUFBTyxDQUFQLEVBQVUsQ0FBVixFQUFhLENBQWIsRUFYTTs7O0VBY2IsSUFBQSxHQUNDO0lBQUEsSUFBQSxFQUFRLElBQUksQ0FBQyxJQUFiO0lBQ0EsTUFBQSxFQUFRLE1BRFI7SUFFQSxJQUFBLEVBQVEsUUFBQSxDQUFDLENBQUQsQ0FBQTthQUFPLENBQUEsR0FBSSxNQUFBLENBQU8sQ0FBUDtJQUFYO0VBRlIsRUFmWTs7O0VBb0JiLElBQUEsR0FBTyxRQUFBLENBQUMsTUFBRCxFQUFBLEdBQVMsT0FBVCxDQUFBO1dBQ04sS0FBQSxDQUFNLE1BQU4sRUFBYyxPQUFkO0VBRE0sRUFwQk07OztFQXdCYixJQUFHLElBQUg7SUFDQyxLQUFBLENBQU0sWUFBTixFQUREO0dBeEJhOzs7RUE0QmIsS0FBQTs7QUFBUztJQUFBLEtBQUEsc0NBQUE7O21CQUFBLElBQUksQ0FBQyxJQUFMLENBQVUsR0FBVjtJQUFBLENBQUE7Ozs7RUE1Qkk7Ozs7QUFBQSIsInNvdXJjZXNDb250ZW50IjpbIiMgQXNzaWdubWVudDpcbm51bWJlciAgID0gNDJcbm9wcG9zaXRlID0gdHJ1ZVxuXG4jIENvbmRpdGlvbnM6XG5udW1iZXIgPSAtNDIgaWYgb3Bwb3NpdGVcblxuIyBGdW5jdGlvbnM6XG5zcXVhcmUgPSAoeCkgLT4geCAqIHhcblxuIyBBcnJheXM6XG5saXN0ID0gWzEsIDIsIDMsIDQsIDVdXG5cbiMgT2JqZWN0czpcbm1hdGggPVxuXHRyb290OiAgIE1hdGguc3FydFxuXHRzcXVhcmU6IHNxdWFyZVxuXHRjdWJlOiAgICh4KSAtPiB4ICogc3F1YXJlIHhcblxuIyBTcGxhdHM6XG5yYWNlID0gKHdpbm5lciwgcnVubmVycy4uLikgLT5cblx0cHJpbnQgd2lubmVyLCBydW5uZXJzXG5cbiMgRXhpc3RlbmNlOlxuaWYgdHJ1ZVxuXHRhbGVydCBcIkkga25ldyBpdCFcIlxuXG4jIEFycmF5IGNvbXByZWhlbnNpb25zOlxuY3ViZXMgPSAobWF0aC5jdWJlIG51bSBmb3IgbnVtIGluIGxpc3QpXG5cbiMgVG8gcmVwcm9kdWNlOlxuIyBjZCB0ZXN0L2ZpeHR1cmVzL3NvdXJjZS1tYXBcbiMgbnB4IC0tcGFja2FnZT1jb2ZmZWVzY3JpcHRAMi41LjEgLS0gY29mZmVlIC1NIC0tY29tcGlsZSB0YWJzLmNvZmZlZVxuIyBzZWQgLWkgLWUgXCJzLyQocHdkIHwgc2VkIC1lIFwicy9cXC8vXFxcXFxcXFxcXC8vZ1wiKS9cXFxcL3N5bnRoZXRoaXplZFxcXFwvd29ya3NwYWNlL2dcIiB0YWJzLmpzXG4iXX0= +//# sourceURL=/synthethized/workspace/tabs.coffee \ No newline at end of file diff --git a/test/parallel/test-node-output-sourcemaps.mjs b/test/parallel/test-node-output-sourcemaps.mjs index d82f4a249cd1d9..64a33f71795232 100644 --- a/test/parallel/test-node-output-sourcemaps.mjs +++ b/test/parallel/test-node-output-sourcemaps.mjs @@ -1,29 +1,20 @@ -import * as common from '../common/index.mjs'; +import '../common/index.mjs'; import * as fixtures from '../common/fixtures.mjs'; import * as snapshot from '../common/assertSnapshot.js'; -import * as path from 'node:path'; import { describe, it } from 'node:test'; describe('sourcemaps output', { concurrency: !process.env.TEST_PARALLEL }, () => { - function normalize(str) { - const result = str - .replaceAll(snapshot.replaceWindowsPaths(process.cwd()), '') - .replaceAll('//', '*') - .replaceAll('/Users/bencoe/oss/coffee-script-test', '') - .replaceAll(/\/(\w)/g, '*$1') - .replaceAll('*test*', '*') - .replaceAll('*fixtures*source-map*', '*') - .replaceAll(/(\W+).*node:internal\*modules.*/g, '$1*'); - if (common.isWindows) { - const currentDeviceLetter = path.parse(process.cwd()).root.substring(0, 1).toLowerCase(); - const regex = new RegExp(`${currentDeviceLetter}:/?`, 'gi'); - return result.replaceAll(regex, ''); - } - return result; - } const defaultTransform = snapshot - .transform(snapshot.replaceWindowsLineEndings, snapshot.replaceWindowsPaths, - normalize, snapshot.replaceNodeVersion); + .transform( + snapshot.replaceWindowsLineEndings, + snapshot.transformCwd('*'), + snapshot.replaceWindowsPaths, + // Remove drive letters from synthethized paths (i.e. not cwd). + snapshot.replaceWindowsDriveLetter, + snapshot.replaceInternalStackTrace, + snapshot.replaceExperimentalWarning, + snapshot.replaceNodeVersion + ); const tests = [ { name: 'source-map/output/source_map_disabled_by_api.js' }, @@ -38,6 +29,9 @@ describe('sourcemaps output', { concurrency: !process.env.TEST_PARALLEL }, () => { name: 'source-map/output/source_map_throw_first_tick.js' }, { name: 'source-map/output/source_map_throw_icu.js' }, { name: 'source-map/output/source_map_throw_set_immediate.js' }, + { name: 'source-map/output/source_map_vm_function.js' }, + { name: 'source-map/output/source_map_vm_module.js' }, + { name: 'source-map/output/source_map_vm_script.js' }, ]; for (const { name, transform } of tests) { it(name, async () => { diff --git a/test/parallel/test-runner-output.mjs b/test/parallel/test-runner-output.mjs index abc3d7c97b4879..1d371264e64deb 100644 --- a/test/parallel/test-runner-output.mjs +++ b/test/parallel/test-runner-output.mjs @@ -61,7 +61,7 @@ const defaultTransform = snapshot.transform( snapshot.replaceWindowsLineEndings, snapshot.replaceStackTrace, removeWindowsPathEscaping, - snapshot.replaceFullPaths, + snapshot.transformCwd(), snapshot.replaceWindowsPaths, replaceTestDuration, replaceTestLocationLine, @@ -79,7 +79,7 @@ const junitTransform = snapshot.transform( const lcovTransform = snapshot.transform( snapshot.replaceWindowsLineEndings, snapshot.replaceStackTrace, - snapshot.replaceFullPaths, + snapshot.transformCwd(), snapshot.replaceWindowsPaths, pickTestFileFromLcov );