Skip to content

Commit 50e4017

Browse files
committed
Merge remote-tracking branch 'origin/master' into uninstall
2 parents 33161bb + c98a759 commit 50e4017

File tree

2 files changed

+159
-69
lines changed

2 files changed

+159
-69
lines changed

source-map-support.js

Lines changed: 116 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -23,39 +23,87 @@ function dynamicRequire(mod, request) {
2323
return mod.require(request);
2424
}
2525

26-
// Only install once if called multiple times
27-
// Remember how the environment looked before installation so we can restore if able
28-
/** @type {HookState} */
29-
var errorPrepareStackTraceHook;
30-
/** @type {HookState} */
31-
var processEmitHook;
3226
/**
3327
* @typedef {{
3428
* enabled: boolean;
3529
* originalValue: any;
3630
* installedValue: any;
3731
* }} HookState
32+
* Used for installing and uninstalling hooks
3833
*/
3934

40-
// If true, the caches are reset before a stack trace formatting operation
41-
var emptyCacheBetweenOperations = false;
35+
// Increment this if the format of sharedData changes in a breaking way.
36+
var sharedDataVersion = 1;
4237

43-
// Supports {browser, node, auto}
44-
var environment = "auto";
38+
function initializeSharedData(defaults) {
39+
var sharedDataKey = 'source-map-support/sharedData';
40+
if (typeof Symbol !== 'undefined') {
41+
sharedDataKey = Symbol.for(sharedDataKey);
42+
}
43+
var sharedData = this[sharedDataKey];
44+
if (!sharedData) {
45+
sharedData = { version: sharedDataVersion };
46+
if (Object.defineProperty) {
47+
Object.defineProperty(this, sharedDataKey, { value: sharedData });
48+
} else {
49+
this[sharedDataKey] = sharedData;
50+
}
51+
}
52+
if (sharedDataVersion !== sharedData.version) {
53+
throw new Error("Multiple incompatible instances of source-map-support were loaded");
54+
}
55+
for (var key in defaults) {
56+
if (!(key in sharedData)) {
57+
sharedData[key] = defaults[key];
58+
}
59+
}
60+
return sharedData;
61+
}
4562

46-
// Maps a file path to a string containing the file contents
47-
var fileContentsCache = {};
63+
// If multiple instances of source-map-support are loaded into the same
64+
// context, they shouldn't overwrite each other. By storing handlers, caches,
65+
// and other state on a shared object, different instances of
66+
// source-map-support can work together in a limited way. This does require
67+
// that future versions of source-map-support continue to support the fields on
68+
// this object. If this internal contract ever needs to be broken, increment
69+
// sharedDataVersion. (This version number is not the same as any of the
70+
// package's version numbers, which should reflect the *external* API of
71+
// source-map-support.)
72+
var sharedData = initializeSharedData({
73+
74+
// Only install once if called multiple times
75+
// Remember how the environment looked before installation so we can restore if able
76+
/** @type {HookState} */
77+
errorPrepareStackTraceHook: undefined,
78+
/** @type {HookState} */
79+
processEmitHook: undefined,
80+
81+
// If true, the caches are reset before a stack trace formatting operation
82+
emptyCacheBetweenOperations: false,
83+
84+
// Maps a file path to a string containing the file contents
85+
fileContentsCache: {},
86+
87+
// Maps a file path to a source map for that file
88+
sourceMapCache: {},
89+
90+
// Priority list of retrieve handlers
91+
retrieveFileHandlers: [],
92+
retrieveMapHandlers: [],
93+
94+
// Priority list of internally-implemented handlers.
95+
// When resetting state, we must keep these.
96+
internalRetrieveFileHandlers: [],
97+
internalRetrieveMapHandlers: [],
4898

49-
// Maps a file path to a source map for that file
50-
var sourceMapCache = {};
99+
});
100+
101+
// Supports {browser, node, auto}
102+
var environment = "auto";
51103

52104
// Regex for detecting source maps
53105
var reSourceMap = /^data:application\/json[^,]+base64,/;
54106

55-
// Priority list of retrieve handlers
56-
var retrieveFileHandlers = [];
57-
var retrieveMapHandlers = [];
58-
59107
function isInBrowser() {
60108
if (environment === "browser")
61109
return true;
@@ -68,21 +116,27 @@ function hasGlobalProcessEventEmitter() {
68116
return ((typeof process === 'object') && (process !== null) && (typeof process.on === 'function'));
69117
}
70118

71-
function handlerExec(list) {
119+
function handlerExec(list, internalList) {
72120
return function(arg) {
73121
for (var i = 0; i < list.length; i++) {
74122
var ret = list[i](arg);
75123
if (ret) {
76124
return ret;
77125
}
78126
}
127+
for (var i = 0; i < internalList.length; i++) {
128+
var ret = internalList[i](arg);
129+
if (ret) {
130+
return ret;
131+
}
132+
}
79133
return null;
80134
};
81135
}
82136

83-
var retrieveFile = handlerExec(retrieveFileHandlers);
137+
var retrieveFile = handlerExec(sharedData.retrieveFileHandlers, sharedData.internalRetrieveFileHandlers);
84138

85-
retrieveFileHandlers.push(function(path) {
139+
sharedData.internalRetrieveFileHandlers.push(function(path) {
86140
// Trim the path to make sure there is no extra whitespace.
87141
path = path.trim();
88142
if (/^file:/.test(path)) {
@@ -93,8 +147,8 @@ retrieveFileHandlers.push(function(path) {
93147
'/'; // file:///root-dir/file -> /root-dir/file
94148
});
95149
}
96-
if (path in fileContentsCache) {
97-
return fileContentsCache[path];
150+
if (path in sharedData.fileContentsCache) {
151+
return sharedData.fileContentsCache[path];
98152
}
99153

100154
var contents = '';
@@ -115,7 +169,7 @@ retrieveFileHandlers.push(function(path) {
115169
/* ignore any errors */
116170
}
117171

118-
return fileContentsCache[path] = contents;
172+
return sharedData.fileContentsCache[path] = contents;
119173
});
120174

121175
// Support URLs relative to a directory, but be careful about a protocol prefix
@@ -170,8 +224,8 @@ function retrieveSourceMapURL(source) {
170224
// there is no source map. The map field may be either a string or the parsed
171225
// JSON object (ie, it must be a valid argument to the SourceMapConsumer
172226
// constructor).
173-
var retrieveSourceMap = handlerExec(retrieveMapHandlers);
174-
retrieveMapHandlers.push(function(source) {
227+
var retrieveSourceMap = handlerExec(sharedData.retrieveMapHandlers, sharedData.internalRetrieveMapHandlers);
228+
sharedData.internalRetrieveMapHandlers.push(function(source) {
175229
var sourceMappingURL = retrieveSourceMapURL(source);
176230
if (!sourceMappingURL) return null;
177231

@@ -199,12 +253,12 @@ retrieveMapHandlers.push(function(source) {
199253
});
200254

201255
function mapSourcePosition(position) {
202-
var sourceMap = sourceMapCache[position.source];
256+
var sourceMap = sharedData.sourceMapCache[position.source];
203257
if (!sourceMap) {
204258
// Call the (overrideable) retrieveSourceMap function to get the source map.
205259
var urlAndMap = retrieveSourceMap(position.source);
206260
if (urlAndMap) {
207-
sourceMap = sourceMapCache[position.source] = {
261+
sourceMap = sharedData.sourceMapCache[position.source] = {
208262
url: urlAndMap.url,
209263
map: new SourceMapConsumer(urlAndMap.map)
210264
};
@@ -216,12 +270,12 @@ function mapSourcePosition(position) {
216270
var contents = sourceMap.map.sourcesContent[i];
217271
if (contents) {
218272
var url = supportRelativeURL(sourceMap.url, source);
219-
fileContentsCache[url] = contents;
273+
sharedData.fileContentsCache[url] = contents;
220274
}
221275
});
222276
}
223277
} else {
224-
sourceMap = sourceMapCache[position.source] = {
278+
sourceMap = sharedData.sourceMapCache[position.source] = {
225279
url: null,
226280
map: null
227281
};
@@ -450,9 +504,9 @@ function createPrepareStackTrace(hookState) {
450504
function prepareStackTrace(error, stack) {
451505
if(!hookState.enabled) return hookState.originalValue.apply(this, arguments);
452506

453-
if (emptyCacheBetweenOperations) {
454-
fileContentsCache = {};
455-
sourceMapCache = {};
507+
if (sharedData.emptyCacheBetweenOperations) {
508+
sharedData.fileContentsCache = {};
509+
sharedData.sourceMapCache = {};
456510
}
457511

458512
// node gives its own errors special treatment. Mimic that behavior
@@ -491,7 +545,7 @@ function getErrorSource(error) {
491545
var column = +match[3];
492546

493547
// Support the inline sourceContents inside the source map
494-
var contents = fileContentsCache[source];
548+
var contents = sharedData.fileContentsCache[source];
495549

496550
// Support files on disk
497551
if (!contents && fs && fs.existsSync(source)) {
@@ -537,15 +591,15 @@ function printFatalErrorUponExit (error) {
537591

538592
function shimEmitUncaughtException () {
539593
const originalValue = process.emit;
540-
var hook = processEmitHook = {
594+
var hook = sharedData.processEmitHook = {
541595
enabled: true,
542596
originalValue,
543597
installedValue: undefined
544598
};
545599
var isTerminatingDueToFatalException = false;
546600
var fatalException;
547601

548-
process.emit = processEmitHook.installedValue = function (type) {
602+
process.emit = sharedData.processEmitHook.installedValue = function (type) {
549603
const hadListeners = originalValue.apply(this, arguments);
550604
if(hook.enabled) {
551605
if (type === 'uncaughtException' && !hadListeners) {
@@ -561,8 +615,8 @@ function shimEmitUncaughtException () {
561615
};
562616
}
563617

564-
var originalRetrieveFileHandlers = retrieveFileHandlers.slice(0);
565-
var originalRetrieveMapHandlers = retrieveMapHandlers.slice(0);
618+
var originalRetrieveFileHandlers = sharedData.retrieveFileHandlers.slice(0);
619+
var originalRetrieveMapHandlers = sharedData.retrieveMapHandlers.slice(0);
566620

567621
exports.wrapCallSite = wrapCallSite;
568622
exports.getErrorSource = getErrorSource;
@@ -583,20 +637,20 @@ exports.install = function(options) {
583637
// directly from disk.
584638
if (options.retrieveFile) {
585639
if (options.overrideRetrieveFile) {
586-
retrieveFileHandlers.length = 0;
640+
sharedData.retrieveFileHandlers.length = 0;
587641
}
588642

589-
retrieveFileHandlers.unshift(options.retrieveFile);
643+
sharedData.retrieveFileHandlers.unshift(options.retrieveFile);
590644
}
591645

592646
// Allow source maps to be found by methods other than reading the files
593647
// directly from disk.
594648
if (options.retrieveSourceMap) {
595649
if (options.overrideRetrieveSourceMap) {
596-
retrieveMapHandlers.length = 0;
650+
sharedData.retrieveMapHandlers.length = 0;
597651
}
598652

599-
retrieveMapHandlers.unshift(options.retrieveSourceMap);
653+
sharedData.retrieveMapHandlers.unshift(options.retrieveSourceMap);
600654
}
601655

602656
// Support runtime transpilers that include inline source maps
@@ -607,8 +661,8 @@ exports.install = function(options) {
607661

608662
if (!$compile.__sourceMapSupport) {
609663
Module.prototype._compile = function(content, filename) {
610-
fileContentsCache[filename] = content;
611-
sourceMapCache[filename] = undefined;
664+
sharedData.fileContentsCache[filename] = content;
665+
sharedData.sourceMapCache[filename] = undefined;
612666
return $compile.call(this, content, filename);
613667
};
614668

@@ -617,24 +671,24 @@ exports.install = function(options) {
617671
}
618672

619673
// Configure options
620-
if (!emptyCacheBetweenOperations) {
621-
emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
674+
if (!sharedData.emptyCacheBetweenOperations) {
675+
sharedData.emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
622676
options.emptyCacheBetweenOperations : false;
623677
}
624678

625679

626680
// Install the error reformatter
627-
if (!errorPrepareStackTraceHook) {
681+
if (!sharedData.errorPrepareStackTraceHook) {
628682
const originalValue = Error.prepareStackTrace;
629-
errorPrepareStackTraceHook = {
683+
sharedData.errorPrepareStackTraceHook = {
630684
enabled: true,
631685
originalValue,
632686
installedValue: undefined
633687
};
634-
Error.prepareStackTrace = errorPrepareStackTraceHook.installedValue = createPrepareStackTrace(errorPrepareStackTraceHook);
688+
Error.prepareStackTrace = sharedData.errorPrepareStackTraceHook.installedValue = createPrepareStackTrace(sharedData.errorPrepareStackTraceHook);
635689
}
636690

637-
if (!processEmitHook) {
691+
if (!sharedData.processEmitHook) {
638692
var installHandler = 'handleUncaughtExceptions' in options ?
639693
options.handleUncaughtExceptions : true;
640694

@@ -663,36 +717,30 @@ exports.install = function(options) {
663717
};
664718

665719
exports.uninstall = function() {
666-
if(processEmitHook) {
720+
if(sharedData.processEmitHook) {
667721
// Disable behavior
668-
processEmitHook.enabled = false;
722+
sharedData.processEmitHook.enabled = false;
669723
// If possible, remove our hook function. May not be possible if subsequent third-party hooks have wrapped around us.
670-
if(process.emit === processEmitHook.installedValue) {
671-
process.emit = processEmitHook.originalValue;
724+
if(process.emit === sharedData.processEmitHook.installedValue) {
725+
process.emit = sharedData.processEmitHook.originalValue;
672726
}
673-
processEmitHook = undefined;
727+
sharedData.processEmitHook = undefined;
674728
}
675-
if(errorPrepareStackTraceHook) {
729+
if(sharedData.errorPrepareStackTraceHook) {
676730
// Disable behavior
677-
errorPrepareStackTraceHook.enabled = false;
731+
sharedData.errorPrepareStackTraceHook.enabled = false;
678732
// If possible or necessary, remove our hook function.
679733
// In vanilla environments, prepareStackTrace is `undefined`.
680734
// We cannot delegate to `undefined` the way we can to a function w/`.apply()`; our only option is to remove the function.
681735
// If we are the *first* hook installed, and another was installed on top of us, we have no choice but to remove both.
682-
if(Error.prepareStackTrace === errorPrepareStackTraceHook.installedValue || typeof errorPrepareStackTraceHook.originalValue !== 'function') {
683-
Error.prepareStackTrace = errorPrepareStackTraceHook.originalValue;
736+
if(Error.prepareStackTrace === sharedData.errorPrepareStackTraceHook.installedValue || typeof sharedData.errorPrepareStackTraceHook.originalValue !== 'function') {
737+
Error.prepareStackTrace = sharedData.errorPrepareStackTraceHook.originalValue;
684738
}
685-
errorPrepareStackTraceHook = undefined;
739+
sharedData.errorPrepareStackTraceHook = undefined;
686740
}
687741
}
688742

689743
exports.resetRetrieveHandlers = function() {
690-
retrieveFileHandlers.length = 0;
691-
retrieveMapHandlers.length = 0;
692-
693-
retrieveFileHandlers = originalRetrieveFileHandlers.slice(0);
694-
retrieveMapHandlers = originalRetrieveMapHandlers.slice(0);
695-
696-
retrieveSourceMap = handlerExec(retrieveMapHandlers);
697-
retrieveFile = handlerExec(retrieveFileHandlers);
744+
sharedData.retrieveFileHandlers.length = 0;
745+
sharedData.retrieveMapHandlers.length = 0;
698746
}

0 commit comments

Comments
 (0)