Ver Fonte

Remove regex replacements from import-typescript

Jake Bailey há 2 anos atrás
pai
commit
416b686d69

+ 10 - 63
build/importTypescript.ts

@@ -37,69 +37,16 @@ export const typescriptVersion = "${typeScriptDependencyVersion}";\n`
 
 	let tsServices = fs.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescript.js')).toString();
 
-	// Ensure we never run into the node system...
-	// (this also removes require calls that trick webpack into shimming those modules...)
-	tsServices = tsServices.replace(
-		/\n    ts\.sys =([^]*)\n    \}\)\(\);/m,
-		`\n    // MONACOCHANGE\n    ts.sys = undefined;\n    // END MONACOCHANGE`
-	);
-
-	// Eliminate more require() calls...
-	tsServices = tsServices.replace(
-		/^( +)etwModule = require\(.*$/m,
-		'$1// MONACOCHANGE\n$1etwModule = undefined;\n$1// END MONACOCHANGE'
-	);
-	tsServices = tsServices.replace(
-		/^( +)var result = ts\.sys\.require\(.*$/m,
-		'$1// MONACOCHANGE\n$1var result = undefined;\n$1// END MONACOCHANGE'
-	);
-	tsServices = tsServices.replace(
-		/^( +)fs = require\("fs"\);$/m,
-		'$1// MONACOCHANGE\n$1fs = undefined;\n$1// END MONACOCHANGE'
-	);
-	tsServices = tsServices.replace(
-		/^( +)debugger;$/m,
-		'$1// MONACOCHANGE\n$1// debugger;\n$1// END MONACOCHANGE'
-	);
-	tsServices = tsServices.replace(
-		/= require\("perf_hooks"\)/m,
-		'/* MONACOCHANGE */= {}/* END MONACOCHANGE */'
-	);
-	tsServices = tsServices.replace(
-		/typeof require === "function"/m,
-		'/* MONACOCHANGE */false/* END MONACOCHANGE */'
-	);
-
-	tsServices = tsServices.replace(
-		/module.exports = ts;/m,
-		'/* MONACOCHANGE */ /*module.exports = ts;*/ /* END MONACOCHANGE */'
-	);
-
-	// Flag any new require calls (outside comments) so they can be corrected preemptively.
-	// To avoid missing cases (or using an even more complex regex), temporarily remove comments
-	// about require() and then check for lines actually calling require().
-	// \/[*/] matches the start of a comment (single or multi-line).
-	// ^\s+\*[^/] matches (presumably) a later line of a multi-line comment.
-	const tsServicesNoCommentedRequire = tsServices.replace(
-		/(\/[*/]|^\s+\*[^/]).*\brequire\(.*/gm,
-		''
-	);
-	const linesWithRequire = tsServicesNoCommentedRequire.match(/^.*?\brequire\(.*$/gm);
-
-	// Allow error messages to include references to require() in their strings
-	const runtimeRequires =
-		linesWithRequire &&
-		linesWithRequire.filter((l) => !l.includes(': diag(') && !l.includes('ts.DiagnosticCategory'));
-
-	if (runtimeRequires && runtimeRequires.length && linesWithRequire) {
-		console.error(
-			'Found new require() calls on the following lines. These should be removed to avoid breaking webpack builds.\n'
-		);
-		console.error(
-			runtimeRequires.map((r) => `${r} (${tsServicesNoCommentedRequire.indexOf(r)})`).join('\n')
-		);
-		process.exit(1);
-	}
+	// The output from this build will only be accessible via AMD or ESM; rather than removing
+	// references to require/module, define them as dummy variables that bundlers will ignore.
+	// The TS code can figure out that it's not running under Node even with these defined.
+	tsServices =
+		`
+/* MONACOCHANGE */
+var require = undefined;
+var module = { exports: {} };
+/* END MONACOCHANGE */
+` + tsServices;
 
 	const tsServices_amd =
 		generatedNote +

+ 2 - 1
build/tsconfig.json

@@ -1,7 +1,8 @@
 {
 	"compilerOptions": {
 		"noEmit": true,
+		"module": "CommonJS",
 		"esModuleInterop": true
 	},
-	"files": ["./**/*"]
+	"include": ["./**/*"]
 }

+ 2 - 0
build/utils.ts

@@ -104,6 +104,7 @@ export function buildESM(options: { base: string; entryPoints: string[]; externa
 		bundle: true,
 		target: 'esnext',
 		format: 'esm',
+		drop: ['debugger'],
 		define: {
 			AMD: 'false'
 		},
@@ -141,6 +142,7 @@ function buildOneAMD(
 		bundle: true,
 		target: 'esnext',
 		format: 'iife',
+		drop: ['debugger'],
 		define: {
 			AMD: 'true'
 		},

+ 602 - 18
src/language/typescript/lib/typescriptServices-amd.js

@@ -1,6 +1,11 @@
 //
 // **NOTE**: Do not edit directly! This file is generated using `npm run import-typescript`
 //
+
+/* MONACOCHANGE */
+var require = undefined;
+var module = { exports: {} };
+/* END MONACOCHANGE */
 /*! *****************************************************************************
 Copyright (c) Microsoft Corporation. All rights reserved.
 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
@@ -2554,9 +2559,7 @@ var ts;
             return true;
         }
         function fail(message, stackCrawlMark) {
-            // MONACOCHANGE
-            // debugger;
-            // END MONACOCHANGE
+            debugger;
             var e = new Error(message ? "Debug Failure. ".concat(message) : "Debug Failure.");
             if (Error.captureStackTrace) {
                 Error.captureStackTrace(e, stackCrawlMark || fail);
@@ -3058,9 +3061,7 @@ var ts;
             try {
                 if (ts.sys && ts.sys.require) {
                     var basePath = ts.getDirectoryPath(ts.resolvePath(ts.sys.getExecutingFilePath()));
-                    // MONACOCHANGE
-                    var result = undefined;
-                    // END MONACOCHANGE
+                    var result = ts.sys.require(basePath, "./compiler-debug");
                     if (!result.error) {
                         result.module.init(ts);
                         extendedDebugModule = result.module;
@@ -3512,10 +3513,10 @@ var ts;
         }
     }
     function tryGetNodePerformanceHooks() {
-        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof module === "object" && /* MONACOCHANGE */false/* END MONACOCHANGE */) {
+        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof module === "object" && typeof require === "function") {
             try {
                 var performance_1;
-                var _a /* MONACOCHANGE */= {}/* END MONACOCHANGE */, nodePerformance_1 = _a.performance, PerformanceObserver_1 = _a.PerformanceObserver;
+                var _a = require("perf_hooks"), nodePerformance_1 = _a.performance, PerformanceObserver_1 = _a.PerformanceObserver;
                 if (hasRequiredAPI(nodePerformance_1, PerformanceObserver_1)) {
                     performance_1 = nodePerformance_1;
                     // There is a bug in Node's performance.measure prior to 12.16.3/13.13.0 that does not
@@ -3746,9 +3747,7 @@ var ts;
         var etwModulePath = (_a = process.env.TS_ETW_MODULE_PATH) !== null && _a !== void 0 ? _a : "./node_modules/@microsoft/typescript-etw";
         // require() will throw an exception if the module is not found
         // It may also return undefined if not installed properly
-        // MONACOCHANGE
-        etwModule = undefined;
-        // END MONACOCHANGE
+        etwModule = require(etwModulePath);
     }
     catch (e) {
         etwModule = undefined;
@@ -3777,9 +3776,7 @@ var ts;
             ts.Debug.assert(!ts.tracing, "Tracing already started");
             if (fs === undefined) {
                 try {
-                    // MONACOCHANGE
-                    fs = undefined;
-                    // END MONACOCHANGE
+                    fs = require("fs");
                 }
                 catch (e) {
                     throw new Error("tracing requires having fs\n(original error: ".concat(e.message || e, ")"));
@@ -7463,9 +7460,596 @@ var ts;
     ts.getNodeMajorVersion = getNodeMajorVersion;
     // TODO: GH#18217 this is used as if it's certainly defined in many places.
     // eslint-disable-next-line prefer-const
-    // MONACOCHANGE
-    ts.sys = undefined;
-    // END MONACOCHANGE
+    ts.sys = (function () {
+        // NodeJS detects "\uFEFF" at the start of the string and *replaces* it with the actual
+        // byte order mark from the specified encoding. Using any other byte order mark does
+        // not actually work.
+        var byteOrderMarkIndicator = "\uFEFF";
+        function getNodeSystem() {
+            var _a;
+            var nativePattern = /^native |^\([^)]+\)$|^(internal[\\/]|[a-zA-Z0-9_\s]+(\.js)?$)/;
+            var _fs = require("fs");
+            var _path = require("path");
+            var _os = require("os");
+            // crypto can be absent on reduced node installations
+            var _crypto;
+            try {
+                _crypto = require("crypto");
+            }
+            catch (_b) {
+                _crypto = undefined;
+            }
+            var activeSession;
+            var profilePath = "./profile.cpuprofile";
+            var hitSystemWatcherLimit = false;
+            var Buffer = require("buffer").Buffer;
+            var nodeVersion = getNodeMajorVersion();
+            var isNode4OrLater = nodeVersion >= 4;
+            var isLinuxOrMacOs = process.platform === "linux" || process.platform === "darwin";
+            var platform = _os.platform();
+            var useCaseSensitiveFileNames = isFileSystemCaseSensitive();
+            var realpathSync = (_a = _fs.realpathSync.native) !== null && _a !== void 0 ? _a : _fs.realpathSync;
+            var fsSupportsRecursiveFsWatch = isNode4OrLater && (process.platform === "win32" || process.platform === "darwin");
+            var getCurrentDirectory = ts.memoize(function () { return process.cwd(); });
+            var _c = createSystemWatchFunctions({
+                pollingWatchFile: createSingleFileWatcherPerName(fsWatchFileWorker, useCaseSensitiveFileNames),
+                getModifiedTime: getModifiedTime,
+                setTimeout: setTimeout,
+                clearTimeout: clearTimeout,
+                fsWatch: fsWatch,
+                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
+                getCurrentDirectory: getCurrentDirectory,
+                fileExists: fileExists,
+                // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
+                // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
+                fsSupportsRecursiveFsWatch: fsSupportsRecursiveFsWatch,
+                directoryExists: directoryExists,
+                getAccessibleSortedChildDirectories: function (path) { return getAccessibleFileSystemEntries(path).directories; },
+                realpath: realpath,
+                tscWatchFile: process.env.TSC_WATCHFILE,
+                useNonPollingWatchers: process.env.TSC_NONPOLLING_WATCHER,
+                tscWatchDirectory: process.env.TSC_WATCHDIRECTORY,
+                defaultWatchFileKind: function () { var _a, _b; return (_b = (_a = sys).defaultWatchFileKind) === null || _b === void 0 ? void 0 : _b.call(_a); },
+            }), watchFile = _c.watchFile, watchDirectory = _c.watchDirectory;
+            var nodeSystem = {
+                args: process.argv.slice(2),
+                newLine: _os.EOL,
+                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
+                write: function (s) {
+                    process.stdout.write(s);
+                },
+                getWidthOfTerminal: function () {
+                    return process.stdout.columns;
+                },
+                writeOutputIsTTY: function () {
+                    return process.stdout.isTTY;
+                },
+                readFile: readFile,
+                writeFile: writeFile,
+                watchFile: watchFile,
+                watchDirectory: watchDirectory,
+                resolvePath: function (path) { return _path.resolve(path); },
+                fileExists: fileExists,
+                directoryExists: directoryExists,
+                createDirectory: function (directoryName) {
+                    if (!nodeSystem.directoryExists(directoryName)) {
+                        // Wrapped in a try-catch to prevent crashing if we are in a race
+                        // with another copy of ourselves to create the same directory
+                        try {
+                            _fs.mkdirSync(directoryName);
+                        }
+                        catch (e) {
+                            if (e.code !== "EEXIST") {
+                                // Failed for some other reason (access denied?); still throw
+                                throw e;
+                            }
+                        }
+                    }
+                },
+                getExecutingFilePath: function () {
+                    return __filename;
+                },
+                getCurrentDirectory: getCurrentDirectory,
+                getDirectories: getDirectories,
+                getEnvironmentVariable: function (name) {
+                    return process.env[name] || "";
+                },
+                readDirectory: readDirectory,
+                getModifiedTime: getModifiedTime,
+                setModifiedTime: setModifiedTime,
+                deleteFile: deleteFile,
+                createHash: _crypto ? createSHA256Hash : generateDjb2Hash,
+                createSHA256Hash: _crypto ? createSHA256Hash : undefined,
+                getMemoryUsage: function () {
+                    if (global.gc) {
+                        global.gc();
+                    }
+                    return process.memoryUsage().heapUsed;
+                },
+                getFileSize: function (path) {
+                    try {
+                        var stat = statSync(path);
+                        if (stat === null || stat === void 0 ? void 0 : stat.isFile()) {
+                            return stat.size;
+                        }
+                    }
+                    catch ( /*ignore*/_a) { /*ignore*/ }
+                    return 0;
+                },
+                exit: function (exitCode) {
+                    disableCPUProfiler(function () { return process.exit(exitCode); });
+                },
+                enableCPUProfiler: enableCPUProfiler,
+                disableCPUProfiler: disableCPUProfiler,
+                cpuProfilingEnabled: function () { return !!activeSession || ts.contains(process.execArgv, "--cpu-prof") || ts.contains(process.execArgv, "--prof"); },
+                realpath: realpath,
+                debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || ts.some(process.execArgv, function (arg) { return /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg); }),
+                tryEnableSourceMapsForHost: function () {
+                    try {
+                        require("source-map-support").install();
+                    }
+                    catch (_a) {
+                        // Could not enable source maps.
+                    }
+                },
+                setTimeout: setTimeout,
+                clearTimeout: clearTimeout,
+                clearScreen: function () {
+                    process.stdout.write("\x1Bc");
+                },
+                setBlocking: function () {
+                    if (process.stdout && process.stdout._handle && process.stdout._handle.setBlocking) {
+                        process.stdout._handle.setBlocking(true);
+                    }
+                },
+                bufferFrom: bufferFrom,
+                base64decode: function (input) { return bufferFrom(input, "base64").toString("utf8"); },
+                base64encode: function (input) { return bufferFrom(input).toString("base64"); },
+                require: function (baseDir, moduleName) {
+                    try {
+                        var modulePath = ts.resolveJSModule(moduleName, baseDir, nodeSystem);
+                        return { module: require(modulePath), modulePath: modulePath, error: undefined };
+                    }
+                    catch (error) {
+                        return { module: undefined, modulePath: undefined, error: error };
+                    }
+                }
+            };
+            return nodeSystem;
+            /**
+             * `throwIfNoEntry` was added so recently that it's not in the node types.
+             * This helper encapsulates the mitigating usage of `any`.
+             * See https://github.com/nodejs/node/pull/33716
+             */
+            function statSync(path) {
+                // throwIfNoEntry will be ignored by older versions of node
+                return _fs.statSync(path, { throwIfNoEntry: false });
+            }
+            /**
+             * Uses the builtin inspector APIs to capture a CPU profile
+             * See https://nodejs.org/api/inspector.html#inspector_example_usage for details
+             */
+            function enableCPUProfiler(path, cb) {
+                if (activeSession) {
+                    cb();
+                    return false;
+                }
+                var inspector = require("inspector");
+                if (!inspector || !inspector.Session) {
+                    cb();
+                    return false;
+                }
+                var session = new inspector.Session();
+                session.connect();
+                session.post("Profiler.enable", function () {
+                    session.post("Profiler.start", function () {
+                        activeSession = session;
+                        profilePath = path;
+                        cb();
+                    });
+                });
+                return true;
+            }
+            /**
+             * Strips non-TS paths from the profile, so users with private projects shouldn't
+             * need to worry about leaking paths by submitting a cpu profile to us
+             */
+            function cleanupPaths(profile) {
+                var externalFileCounter = 0;
+                var remappedPaths = new ts.Map();
+                var normalizedDir = ts.normalizeSlashes(__dirname);
+                // Windows rooted dir names need an extra `/` prepended to be valid file:/// urls
+                var fileUrlRoot = "file://".concat(ts.getRootLength(normalizedDir) === 1 ? "" : "/").concat(normalizedDir);
+                for (var _i = 0, _a = profile.nodes; _i < _a.length; _i++) {
+                    var node = _a[_i];
+                    if (node.callFrame.url) {
+                        var url = ts.normalizeSlashes(node.callFrame.url);
+                        if (ts.containsPath(fileUrlRoot, url, useCaseSensitiveFileNames)) {
+                            node.callFrame.url = ts.getRelativePathToDirectoryOrUrl(fileUrlRoot, url, fileUrlRoot, ts.createGetCanonicalFileName(useCaseSensitiveFileNames), /*isAbsolutePathAnUrl*/ true);
+                        }
+                        else if (!nativePattern.test(url)) {
+                            node.callFrame.url = (remappedPaths.has(url) ? remappedPaths : remappedPaths.set(url, "external".concat(externalFileCounter, ".js"))).get(url);
+                            externalFileCounter++;
+                        }
+                    }
+                }
+                return profile;
+            }
+            function disableCPUProfiler(cb) {
+                if (activeSession && activeSession !== "stopping") {
+                    var s_1 = activeSession;
+                    activeSession.post("Profiler.stop", function (err, _a) {
+                        var _b;
+                        var profile = _a.profile;
+                        if (!err) {
+                            try {
+                                if ((_b = statSync(profilePath)) === null || _b === void 0 ? void 0 : _b.isDirectory()) {
+                                    profilePath = _path.join(profilePath, "".concat((new Date()).toISOString().replace(/:/g, "-"), "+P").concat(process.pid, ".cpuprofile"));
+                                }
+                            }
+                            catch (_c) {
+                                // do nothing and ignore fallible fs operation
+                            }
+                            try {
+                                _fs.mkdirSync(_path.dirname(profilePath), { recursive: true });
+                            }
+                            catch (_d) {
+                                // do nothing and ignore fallible fs operation
+                            }
+                            _fs.writeFileSync(profilePath, JSON.stringify(cleanupPaths(profile)));
+                        }
+                        activeSession = undefined;
+                        s_1.disconnect();
+                        cb();
+                    });
+                    activeSession = "stopping";
+                    return true;
+                }
+                else {
+                    cb();
+                    return false;
+                }
+            }
+            function bufferFrom(input, encoding) {
+                // See https://github.com/Microsoft/TypeScript/issues/25652
+                return Buffer.from && Buffer.from !== Int8Array.from
+                    ? Buffer.from(input, encoding)
+                    : new Buffer(input, encoding);
+            }
+            function isFileSystemCaseSensitive() {
+                // win32\win64 are case insensitive platforms
+                if (platform === "win32" || platform === "win64") {
+                    return false;
+                }
+                // If this file exists under a different case, we must be case-insensitve.
+                return !fileExists(swapCase(__filename));
+            }
+            /** Convert all lowercase chars to uppercase, and vice-versa */
+            function swapCase(s) {
+                return s.replace(/\w/g, function (ch) {
+                    var up = ch.toUpperCase();
+                    return ch === up ? ch.toLowerCase() : up;
+                });
+            }
+            function fsWatchFileWorker(fileName, callback, pollingInterval) {
+                _fs.watchFile(fileName, { persistent: true, interval: pollingInterval }, fileChanged);
+                var eventKind;
+                return {
+                    close: function () { return _fs.unwatchFile(fileName, fileChanged); }
+                };
+                function fileChanged(curr, prev) {
+                    // previous event kind check is to ensure we recongnize the file as previously also missing when it is restored or renamed twice (that is it disappears and reappears)
+                    // In such case, prevTime returned is same as prev time of event when file was deleted as per node documentation
+                    var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted;
+                    if (+curr.mtime === 0) {
+                        if (isPreviouslyDeleted) {
+                            // Already deleted file, no need to callback again
+                            return;
+                        }
+                        eventKind = FileWatcherEventKind.Deleted;
+                    }
+                    else if (isPreviouslyDeleted) {
+                        eventKind = FileWatcherEventKind.Created;
+                    }
+                    // If there is no change in modified time, ignore the event
+                    else if (+curr.mtime === +prev.mtime) {
+                        return;
+                    }
+                    else {
+                        // File changed
+                        eventKind = FileWatcherEventKind.Changed;
+                    }
+                    callback(fileName, eventKind);
+                }
+            }
+            function fsWatch(fileOrDirectory, entryKind, callback, recursive, fallbackPollingInterval, fallbackOptions) {
+                var options;
+                var lastDirectoryPartWithDirectorySeparator;
+                var lastDirectoryPart;
+                if (isLinuxOrMacOs) {
+                    lastDirectoryPartWithDirectorySeparator = fileOrDirectory.substr(fileOrDirectory.lastIndexOf(ts.directorySeparator));
+                    lastDirectoryPart = lastDirectoryPartWithDirectorySeparator.slice(ts.directorySeparator.length);
+                }
+                /** Watcher for the file system entry depending on whether it is missing or present */
+                var watcher = !fileSystemEntryExists(fileOrDirectory, entryKind) ?
+                    watchMissingFileSystemEntry() :
+                    watchPresentFileSystemEntry();
+                return {
+                    close: function () {
+                        // Close the watcher (either existing file system entry watcher or missing file system entry watcher)
+                        watcher.close();
+                        watcher = undefined;
+                    }
+                };
+                /**
+                 * Invoke the callback with rename and update the watcher if not closed
+                 * @param createWatcher
+                 */
+                function invokeCallbackAndUpdateWatcher(createWatcher) {
+                    ts.sysLog("sysLog:: ".concat(fileOrDirectory, ":: Changing watcher to ").concat(createWatcher === watchPresentFileSystemEntry ? "Present" : "Missing", "FileSystemEntryWatcher"));
+                    // Call the callback for current directory
+                    callback("rename", "");
+                    // If watcher is not closed, update it
+                    if (watcher) {
+                        watcher.close();
+                        watcher = createWatcher();
+                    }
+                }
+                /**
+                 * Watch the file or directory that is currently present
+                 * and when the watched file or directory is deleted, switch to missing file system entry watcher
+                 */
+                function watchPresentFileSystemEntry() {
+                    // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
+                    // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
+                    if (options === undefined) {
+                        if (fsSupportsRecursiveFsWatch) {
+                            options = { persistent: true, recursive: !!recursive };
+                        }
+                        else {
+                            options = { persistent: true };
+                        }
+                    }
+                    if (hitSystemWatcherLimit) {
+                        ts.sysLog("sysLog:: ".concat(fileOrDirectory, ":: Defaulting to fsWatchFile"));
+                        return watchPresentFileSystemEntryWithFsWatchFile();
+                    }
+                    try {
+                        var presentWatcher = _fs.watch(fileOrDirectory, options, isLinuxOrMacOs ?
+                            callbackChangingToMissingFileSystemEntry :
+                            callback);
+                        // Watch the missing file or directory or error
+                        presentWatcher.on("error", function () { return invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry); });
+                        return presentWatcher;
+                    }
+                    catch (e) {
+                        // Catch the exception and use polling instead
+                        // Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
+                        // so instead of throwing error, use fs.watchFile
+                        hitSystemWatcherLimit || (hitSystemWatcherLimit = e.code === "ENOSPC");
+                        ts.sysLog("sysLog:: ".concat(fileOrDirectory, ":: Changing to fsWatchFile"));
+                        return watchPresentFileSystemEntryWithFsWatchFile();
+                    }
+                }
+                function callbackChangingToMissingFileSystemEntry(event, relativeName) {
+                    // because relativeName is not guaranteed to be correct we need to check on each rename with few combinations
+                    // Eg on ubuntu while watching app/node_modules the relativeName is "node_modules" which is neither relative nor full path
+                    return event === "rename" &&
+                        (!relativeName ||
+                            relativeName === lastDirectoryPart ||
+                            (relativeName.lastIndexOf(lastDirectoryPartWithDirectorySeparator) !== -1 && relativeName.lastIndexOf(lastDirectoryPartWithDirectorySeparator) === relativeName.length - lastDirectoryPartWithDirectorySeparator.length)) &&
+                        !fileSystemEntryExists(fileOrDirectory, entryKind) ?
+                        invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry) :
+                        callback(event, relativeName);
+                }
+                /**
+                 * Watch the file or directory using fs.watchFile since fs.watch threw exception
+                 * Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
+                 */
+                function watchPresentFileSystemEntryWithFsWatchFile() {
+                    return watchFile(fileOrDirectory, createFileWatcherCallback(callback), fallbackPollingInterval, fallbackOptions);
+                }
+                /**
+                 * Watch the file or directory that is missing
+                 * and switch to existing file or directory when the missing filesystem entry is created
+                 */
+                function watchMissingFileSystemEntry() {
+                    return watchFile(fileOrDirectory, function (_fileName, eventKind) {
+                        if (eventKind === FileWatcherEventKind.Created && fileSystemEntryExists(fileOrDirectory, entryKind)) {
+                            // Call the callback for current file or directory
+                            // For now it could be callback for the inner directory creation,
+                            // but just return current directory, better than current no-op
+                            invokeCallbackAndUpdateWatcher(watchPresentFileSystemEntry);
+                        }
+                    }, fallbackPollingInterval, fallbackOptions);
+                }
+            }
+            function readFileWorker(fileName, _encoding) {
+                var buffer;
+                try {
+                    buffer = _fs.readFileSync(fileName);
+                }
+                catch (e) {
+                    return undefined;
+                }
+                var len = buffer.length;
+                if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
+                    // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
+                    // flip all byte pairs and treat as little endian.
+                    len &= ~1; // Round down to a multiple of 2
+                    for (var i = 0; i < len; i += 2) {
+                        var temp = buffer[i];
+                        buffer[i] = buffer[i + 1];
+                        buffer[i + 1] = temp;
+                    }
+                    return buffer.toString("utf16le", 2);
+                }
+                if (len >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) {
+                    // Little endian UTF-16 byte order mark detected
+                    return buffer.toString("utf16le", 2);
+                }
+                if (len >= 3 && buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
+                    // UTF-8 byte order mark detected
+                    return buffer.toString("utf8", 3);
+                }
+                // Default is UTF-8 with no byte order mark
+                return buffer.toString("utf8");
+            }
+            function readFile(fileName, _encoding) {
+                ts.perfLogger.logStartReadFile(fileName);
+                var file = readFileWorker(fileName, _encoding);
+                ts.perfLogger.logStopReadFile();
+                return file;
+            }
+            function writeFile(fileName, data, writeByteOrderMark) {
+                ts.perfLogger.logEvent("WriteFile: " + fileName);
+                // If a BOM is required, emit one
+                if (writeByteOrderMark) {
+                    data = byteOrderMarkIndicator + data;
+                }
+                var fd;
+                try {
+                    fd = _fs.openSync(fileName, "w");
+                    _fs.writeSync(fd, data, /*position*/ undefined, "utf8");
+                }
+                finally {
+                    if (fd !== undefined) {
+                        _fs.closeSync(fd);
+                    }
+                }
+            }
+            function getAccessibleFileSystemEntries(path) {
+                ts.perfLogger.logEvent("ReadDir: " + (path || "."));
+                try {
+                    var entries = _fs.readdirSync(path || ".", { withFileTypes: true });
+                    var files = [];
+                    var directories = [];
+                    for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
+                        var dirent = entries_1[_i];
+                        // withFileTypes is not supported before Node 10.10.
+                        var entry = typeof dirent === "string" ? dirent : dirent.name;
+                        // This is necessary because on some file system node fails to exclude
+                        // "." and "..". See https://github.com/nodejs/node/issues/4002
+                        if (entry === "." || entry === "..") {
+                            continue;
+                        }
+                        var stat = void 0;
+                        if (typeof dirent === "string" || dirent.isSymbolicLink()) {
+                            var name = ts.combinePaths(path, entry);
+                            try {
+                                stat = statSync(name);
+                                if (!stat) {
+                                    continue;
+                                }
+                            }
+                            catch (e) {
+                                continue;
+                            }
+                        }
+                        else {
+                            stat = dirent;
+                        }
+                        if (stat.isFile()) {
+                            files.push(entry);
+                        }
+                        else if (stat.isDirectory()) {
+                            directories.push(entry);
+                        }
+                    }
+                    files.sort();
+                    directories.sort();
+                    return { files: files, directories: directories };
+                }
+                catch (e) {
+                    return ts.emptyFileSystemEntries;
+                }
+            }
+            function readDirectory(path, extensions, excludes, includes, depth) {
+                return ts.matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
+            }
+            function fileSystemEntryExists(path, entryKind) {
+                // Since the error thrown by fs.statSync isn't used, we can avoid collecting a stack trace to improve
+                // the CPU time performance.
+                var originalStackTraceLimit = Error.stackTraceLimit;
+                Error.stackTraceLimit = 0;
+                try {
+                    var stat = statSync(path);
+                    if (!stat) {
+                        return false;
+                    }
+                    switch (entryKind) {
+                        case 0 /* File */: return stat.isFile();
+                        case 1 /* Directory */: return stat.isDirectory();
+                        default: return false;
+                    }
+                }
+                catch (e) {
+                    return false;
+                }
+                finally {
+                    Error.stackTraceLimit = originalStackTraceLimit;
+                }
+            }
+            function fileExists(path) {
+                return fileSystemEntryExists(path, 0 /* File */);
+            }
+            function directoryExists(path) {
+                return fileSystemEntryExists(path, 1 /* Directory */);
+            }
+            function getDirectories(path) {
+                return getAccessibleFileSystemEntries(path).directories.slice();
+            }
+            function realpath(path) {
+                try {
+                    return realpathSync(path);
+                }
+                catch (_a) {
+                    return path;
+                }
+            }
+            function getModifiedTime(path) {
+                var _a;
+                try {
+                    return (_a = statSync(path)) === null || _a === void 0 ? void 0 : _a.mtime;
+                }
+                catch (e) {
+                    return undefined;
+                }
+            }
+            function setModifiedTime(path, time) {
+                try {
+                    _fs.utimesSync(path, time, time);
+                }
+                catch (e) {
+                    return;
+                }
+            }
+            function deleteFile(path) {
+                try {
+                    return _fs.unlinkSync(path);
+                }
+                catch (e) {
+                    return;
+                }
+            }
+            function createSHA256Hash(data) {
+                var hash = _crypto.createHash("sha256");
+                hash.update(data);
+                return hash.digest("hex");
+            }
+        }
+        var sys;
+        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") {
+            // process and process.nextTick checks if current environment is node-like
+            // process.browser check excludes webpack and browserify
+            sys = getNodeSystem();
+        }
+        if (sys) {
+            // patch writefile to create folder before writing the file
+            patchWriteFileEnsuringDirectory(sys);
+        }
+        return sys;
+    })();
     /*@internal*/
     function setSys(s) {
         ts.sys = s;
@@ -162604,7 +163188,7 @@ if (typeof process === "undefined" || process.browser) {
     globalThis.toolsVersion = ts.versionMajorMinor;
 }
 if (typeof module !== "undefined" && module.exports) {
-    /* MONACOCHANGE */ /*module.exports = ts;*/ /* END MONACOCHANGE */
+    module.exports = ts;
 }
 var ts;
 (function (ts) {

+ 602 - 18
src/language/typescript/lib/typescriptServices.js

@@ -1,6 +1,11 @@
 //
 // **NOTE**: Do not edit directly! This file is generated using `npm run import-typescript`
 //
+
+/* MONACOCHANGE */
+var require = undefined;
+var module = { exports: {} };
+/* END MONACOCHANGE */
 /*! *****************************************************************************
 Copyright (c) Microsoft Corporation. All rights reserved.
 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
@@ -2554,9 +2559,7 @@ var ts;
             return true;
         }
         function fail(message, stackCrawlMark) {
-            // MONACOCHANGE
-            // debugger;
-            // END MONACOCHANGE
+            debugger;
             var e = new Error(message ? "Debug Failure. ".concat(message) : "Debug Failure.");
             if (Error.captureStackTrace) {
                 Error.captureStackTrace(e, stackCrawlMark || fail);
@@ -3058,9 +3061,7 @@ var ts;
             try {
                 if (ts.sys && ts.sys.require) {
                     var basePath = ts.getDirectoryPath(ts.resolvePath(ts.sys.getExecutingFilePath()));
-                    // MONACOCHANGE
-                    var result = undefined;
-                    // END MONACOCHANGE
+                    var result = ts.sys.require(basePath, "./compiler-debug");
                     if (!result.error) {
                         result.module.init(ts);
                         extendedDebugModule = result.module;
@@ -3512,10 +3513,10 @@ var ts;
         }
     }
     function tryGetNodePerformanceHooks() {
-        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof module === "object" && /* MONACOCHANGE */false/* END MONACOCHANGE */) {
+        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof module === "object" && typeof require === "function") {
             try {
                 var performance_1;
-                var _a /* MONACOCHANGE */= {}/* END MONACOCHANGE */, nodePerformance_1 = _a.performance, PerformanceObserver_1 = _a.PerformanceObserver;
+                var _a = require("perf_hooks"), nodePerformance_1 = _a.performance, PerformanceObserver_1 = _a.PerformanceObserver;
                 if (hasRequiredAPI(nodePerformance_1, PerformanceObserver_1)) {
                     performance_1 = nodePerformance_1;
                     // There is a bug in Node's performance.measure prior to 12.16.3/13.13.0 that does not
@@ -3746,9 +3747,7 @@ var ts;
         var etwModulePath = (_a = process.env.TS_ETW_MODULE_PATH) !== null && _a !== void 0 ? _a : "./node_modules/@microsoft/typescript-etw";
         // require() will throw an exception if the module is not found
         // It may also return undefined if not installed properly
-        // MONACOCHANGE
-        etwModule = undefined;
-        // END MONACOCHANGE
+        etwModule = require(etwModulePath);
     }
     catch (e) {
         etwModule = undefined;
@@ -3777,9 +3776,7 @@ var ts;
             ts.Debug.assert(!ts.tracing, "Tracing already started");
             if (fs === undefined) {
                 try {
-                    // MONACOCHANGE
-                    fs = undefined;
-                    // END MONACOCHANGE
+                    fs = require("fs");
                 }
                 catch (e) {
                     throw new Error("tracing requires having fs\n(original error: ".concat(e.message || e, ")"));
@@ -7463,9 +7460,596 @@ var ts;
     ts.getNodeMajorVersion = getNodeMajorVersion;
     // TODO: GH#18217 this is used as if it's certainly defined in many places.
     // eslint-disable-next-line prefer-const
-    // MONACOCHANGE
-    ts.sys = undefined;
-    // END MONACOCHANGE
+    ts.sys = (function () {
+        // NodeJS detects "\uFEFF" at the start of the string and *replaces* it with the actual
+        // byte order mark from the specified encoding. Using any other byte order mark does
+        // not actually work.
+        var byteOrderMarkIndicator = "\uFEFF";
+        function getNodeSystem() {
+            var _a;
+            var nativePattern = /^native |^\([^)]+\)$|^(internal[\\/]|[a-zA-Z0-9_\s]+(\.js)?$)/;
+            var _fs = require("fs");
+            var _path = require("path");
+            var _os = require("os");
+            // crypto can be absent on reduced node installations
+            var _crypto;
+            try {
+                _crypto = require("crypto");
+            }
+            catch (_b) {
+                _crypto = undefined;
+            }
+            var activeSession;
+            var profilePath = "./profile.cpuprofile";
+            var hitSystemWatcherLimit = false;
+            var Buffer = require("buffer").Buffer;
+            var nodeVersion = getNodeMajorVersion();
+            var isNode4OrLater = nodeVersion >= 4;
+            var isLinuxOrMacOs = process.platform === "linux" || process.platform === "darwin";
+            var platform = _os.platform();
+            var useCaseSensitiveFileNames = isFileSystemCaseSensitive();
+            var realpathSync = (_a = _fs.realpathSync.native) !== null && _a !== void 0 ? _a : _fs.realpathSync;
+            var fsSupportsRecursiveFsWatch = isNode4OrLater && (process.platform === "win32" || process.platform === "darwin");
+            var getCurrentDirectory = ts.memoize(function () { return process.cwd(); });
+            var _c = createSystemWatchFunctions({
+                pollingWatchFile: createSingleFileWatcherPerName(fsWatchFileWorker, useCaseSensitiveFileNames),
+                getModifiedTime: getModifiedTime,
+                setTimeout: setTimeout,
+                clearTimeout: clearTimeout,
+                fsWatch: fsWatch,
+                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
+                getCurrentDirectory: getCurrentDirectory,
+                fileExists: fileExists,
+                // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
+                // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
+                fsSupportsRecursiveFsWatch: fsSupportsRecursiveFsWatch,
+                directoryExists: directoryExists,
+                getAccessibleSortedChildDirectories: function (path) { return getAccessibleFileSystemEntries(path).directories; },
+                realpath: realpath,
+                tscWatchFile: process.env.TSC_WATCHFILE,
+                useNonPollingWatchers: process.env.TSC_NONPOLLING_WATCHER,
+                tscWatchDirectory: process.env.TSC_WATCHDIRECTORY,
+                defaultWatchFileKind: function () { var _a, _b; return (_b = (_a = sys).defaultWatchFileKind) === null || _b === void 0 ? void 0 : _b.call(_a); },
+            }), watchFile = _c.watchFile, watchDirectory = _c.watchDirectory;
+            var nodeSystem = {
+                args: process.argv.slice(2),
+                newLine: _os.EOL,
+                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
+                write: function (s) {
+                    process.stdout.write(s);
+                },
+                getWidthOfTerminal: function () {
+                    return process.stdout.columns;
+                },
+                writeOutputIsTTY: function () {
+                    return process.stdout.isTTY;
+                },
+                readFile: readFile,
+                writeFile: writeFile,
+                watchFile: watchFile,
+                watchDirectory: watchDirectory,
+                resolvePath: function (path) { return _path.resolve(path); },
+                fileExists: fileExists,
+                directoryExists: directoryExists,
+                createDirectory: function (directoryName) {
+                    if (!nodeSystem.directoryExists(directoryName)) {
+                        // Wrapped in a try-catch to prevent crashing if we are in a race
+                        // with another copy of ourselves to create the same directory
+                        try {
+                            _fs.mkdirSync(directoryName);
+                        }
+                        catch (e) {
+                            if (e.code !== "EEXIST") {
+                                // Failed for some other reason (access denied?); still throw
+                                throw e;
+                            }
+                        }
+                    }
+                },
+                getExecutingFilePath: function () {
+                    return __filename;
+                },
+                getCurrentDirectory: getCurrentDirectory,
+                getDirectories: getDirectories,
+                getEnvironmentVariable: function (name) {
+                    return process.env[name] || "";
+                },
+                readDirectory: readDirectory,
+                getModifiedTime: getModifiedTime,
+                setModifiedTime: setModifiedTime,
+                deleteFile: deleteFile,
+                createHash: _crypto ? createSHA256Hash : generateDjb2Hash,
+                createSHA256Hash: _crypto ? createSHA256Hash : undefined,
+                getMemoryUsage: function () {
+                    if (global.gc) {
+                        global.gc();
+                    }
+                    return process.memoryUsage().heapUsed;
+                },
+                getFileSize: function (path) {
+                    try {
+                        var stat = statSync(path);
+                        if (stat === null || stat === void 0 ? void 0 : stat.isFile()) {
+                            return stat.size;
+                        }
+                    }
+                    catch ( /*ignore*/_a) { /*ignore*/ }
+                    return 0;
+                },
+                exit: function (exitCode) {
+                    disableCPUProfiler(function () { return process.exit(exitCode); });
+                },
+                enableCPUProfiler: enableCPUProfiler,
+                disableCPUProfiler: disableCPUProfiler,
+                cpuProfilingEnabled: function () { return !!activeSession || ts.contains(process.execArgv, "--cpu-prof") || ts.contains(process.execArgv, "--prof"); },
+                realpath: realpath,
+                debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || ts.some(process.execArgv, function (arg) { return /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg); }),
+                tryEnableSourceMapsForHost: function () {
+                    try {
+                        require("source-map-support").install();
+                    }
+                    catch (_a) {
+                        // Could not enable source maps.
+                    }
+                },
+                setTimeout: setTimeout,
+                clearTimeout: clearTimeout,
+                clearScreen: function () {
+                    process.stdout.write("\x1Bc");
+                },
+                setBlocking: function () {
+                    if (process.stdout && process.stdout._handle && process.stdout._handle.setBlocking) {
+                        process.stdout._handle.setBlocking(true);
+                    }
+                },
+                bufferFrom: bufferFrom,
+                base64decode: function (input) { return bufferFrom(input, "base64").toString("utf8"); },
+                base64encode: function (input) { return bufferFrom(input).toString("base64"); },
+                require: function (baseDir, moduleName) {
+                    try {
+                        var modulePath = ts.resolveJSModule(moduleName, baseDir, nodeSystem);
+                        return { module: require(modulePath), modulePath: modulePath, error: undefined };
+                    }
+                    catch (error) {
+                        return { module: undefined, modulePath: undefined, error: error };
+                    }
+                }
+            };
+            return nodeSystem;
+            /**
+             * `throwIfNoEntry` was added so recently that it's not in the node types.
+             * This helper encapsulates the mitigating usage of `any`.
+             * See https://github.com/nodejs/node/pull/33716
+             */
+            function statSync(path) {
+                // throwIfNoEntry will be ignored by older versions of node
+                return _fs.statSync(path, { throwIfNoEntry: false });
+            }
+            /**
+             * Uses the builtin inspector APIs to capture a CPU profile
+             * See https://nodejs.org/api/inspector.html#inspector_example_usage for details
+             */
+            function enableCPUProfiler(path, cb) {
+                if (activeSession) {
+                    cb();
+                    return false;
+                }
+                var inspector = require("inspector");
+                if (!inspector || !inspector.Session) {
+                    cb();
+                    return false;
+                }
+                var session = new inspector.Session();
+                session.connect();
+                session.post("Profiler.enable", function () {
+                    session.post("Profiler.start", function () {
+                        activeSession = session;
+                        profilePath = path;
+                        cb();
+                    });
+                });
+                return true;
+            }
+            /**
+             * Strips non-TS paths from the profile, so users with private projects shouldn't
+             * need to worry about leaking paths by submitting a cpu profile to us
+             */
+            function cleanupPaths(profile) {
+                var externalFileCounter = 0;
+                var remappedPaths = new ts.Map();
+                var normalizedDir = ts.normalizeSlashes(__dirname);
+                // Windows rooted dir names need an extra `/` prepended to be valid file:/// urls
+                var fileUrlRoot = "file://".concat(ts.getRootLength(normalizedDir) === 1 ? "" : "/").concat(normalizedDir);
+                for (var _i = 0, _a = profile.nodes; _i < _a.length; _i++) {
+                    var node = _a[_i];
+                    if (node.callFrame.url) {
+                        var url = ts.normalizeSlashes(node.callFrame.url);
+                        if (ts.containsPath(fileUrlRoot, url, useCaseSensitiveFileNames)) {
+                            node.callFrame.url = ts.getRelativePathToDirectoryOrUrl(fileUrlRoot, url, fileUrlRoot, ts.createGetCanonicalFileName(useCaseSensitiveFileNames), /*isAbsolutePathAnUrl*/ true);
+                        }
+                        else if (!nativePattern.test(url)) {
+                            node.callFrame.url = (remappedPaths.has(url) ? remappedPaths : remappedPaths.set(url, "external".concat(externalFileCounter, ".js"))).get(url);
+                            externalFileCounter++;
+                        }
+                    }
+                }
+                return profile;
+            }
+            function disableCPUProfiler(cb) {
+                if (activeSession && activeSession !== "stopping") {
+                    var s_1 = activeSession;
+                    activeSession.post("Profiler.stop", function (err, _a) {
+                        var _b;
+                        var profile = _a.profile;
+                        if (!err) {
+                            try {
+                                if ((_b = statSync(profilePath)) === null || _b === void 0 ? void 0 : _b.isDirectory()) {
+                                    profilePath = _path.join(profilePath, "".concat((new Date()).toISOString().replace(/:/g, "-"), "+P").concat(process.pid, ".cpuprofile"));
+                                }
+                            }
+                            catch (_c) {
+                                // do nothing and ignore fallible fs operation
+                            }
+                            try {
+                                _fs.mkdirSync(_path.dirname(profilePath), { recursive: true });
+                            }
+                            catch (_d) {
+                                // do nothing and ignore fallible fs operation
+                            }
+                            _fs.writeFileSync(profilePath, JSON.stringify(cleanupPaths(profile)));
+                        }
+                        activeSession = undefined;
+                        s_1.disconnect();
+                        cb();
+                    });
+                    activeSession = "stopping";
+                    return true;
+                }
+                else {
+                    cb();
+                    return false;
+                }
+            }
+            function bufferFrom(input, encoding) {
+                // See https://github.com/Microsoft/TypeScript/issues/25652
+                return Buffer.from && Buffer.from !== Int8Array.from
+                    ? Buffer.from(input, encoding)
+                    : new Buffer(input, encoding);
+            }
+            function isFileSystemCaseSensitive() {
+                // win32\win64 are case insensitive platforms
+                if (platform === "win32" || platform === "win64") {
+                    return false;
+                }
+                // If this file exists under a different case, we must be case-insensitve.
+                return !fileExists(swapCase(__filename));
+            }
+            /** Convert all lowercase chars to uppercase, and vice-versa */
+            function swapCase(s) {
+                return s.replace(/\w/g, function (ch) {
+                    var up = ch.toUpperCase();
+                    return ch === up ? ch.toLowerCase() : up;
+                });
+            }
+            function fsWatchFileWorker(fileName, callback, pollingInterval) {
+                _fs.watchFile(fileName, { persistent: true, interval: pollingInterval }, fileChanged);
+                var eventKind;
+                return {
+                    close: function () { return _fs.unwatchFile(fileName, fileChanged); }
+                };
+                function fileChanged(curr, prev) {
+                    // previous event kind check is to ensure we recongnize the file as previously also missing when it is restored or renamed twice (that is it disappears and reappears)
+                    // In such case, prevTime returned is same as prev time of event when file was deleted as per node documentation
+                    var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted;
+                    if (+curr.mtime === 0) {
+                        if (isPreviouslyDeleted) {
+                            // Already deleted file, no need to callback again
+                            return;
+                        }
+                        eventKind = FileWatcherEventKind.Deleted;
+                    }
+                    else if (isPreviouslyDeleted) {
+                        eventKind = FileWatcherEventKind.Created;
+                    }
+                    // If there is no change in modified time, ignore the event
+                    else if (+curr.mtime === +prev.mtime) {
+                        return;
+                    }
+                    else {
+                        // File changed
+                        eventKind = FileWatcherEventKind.Changed;
+                    }
+                    callback(fileName, eventKind);
+                }
+            }
+            function fsWatch(fileOrDirectory, entryKind, callback, recursive, fallbackPollingInterval, fallbackOptions) {
+                var options;
+                var lastDirectoryPartWithDirectorySeparator;
+                var lastDirectoryPart;
+                if (isLinuxOrMacOs) {
+                    lastDirectoryPartWithDirectorySeparator = fileOrDirectory.substr(fileOrDirectory.lastIndexOf(ts.directorySeparator));
+                    lastDirectoryPart = lastDirectoryPartWithDirectorySeparator.slice(ts.directorySeparator.length);
+                }
+                /** Watcher for the file system entry depending on whether it is missing or present */
+                var watcher = !fileSystemEntryExists(fileOrDirectory, entryKind) ?
+                    watchMissingFileSystemEntry() :
+                    watchPresentFileSystemEntry();
+                return {
+                    close: function () {
+                        // Close the watcher (either existing file system entry watcher or missing file system entry watcher)
+                        watcher.close();
+                        watcher = undefined;
+                    }
+                };
+                /**
+                 * Invoke the callback with rename and update the watcher if not closed
+                 * @param createWatcher
+                 */
+                function invokeCallbackAndUpdateWatcher(createWatcher) {
+                    ts.sysLog("sysLog:: ".concat(fileOrDirectory, ":: Changing watcher to ").concat(createWatcher === watchPresentFileSystemEntry ? "Present" : "Missing", "FileSystemEntryWatcher"));
+                    // Call the callback for current directory
+                    callback("rename", "");
+                    // If watcher is not closed, update it
+                    if (watcher) {
+                        watcher.close();
+                        watcher = createWatcher();
+                    }
+                }
+                /**
+                 * Watch the file or directory that is currently present
+                 * and when the watched file or directory is deleted, switch to missing file system entry watcher
+                 */
+                function watchPresentFileSystemEntry() {
+                    // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
+                    // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
+                    if (options === undefined) {
+                        if (fsSupportsRecursiveFsWatch) {
+                            options = { persistent: true, recursive: !!recursive };
+                        }
+                        else {
+                            options = { persistent: true };
+                        }
+                    }
+                    if (hitSystemWatcherLimit) {
+                        ts.sysLog("sysLog:: ".concat(fileOrDirectory, ":: Defaulting to fsWatchFile"));
+                        return watchPresentFileSystemEntryWithFsWatchFile();
+                    }
+                    try {
+                        var presentWatcher = _fs.watch(fileOrDirectory, options, isLinuxOrMacOs ?
+                            callbackChangingToMissingFileSystemEntry :
+                            callback);
+                        // Watch the missing file or directory or error
+                        presentWatcher.on("error", function () { return invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry); });
+                        return presentWatcher;
+                    }
+                    catch (e) {
+                        // Catch the exception and use polling instead
+                        // Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
+                        // so instead of throwing error, use fs.watchFile
+                        hitSystemWatcherLimit || (hitSystemWatcherLimit = e.code === "ENOSPC");
+                        ts.sysLog("sysLog:: ".concat(fileOrDirectory, ":: Changing to fsWatchFile"));
+                        return watchPresentFileSystemEntryWithFsWatchFile();
+                    }
+                }
+                function callbackChangingToMissingFileSystemEntry(event, relativeName) {
+                    // because relativeName is not guaranteed to be correct we need to check on each rename with few combinations
+                    // Eg on ubuntu while watching app/node_modules the relativeName is "node_modules" which is neither relative nor full path
+                    return event === "rename" &&
+                        (!relativeName ||
+                            relativeName === lastDirectoryPart ||
+                            (relativeName.lastIndexOf(lastDirectoryPartWithDirectorySeparator) !== -1 && relativeName.lastIndexOf(lastDirectoryPartWithDirectorySeparator) === relativeName.length - lastDirectoryPartWithDirectorySeparator.length)) &&
+                        !fileSystemEntryExists(fileOrDirectory, entryKind) ?
+                        invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry) :
+                        callback(event, relativeName);
+                }
+                /**
+                 * Watch the file or directory using fs.watchFile since fs.watch threw exception
+                 * Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
+                 */
+                function watchPresentFileSystemEntryWithFsWatchFile() {
+                    return watchFile(fileOrDirectory, createFileWatcherCallback(callback), fallbackPollingInterval, fallbackOptions);
+                }
+                /**
+                 * Watch the file or directory that is missing
+                 * and switch to existing file or directory when the missing filesystem entry is created
+                 */
+                function watchMissingFileSystemEntry() {
+                    return watchFile(fileOrDirectory, function (_fileName, eventKind) {
+                        if (eventKind === FileWatcherEventKind.Created && fileSystemEntryExists(fileOrDirectory, entryKind)) {
+                            // Call the callback for current file or directory
+                            // For now it could be callback for the inner directory creation,
+                            // but just return current directory, better than current no-op
+                            invokeCallbackAndUpdateWatcher(watchPresentFileSystemEntry);
+                        }
+                    }, fallbackPollingInterval, fallbackOptions);
+                }
+            }
+            function readFileWorker(fileName, _encoding) {
+                var buffer;
+                try {
+                    buffer = _fs.readFileSync(fileName);
+                }
+                catch (e) {
+                    return undefined;
+                }
+                var len = buffer.length;
+                if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
+                    // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
+                    // flip all byte pairs and treat as little endian.
+                    len &= ~1; // Round down to a multiple of 2
+                    for (var i = 0; i < len; i += 2) {
+                        var temp = buffer[i];
+                        buffer[i] = buffer[i + 1];
+                        buffer[i + 1] = temp;
+                    }
+                    return buffer.toString("utf16le", 2);
+                }
+                if (len >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) {
+                    // Little endian UTF-16 byte order mark detected
+                    return buffer.toString("utf16le", 2);
+                }
+                if (len >= 3 && buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
+                    // UTF-8 byte order mark detected
+                    return buffer.toString("utf8", 3);
+                }
+                // Default is UTF-8 with no byte order mark
+                return buffer.toString("utf8");
+            }
+            function readFile(fileName, _encoding) {
+                ts.perfLogger.logStartReadFile(fileName);
+                var file = readFileWorker(fileName, _encoding);
+                ts.perfLogger.logStopReadFile();
+                return file;
+            }
+            function writeFile(fileName, data, writeByteOrderMark) {
+                ts.perfLogger.logEvent("WriteFile: " + fileName);
+                // If a BOM is required, emit one
+                if (writeByteOrderMark) {
+                    data = byteOrderMarkIndicator + data;
+                }
+                var fd;
+                try {
+                    fd = _fs.openSync(fileName, "w");
+                    _fs.writeSync(fd, data, /*position*/ undefined, "utf8");
+                }
+                finally {
+                    if (fd !== undefined) {
+                        _fs.closeSync(fd);
+                    }
+                }
+            }
+            function getAccessibleFileSystemEntries(path) {
+                ts.perfLogger.logEvent("ReadDir: " + (path || "."));
+                try {
+                    var entries = _fs.readdirSync(path || ".", { withFileTypes: true });
+                    var files = [];
+                    var directories = [];
+                    for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
+                        var dirent = entries_1[_i];
+                        // withFileTypes is not supported before Node 10.10.
+                        var entry = typeof dirent === "string" ? dirent : dirent.name;
+                        // This is necessary because on some file system node fails to exclude
+                        // "." and "..". See https://github.com/nodejs/node/issues/4002
+                        if (entry === "." || entry === "..") {
+                            continue;
+                        }
+                        var stat = void 0;
+                        if (typeof dirent === "string" || dirent.isSymbolicLink()) {
+                            var name = ts.combinePaths(path, entry);
+                            try {
+                                stat = statSync(name);
+                                if (!stat) {
+                                    continue;
+                                }
+                            }
+                            catch (e) {
+                                continue;
+                            }
+                        }
+                        else {
+                            stat = dirent;
+                        }
+                        if (stat.isFile()) {
+                            files.push(entry);
+                        }
+                        else if (stat.isDirectory()) {
+                            directories.push(entry);
+                        }
+                    }
+                    files.sort();
+                    directories.sort();
+                    return { files: files, directories: directories };
+                }
+                catch (e) {
+                    return ts.emptyFileSystemEntries;
+                }
+            }
+            function readDirectory(path, extensions, excludes, includes, depth) {
+                return ts.matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
+            }
+            function fileSystemEntryExists(path, entryKind) {
+                // Since the error thrown by fs.statSync isn't used, we can avoid collecting a stack trace to improve
+                // the CPU time performance.
+                var originalStackTraceLimit = Error.stackTraceLimit;
+                Error.stackTraceLimit = 0;
+                try {
+                    var stat = statSync(path);
+                    if (!stat) {
+                        return false;
+                    }
+                    switch (entryKind) {
+                        case 0 /* File */: return stat.isFile();
+                        case 1 /* Directory */: return stat.isDirectory();
+                        default: return false;
+                    }
+                }
+                catch (e) {
+                    return false;
+                }
+                finally {
+                    Error.stackTraceLimit = originalStackTraceLimit;
+                }
+            }
+            function fileExists(path) {
+                return fileSystemEntryExists(path, 0 /* File */);
+            }
+            function directoryExists(path) {
+                return fileSystemEntryExists(path, 1 /* Directory */);
+            }
+            function getDirectories(path) {
+                return getAccessibleFileSystemEntries(path).directories.slice();
+            }
+            function realpath(path) {
+                try {
+                    return realpathSync(path);
+                }
+                catch (_a) {
+                    return path;
+                }
+            }
+            function getModifiedTime(path) {
+                var _a;
+                try {
+                    return (_a = statSync(path)) === null || _a === void 0 ? void 0 : _a.mtime;
+                }
+                catch (e) {
+                    return undefined;
+                }
+            }
+            function setModifiedTime(path, time) {
+                try {
+                    _fs.utimesSync(path, time, time);
+                }
+                catch (e) {
+                    return;
+                }
+            }
+            function deleteFile(path) {
+                try {
+                    return _fs.unlinkSync(path);
+                }
+                catch (e) {
+                    return;
+                }
+            }
+            function createSHA256Hash(data) {
+                var hash = _crypto.createHash("sha256");
+                hash.update(data);
+                return hash.digest("hex");
+            }
+        }
+        var sys;
+        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") {
+            // process and process.nextTick checks if current environment is node-like
+            // process.browser check excludes webpack and browserify
+            sys = getNodeSystem();
+        }
+        if (sys) {
+            // patch writefile to create folder before writing the file
+            patchWriteFileEnsuringDirectory(sys);
+        }
+        return sys;
+    })();
     /*@internal*/
     function setSys(s) {
         ts.sys = s;
@@ -162604,7 +163188,7 @@ if (typeof process === "undefined" || process.browser) {
     globalThis.toolsVersion = ts.versionMajorMinor;
 }
 if (typeof module !== "undefined" && module.exports) {
-    /* MONACOCHANGE */ /*module.exports = ts;*/ /* END MONACOCHANGE */
+    module.exports = ts;
 }
 var ts;
 (function (ts) {