From f3b191ab38fb9f1717ce5ce3396bb41204ffb399 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 7 Sep 2018 16:05:24 +0200 Subject: [PATCH] @ts-check for bootstrap JS files --- src/bootstrap-amd.js | 5 +- src/bootstrap-fork.js | 13 +- src/bootstrap-window.js | 29 ++++- src/bootstrap.js | 26 +++- src/cli.js | 3 + src/main.js | 114 +++++++++++++++--- src/paths.js | 18 ++- .../electron-browser/issue/issueReporter.js | 1 + .../processExplorer/processExplorer.js | 1 + .../sharedProcess/sharedProcess.js | 1 + .../electron-browser/bootstrap/index.js | 15 ++- 11 files changed, 195 insertions(+), 31 deletions(-) diff --git a/src/bootstrap-amd.js b/src/bootstrap-amd.js index 9ed9971d9cb..85e0ef9c85e 100644 --- a/src/bootstrap-amd.js +++ b/src/bootstrap-amd.js @@ -3,6 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +//@ts-check +'use strict'; + const loader = require('./vs/loader'); const bootstrap = require('./bootstrap'); @@ -20,7 +23,7 @@ loader.config({ }); // Running in Electron -if (process.env['ELECTRON_RUN_AS_NODE'] || process.versions.electron) { +if (process.env['ELECTRON_RUN_AS_NODE'] || process.versions['electron']) { loader.define('fs', ['original-fs'], function (originalFS) { return originalFS; // replace the patched electron fs with the original node fs for all AMD code }); diff --git a/src/bootstrap-fork.js b/src/bootstrap-fork.js index 51b67383a36..e30cadb0fca 100644 --- a/src/bootstrap-fork.js +++ b/src/bootstrap-fork.js @@ -3,6 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +//@ts-check +'use strict'; + const bootstrap = require('./bootstrap'); // Enable ASAR in our forked processes @@ -143,19 +146,21 @@ function disableSTDIO() { write: function () { /* No OP */ } }); - process.__defineGetter__('stdout', function () { return writable; }); - process.__defineGetter__('stderr', function () { return writable; }); - process.__defineGetter__('stdin', function () { return writable; }); + process['__defineGetter__']('stdout', function () { return writable; }); + process['__defineGetter__']('stderr', function () { return writable; }); + process['__defineGetter__']('stdin', function () { return writable; }); } function handleExceptions() { // Handle uncaught exceptions + // @ts-ignore process.on('uncaughtException', function (err) { console.error('Uncaught Exception: ', err); }); // Handle unhandled promise rejections + // @ts-ignore process.on('unhandledRejection', function (reason) { console.error('Unhandled Promise Rejection: ', reason); }); @@ -181,7 +186,7 @@ function configureCrashReporter() { try { const crashReporterOptions = JSON.parse(crashReporterOptionsRaw); if (crashReporterOptions) { - process.crashReporter.start(crashReporterOptions); + process['crashReporter'].start(crashReporterOptions); } } catch (error) { console.error(error); diff --git a/src/bootstrap-window.js b/src/bootstrap-window.js index d5ff9909953..a260c5f9bc3 100644 --- a/src/bootstrap-window.js +++ b/src/bootstrap-window.js @@ -3,6 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +//@ts-check +'use strict'; + const bootstrap = require('./bootstrap'); exports.parseURLQueryArgs = function () { @@ -15,17 +18,30 @@ exports.parseURLQueryArgs = function () { .reduce(function (r, param) { r[param[0]] = decodeURIComponent(param[1]); return r; }, {}); }; -exports.assign = function (destination, source) { +/** + * @param {object} destination + * @param {object} source + * @returns {object} + */ +exports.assign = function assign(destination, source) { return Object.keys(source).reduce(function (r, key) { r[key] = source[key]; return r; }, destination); }; +/** + * + * @param {string[]} modulePaths + * @param {(result, configuration) => any} resultCallback + * @param {{ removeDeveloperKeybindingsAfterLoad: boolean, canModifyDOM: (config) => void, beforeLoaderConfig: (config, loaderConfig) => void, beforeRequire: () => void }=} options + */ exports.load = function (modulePaths, resultCallback, options) { + // @ts-ignore const webFrame = require('electron').webFrame; const args = exports.parseURLQueryArgs(); const configuration = JSON.parse(args['config'] || '{}') || {}; // Error handler + // @ts-ignore process.on('uncaughtException', function (error) { onUnexpectedError(error, enableDeveloperTools); }); // Developer tools @@ -70,13 +86,13 @@ exports.load = function (modulePaths, resultCallback, options) { const amdDefine = amdLoader.require.define; const nodeRequire = amdLoader.require.nodeRequire; - window.nodeRequire = nodeRequire; - window.require = amdRequire; + window['nodeRequire'] = nodeRequire; + window['require'] = amdRequire; // replace the patched electron fs with the original node fs for all AMD code amdDefine('fs', ['original-fs'], function (originalFS) { return originalFS; }); - window.MonacoEnvironment = {}; + window['MonacoEnvironment'] = {}; const loaderConfig = { baseUrl: bootstrap.uriFromPath(configuration.appRoot) + '/out', @@ -119,7 +135,11 @@ exports.load = function (modulePaths, resultCallback, options) { }); }; +/** + * @returns () => void + */ function registerDeveloperKeybindings() { + // @ts-ignore const ipc = require('electron').ipcRenderer; const extractKey = function (e) { @@ -156,6 +176,7 @@ function registerDeveloperKeybindings() { } function onUnexpectedError(error, enableDeveloperTools) { + // @ts-ignore const ipc = require('electron').ipcRenderer; if (enableDeveloperTools) { diff --git a/src/bootstrap.js b/src/bootstrap.js index 43b30f58708..58c74c3f4aa 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -3,6 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +//@ts-check +'use strict'; + //#region global bootstrapping // increase number of stack frames(from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) @@ -10,6 +13,7 @@ Error.stackTraceLimit = 100; // Workaround for Electron not installing a handler to ignore SIGPIPE // (https://github.com/electron/electron/issues/13254) +// @ts-ignore process.on('SIGPIPE', () => { console.error(new Error('Unexpected SIGPIPE')); }); @@ -18,8 +22,9 @@ process.on('SIGPIPE', () => { //#region Add support for using node_modules.asar exports.enableASARSupport = function () { - const path = require('path'); + // @ts-ignore const Module = require('module'); + const path = require('path'); let NODE_MODULES_PATH = path.join(__dirname, '../node_modules'); if (process.platform === 'win32' && /[a-z]\:/.test(NODE_MODULES_PATH)) { @@ -46,6 +51,10 @@ exports.enableASARSupport = function () { //#endregion //#region URI helpers +/** + * @param {string} _path + * @returns {string} + */ exports.uriFromPath = function (_path) { const path = require('path'); @@ -59,6 +68,10 @@ exports.uriFromPath = function (_path) { //#endregion //#region FS helpers +/** + * @param {string} file + * @returns {Promise} + */ exports.readFile = function (file) { const fs = require('fs'); @@ -73,6 +86,11 @@ exports.readFile = function (file) { }); }; +/** + * @param {string} file + * @param {string} content + * @returns {Promise} + */ exports.writeFile = function (file, content) { const fs = require('fs'); @@ -136,10 +154,14 @@ exports.setupNLS = function () { //#endregion //#region Portable helpers +/** + * @returns {{ portableDataPath: string, isPortable: boolean }} + */ exports.configurePortable = function () { + // @ts-ignore + const product = require('../product.json'); const path = require('path'); const fs = require('fs'); - const product = require('../product.json'); const appRoot = path.dirname(__dirname); diff --git a/src/cli.js b/src/cli.js index d464953c4b7..17db1b6a2f7 100644 --- a/src/cli.js +++ b/src/cli.js @@ -3,6 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +//@ts-check +'use strict'; + const bootstrap = require('./bootstrap'); // Enable portable support diff --git a/src/main.js b/src/main.js index dea74bf39ff..ecdb72e6037 100644 --- a/src/main.js +++ b/src/main.js @@ -2,6 +2,8 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ + +//@ts-check 'use strict'; const perf = require('./vs/base/common/performance'); @@ -9,10 +11,12 @@ perf.mark('main:started'); const fs = require('fs'); const path = require('path'); -const product = require('../product.json'); const bootstrap = require('./bootstrap'); -const app = require('electron').app; const paths = require('./paths'); +// @ts-ignore +const product = require('../product.json'); +// @ts-ignore +const app = require('electron').app; // Enable portable support const portable = bootstrap.configurePortable(); @@ -116,6 +120,9 @@ function configureCommandlineSwitches(cliArgs, nodeCachedDataDir) { } } +/** + * @returns {string} + */ function resolveJSFlags(cliArgs, ...jsFlags) { if (cliArgs['js-flags']) { jsFlags.push(cliArgs['js-flags']); @@ -128,6 +135,9 @@ function resolveJSFlags(cliArgs, ...jsFlags) { return jsFlags.length > 0 ? jsFlags.join(' ') : null; } +/** + * @returns {string} + */ function getUserDataPath(cliArgs) { if (portable.isPortable) { return path.join(portable.portableDataPath, 'user-data'); @@ -138,7 +148,7 @@ function getUserDataPath(cliArgs) { function parseCLIArgs() { const minimist = require('minimist'); - + return minimist(process.argv, { string: [ 'user-data-dir', @@ -166,9 +176,10 @@ function registerListeners() { // Mac: when someone drops a file to the not-yet running VSCode, the open-file event fires even before // the app-ready event. We listen very early for open-file and remember this upon startup as path to open. - global.macOpenFiles = []; + const macOpenFiles = []; + global['macOpenFiles'] = macOpenFiles; app.on('open-file', function (event, path) { - global.macOpenFiles.push(path); + macOpenFiles.push(path); }); const openUrls = []; @@ -182,13 +193,16 @@ function registerListeners() { app.on('open-url', onOpenUrl); }); - global.getOpenUrls = function () { + global['getOpenUrls'] = function () { app.removeListener('open-url', onOpenUrl); return openUrls; }; } +/** + * @param {string} userDataPath + */ function getNodeCachedDir(userDataPath) { return new class { @@ -223,6 +237,10 @@ function getNodeCachedDir(userDataPath) { } //#region NLS Support +/** + * @param {string} content + * @returns {string} + */ function stripComments(content) { let regexp = /("(?:[^\\\"]*(?:\\.)?)*")|('(?:[^\\\']*(?:\\.)?)*')|(\/\*(?:\r?\n|.)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g; let result = content.replace(regexp, function (match, m1, m2, m3, m4) { @@ -247,14 +265,66 @@ function stripComments(content) { return result; } -function mkdir(dir) { return new Promise((c, e) => fs.mkdir(dir, err => (err && err.code !== 'EEXIST') ? e(err) : c(dir))); } -function exists(file) { return new Promise(c => fs.exists(file, c)); } -function touch(file) { return new Promise((c, e) => { const d = new Date(); fs.utimes(file, d, d, err => err ? e(err) : c()); }); } -function lstat(file) { return new Promise((c, e) => fs.lstat(file, (err, stats) => err ? e(err) : c(stats))); } -function readdir(dir) { return new Promise((c, e) => fs.readdir(dir, (err, files) => err ? e(err) : c(files))); } -function rmdir(dir) { return new Promise((c, e) => fs.rmdir(dir, err => err ? e(err) : c(undefined))); } -function unlink(file) { return new Promise((c, e) => fs.unlink(file, err => err ? e(err) : c(undefined))); } +/** + * @param {string} dir + * @returns {Promise} + */ +function mkdir(dir) { + return new Promise((c, e) => fs.mkdir(dir, err => (err && err.code !== 'EEXIST') ? e(err) : c(dir))); +} +/** + * @param {string} file + * @returns {Promise} + */ +function exists(file) { + return new Promise(c => fs.exists(file, c)); +} + +/** + * @param {string} file + * @returns {Promise} + */ +function touch(file) { + return new Promise((c, e) => { const d = new Date(); fs.utimes(file, d, d, err => err ? e(err) : c()); }); +} + +/** + * @param {string} file + * @returns {Promise} + */ +function lstat(file) { + return new Promise((c, e) => fs.lstat(file, (err, stats) => err ? e(err) : c(stats))); +} + +/** + * @param {string} dir + * @returns {Promise} + */ +function readdir(dir) { + return new Promise((c, e) => fs.readdir(dir, (err, files) => err ? e(err) : c(files))); +} + +/** + * @param {string} dir + * @returns {Promise} + */ +function rmdir(dir) { + return new Promise((c, e) => fs.rmdir(dir, err => err ? e(err) : c(undefined))); +} + +/** + * @param {string} file + * @returns {Promise} + */ +function unlink(file) { + return new Promise((c, e) => fs.unlink(file, err => err ? e(err) : c(undefined))); +} + +/** + * @param {string} dir + * @returns {Promise} + */ function mkdirp(dir) { return mkdir(dir).then(null, err => { if (err && err.code === 'ENOENT') { @@ -269,6 +339,10 @@ function mkdirp(dir) { }); } +/** + * @param {string} location + * @returns {Promise} + */ function rimraf(location) { return lstat(location).then(stat => { if (stat.isDirectory() && !stat.isSymbolicLink()) { @@ -290,7 +364,9 @@ function rimraf(location) { // To make this work on case preserving & insensitive FS we do the following: // the language bundles have lower case language tags and we always lower case // the locale we receive from the user or OS. - +/** + * @returns {Promise} + */ function getUserDefinedLocale() { let locale = args['locale']; if (locale) { @@ -315,6 +391,9 @@ function getUserDefinedLocale() { }); } +/** + * @returns {object} + */ function getLanguagePackConfigurations() { let configFile = path.join(userDataPath, 'languagepacks.json'); try { @@ -326,6 +405,10 @@ function getLanguagePackConfigurations() { return undefined; } +/** + * @param {object} config + * @param {string} locale + */ function resolveLanguagePackLocale(config, locale) { try { while (locale) { @@ -346,6 +429,9 @@ function resolveLanguagePackLocale(config, locale) { return undefined; } +/** + * @param {string} locale + */ function getNLSConfiguration(locale) { if (locale === 'pseudo') { return Promise.resolve({ locale: locale, availableLanguages: {}, pseudo: true }); diff --git a/src/paths.js b/src/paths.js index 1fa7c625ee1..33c691bf72b 100644 --- a/src/paths.js +++ b/src/paths.js @@ -3,10 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -var path = require('path'); -var os = require('os'); -var pkg = require('../package.json'); +//@ts-check +'use strict'; +// @ts-ignore +const pkg = require('../package.json'); +const path = require('path'); +const os = require('os'); + +/** + * @param {string} platform + * @returns {string} + */ function getAppDataPath(platform) { switch (platform) { case 'win32': return process.env['VSCODE_APPDATA'] || process.env['APPDATA'] || path.join(process.env['USERPROFILE'], 'AppData', 'Roaming'); @@ -16,6 +24,10 @@ function getAppDataPath(platform) { } } +/** + * @param {string} platform + * @returns {string} + */ function getDefaultUserDataPath(platform) { return path.join(getAppDataPath(platform), pkg.name); } diff --git a/src/vs/code/electron-browser/issue/issueReporter.js b/src/vs/code/electron-browser/issue/issueReporter.js index 01a8e8da4fe..ebe4971f6da 100644 --- a/src/vs/code/electron-browser/issue/issueReporter.js +++ b/src/vs/code/electron-browser/issue/issueReporter.js @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +//@ts-check 'use strict'; const bootstrapWindow = require('../../../../bootstrap-window'); diff --git a/src/vs/code/electron-browser/processExplorer/processExplorer.js b/src/vs/code/electron-browser/processExplorer/processExplorer.js index 379aef3cdee..61099364121 100644 --- a/src/vs/code/electron-browser/processExplorer/processExplorer.js +++ b/src/vs/code/electron-browser/processExplorer/processExplorer.js @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +//@ts-check 'use strict'; const bootstrapWindow = require('../../../../bootstrap-window'); diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcess.js b/src/vs/code/electron-browser/sharedProcess/sharedProcess.js index 624d1335c59..886bca97a2c 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcess.js +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcess.js @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +//@ts-check 'use strict'; const bootstrapWindow = require('../../../../bootstrap-window'); diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index cce69e9c9cf..e9970ed686a 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +//@ts-check 'use strict'; /*global window,document,define*/ @@ -13,7 +14,7 @@ perf.mark('renderer/started'); const bootstrapWindow = require('../../../../bootstrap-window'); // Setup shell environment -process.lazyEnv = getLazyEnv(); +process['lazyEnv'] = getLazyEnv(); // Load workbench main bootstrapWindow.load([ @@ -24,9 +25,10 @@ bootstrapWindow.load([ function (workbench, configuration) { perf.mark('didLoadWorkbenchMain'); - return process.lazyEnv.then(function () { + return process['lazyEnv'].then(function () { perf.mark('main/startup'); + // @ts-ignore return require('vs/workbench/electron-browser/main').startup(configuration); }); }, { @@ -35,7 +37,7 @@ bootstrapWindow.load([ showPartsSplash(windowConfig); }, beforeLoaderConfig: function (windowConfig, loaderConfig) { - const onNodeCachedData = window.MonacoEnvironment.onNodeCachedData = []; + const onNodeCachedData = window['MonacoEnvironment'].onNodeCachedData = []; loaderConfig.onNodeCachedData = function () { onNodeCachedData.push(arguments); }; @@ -47,6 +49,9 @@ bootstrapWindow.load([ } }); +/** + * @param {object} configuration + */ function showPartsSplash(configuration) { perf.mark('willShowPartsSplash'); @@ -110,7 +115,11 @@ function showPartsSplash(configuration) { perf.mark('didShowPartsSplash'); } +/** + * @returns {Promise} + */ function getLazyEnv() { + // @ts-ignore const ipc = require('electron').ipcRenderer; return new Promise(function (resolve) {