diff --git a/.yarnrc b/.yarnrc index fe7090fa356..692f8799451 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,3 +1,3 @@ disturl "https://atom.io/download/electron" -target "3.1.3" +target "3.1.6" runtime "electron" diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 37d63713475..be1b9e2bd3b 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -16,7 +16,7 @@ }, { "name": "ms-vscode.node-debug2", - "version": "1.32.0", + "version": "1.33.0", "repo": "https://github.com/Microsoft/vscode-node-debug2", "metadata": { "id": "36d19e17-7569-4841-a001-947eb18602b2", diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 9c2231119e9..041ceea7419 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -339,6 +339,8 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op .pipe(util.cleanNodeModule('node-pty', ['binding.gyp', 'build/**', 'src/**', 'tools/**'], ['build/Release/*.exe', 'build/Release/*.dll', 'build/Release/*.node'])) .pipe(util.cleanNodeModule('vscode-nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['build/Release/*.node', '**/*.a'])) .pipe(util.cleanNodeModule('vsda', ['binding.gyp', 'README.md', 'build/**', '*.bat', '*.sh', '*.cpp', '*.h'], ['build/Release/vsda.node'])) + .pipe(util.cleanNodeModule('win-ca-lib', ['**/*'], ['package.json', '**/*.node'])) + .pipe(util.cleanNodeModule('node-addon-api', ['**/*'])) .pipe(createAsar(path.join(process.cwd(), 'node_modules'), ['**/*.node', '**/vscode-ripgrep/bin/*', '**/node-pty/build/Release/*'], 'app/node_modules.asar')); let all = es.merge( diff --git a/cgmanifest.json b/cgmanifest.json index 21d78500903..afaebd61771 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -73,12 +73,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "72ff292302f95bfe5b4e02085a7be56254b42b0e" + "commitHash": "73158a6419a3e2da9e4d523e1131052abd28fbbb" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "3.1.3" + "version": "3.1.6" }, { "component": { diff --git a/package.json b/package.json index 51241ada59a..5ea684c24c9 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "vscode-ripgrep": "^1.2.5", "vscode-sqlite3": "4.0.7", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.12.0-beta5", + "vscode-xterm": "3.13.0-beta1", "yauzl": "^2.9.1", "yazl": "^2.4.3" }, @@ -146,8 +146,9 @@ }, "optionalDependencies": { "vscode-windows-registry": "1.0.1", + "win-ca-lib": "https://github.com/chrmarti/win-ca/releases/download/v2.4.1-lib-test/win-ca-lib-2.4.1.tgz", "windows-foreground-love": "0.1.0", "windows-mutex": "0.2.1", "windows-process-tree": "0.2.3" } -} \ No newline at end of file +} diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index b75bed4176a..8465b2b8a15 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -24,6 +24,7 @@ "./vs/workbench/contrib/splash/**/*.ts", "./vs/workbench/contrib/tasks/**/*.ts", "./vs/workbench/services/commands/**/*", + "./vs/workbench/services/configuration/common/**/*", "./vs/workbench/services/files/node/watcher/**/*", "./vs/workbench/services/themes/**/*.ts", "./vs/workbench/services/bulkEdit/**/*.ts", @@ -255,6 +256,7 @@ "./vs/workbench/contrib/debug/electron-browser/electronDebugActions.ts", "./vs/workbench/contrib/debug/electron-browser/rawDebugSession.ts", "./vs/workbench/contrib/debug/electron-browser/variablesView.ts", + "./vs/workbench/contrib/debug/electron-browser/watchExpressionsView.ts", "./vs/workbench/contrib/debug/test/common/debugSource.test.ts", "./vs/workbench/contrib/debug/test/common/debugUtils.test.ts", "./vs/workbench/contrib/debug/test/common/mockDebug.ts", @@ -381,11 +383,9 @@ "./vs/workbench/services/backup/common/backup.ts", "./vs/workbench/services/backup/node/backupFileService.ts", "./vs/workbench/services/broadcast/electron-browser/broadcastService.ts", - "./vs/workbench/services/configuration/common/configuration.ts", - "./vs/workbench/services/configuration/common/configurationModels.ts", - "./vs/workbench/services/configuration/common/jsonEditing.ts", "./vs/workbench/services/configuration/node/configuration.ts", "./vs/workbench/services/configuration/node/configurationEditingService.ts", + "./vs/workbench/services/configuration/node/configurationService.ts", "./vs/workbench/services/configuration/node/jsonEditingService.ts", "./vs/workbench/services/configuration/test/common/configurationModels.test.ts", "./vs/workbench/services/configurationResolver/common/configurationResolver.ts", @@ -461,7 +461,7 @@ "./vs/workbench/services/search/node/ripgrepSearchProvider.ts", "./vs/workbench/services/search/node/ripgrepSearchUtils.ts", "./vs/workbench/services/search/node/ripgrepTextSearchEngine.ts", - "./vs/workbench/services/search/node/search.ts", + "./vs/workbench/services/search/common/search.ts", "./vs/workbench/services/search/node/searchApp.ts", "./vs/workbench/services/search/node/searchIpc.ts", "./vs/workbench/services/search/node/textSearchAdapter.ts", @@ -476,7 +476,7 @@ "./vs/workbench/services/search/test/node/textSearchManager.test.ts", "./vs/workbench/services/textMate/common/TMHelper.ts", "./vs/workbench/services/textMate/common/textMateService.ts", - "./vs/workbench/services/textMate/electron-browser/TMGrammars.ts", + "./vs/workbench/services/textMate/common/TMGrammars.ts", "./vs/workbench/services/textMate/electron-browser/textMateService.ts", "./vs/workbench/services/textfile/common/textFileEditorModel.ts", "./vs/workbench/services/textfile/common/textFileEditorModelManager.ts", @@ -508,4 +508,4 @@ "./typings/require-monaco.d.ts", "./vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts" ] -} \ No newline at end of file +} diff --git a/src/typings/electron.d.ts b/src/typings/electron.d.ts index 50fb0d3e4f4..f680249a66f 100644 --- a/src/typings/electron.d.ts +++ b/src/typings/electron.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Electron 3.1.3 +// Type definitions for Electron 3.1.6 // Project: http://electronjs.org/ // Definitions by: The Electron Team // Definitions: https://github.com/electron/electron-typescript-definitions diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index fce8467b9c9..2cafd3932c1 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -428,10 +428,10 @@ export class WindowsManager implements IWindowsMainService { // // These are windows to restore because of hot-exit or from previous session (only performed once on startup!) // - let foldersToRestore; - let workspacesToRestore; + let foldersToRestore: URI[] = []; + let workspacesToRestore: IWorkspacePathToOpen[] = []; if (openConfig.initialStartup && !openConfig.cli.extensionDevelopmentPath && !openConfig.cli['disable-restore-windows']) { - foldersToRestore = this.backupMainService.getFolderBackupPaths(); + let foldersToRestore = this.backupMainService.getFolderBackupPaths(); foldersToAdd.push(...foldersToRestore.map(f => ({ folderUri: f, remoteAuhority: getRemoteAuthority(f), isRestored: true }))); // collect from workspaces with hot-exit backups and from previous window session @@ -469,7 +469,7 @@ export class WindowsManager implements IWindowsMainService { const usedWindow = usedWindows[i]; if ( (usedWindow.openedWorkspace && workspacesToRestore.some(workspace => workspace.workspace.id === usedWindow.openedWorkspace!.id)) || // skip over restored workspace - (usedWindow.openedFolderUri && foldersToRestore.some(folder => isEqual(folder.folderUri, usedWindow.openedFolderUri))) || // skip over restored folder + (usedWindow.openedFolderUri && foldersToRestore.some(uri => isEqual(uri, usedWindow.openedFolderUri))) || // skip over restored folder (usedWindow.backupPath && emptyToRestore.some(empty => empty.backupFolder === basename(usedWindow.backupPath!))) // skip over restored empty window ) { continue; @@ -691,8 +691,9 @@ export class WindowsManager implements IWindowsMainService { } // Handle empty to restore - if (emptyToRestore.length > 0) { - emptyToRestore.forEach(emptyWindowBackupInfo => { + const allEmptyToRestore = arrays.distinct(emptyToRestore, info => info.backupFolder); // prevent duplicates + if (allEmptyToRestore.length > 0) { + allEmptyToRestore.forEach(emptyWindowBackupInfo => { const remoteAuthority = emptyWindowBackupInfo.remoteAuthority; const fileInputsForWindow = (fileInputs && fileInputs.remoteAuthority === remoteAuthority) ? fileInputs : undefined; diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index 587ffb1fd09..4ecc73effdf 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -11,6 +11,7 @@ import { URI } from 'vs/base/common/uri'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { equalsIgnoreCase } from 'vs/base/common/strings'; export class OpenerService implements IOpenerService { @@ -30,13 +31,14 @@ export class OpenerService implements IOpenerService { if (!scheme) { // no scheme ?!? return Promise.resolve(false); + } - } else if (scheme === Schemas.http || scheme === Schemas.https || scheme === Schemas.mailto) { + if (equalsIgnoreCase(scheme, Schemas.http) || equalsIgnoreCase(scheme, Schemas.https) || equalsIgnoreCase(scheme, Schemas.mailto)) { // open http or default mail application dom.windowOpenNoOpener(resource.toString(true)); return Promise.resolve(true); - } else if (scheme === Schemas.command) { + } else if (equalsIgnoreCase(scheme, Schemas.command)) { // run command or bail out if command isn't known if (!CommandsRegistry.getCommand(path)) { return Promise.reject(`command '${path}' NOT known`); diff --git a/src/vs/platform/configuration/common/configurationModels.ts b/src/vs/platform/configuration/common/configurationModels.ts index cce51ce4880..6628e6a8823 100644 --- a/src/vs/platform/configuration/common/configurationModels.ts +++ b/src/vs/platform/configuration/common/configurationModels.ts @@ -485,7 +485,7 @@ export class Configuration { }; } - allKeys(workspace: Workspace): string[] { + allKeys(workspace: Workspace | undefined): string[] { let keys = this.keys(workspace); let all = [...keys.default]; const addKeys = (keys) => { diff --git a/src/vs/platform/localizations/node/localizations.ts b/src/vs/platform/localizations/node/localizations.ts index ac7cafcbb5c..9467d8a6282 100644 --- a/src/vs/platform/localizations/node/localizations.ts +++ b/src/vs/platform/localizations/node/localizations.ts @@ -93,6 +93,7 @@ class LanguagePacksCache extends Disposable { private languagePacks: { [language: string]: ILanguagePack } = {}; private languagePacksFilePath: string; private languagePacksFileLimiter: Queue; + private initializedCache: boolean; constructor( @IEnvironmentService environmentService: IEnvironmentService, @@ -105,7 +106,7 @@ class LanguagePacksCache extends Disposable { getLanguagePacks(): Promise<{ [language: string]: ILanguagePack }> { // if queue is not empty, fetch from disk - if (this.languagePacksFileLimiter.size) { + if (this.languagePacksFileLimiter.size || !this.initializedCache) { return this.withLanguagePacks() .then(() => this.languagePacks); } @@ -175,6 +176,7 @@ class LanguagePacksCache extends Disposable { } } this.languagePacks = languagePacks; + this.initializedCache = true; const raw = JSON.stringify(this.languagePacks); this.logService.debug('Writing language packs', raw); return pfs.writeFile(this.languagePacksFilePath, raw); diff --git a/src/vs/platform/request/node/request.ts b/src/vs/platform/request/node/request.ts index 8602bb0357c..c8145bca837 100644 --- a/src/vs/platform/request/node/request.ts +++ b/src/vs/platform/request/node/request.ts @@ -58,6 +58,11 @@ Registry.as(Extensions.Configuration) ], default: 'override', description: localize('proxySupport', "Use the proxy support for extensions.") + }, + 'http.systemCertificates': { + type: 'boolean', + default: true, + description: localize('systemCertificates', "Controls whether CA certificates should be loaded from the OS.") } } }); diff --git a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts index fe7631d0a0e..f61a76d2404 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts @@ -285,6 +285,12 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb // dto helpers + public $sessionCached(sessionID: string) { + // remember that the EH has cached the session and we do not have to send it again + this._sessions.add(sessionID); + } + + getSessionDto(session: undefined): undefined; getSessionDto(session: IDebugSession): IDebugSessionDto; getSessionDto(session: IDebugSession | undefined): IDebugSessionDto | undefined; @@ -294,7 +300,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb if (this._sessions.has(sessionID)) { return sessionID; } else { - this._sessions.add(sessionID); + // this._sessions.add(sessionID); // #69534: see $sessionCached above return { id: sessionID, type: session.configuration.type, diff --git a/src/vs/workbench/api/node/apiCommands.ts b/src/vs/workbench/api/node/apiCommands.ts index fabd2cb70d1..93e4aa8ac41 100644 --- a/src/vs/workbench/api/node/apiCommands.ts +++ b/src/vs/workbench/api/node/apiCommands.ts @@ -11,7 +11,7 @@ import { ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { EditorViewColumn } from 'vs/workbench/api/shared/editor'; import { EditorGroupLayout } from 'vs/workbench/services/editor/common/editorGroupsService'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { IWindowsService } from 'vs/platform/windows/common/windows'; +import { IWindowsService, IOpenSettings } from 'vs/platform/windows/common/windows'; import { IDownloadService } from 'vs/platform/download/common/download'; // ----------------------------------------------------------------- @@ -31,32 +31,39 @@ function adjustHandler(handler: (executor: ICommandsExecutor, ...args: any[]) => }; } +interface IOpenFolderAPICommandOptions { + forceNewWindow?: boolean; + noRecentEntry?: boolean; +} + export class OpenFolderAPICommand { public static ID = 'vscode.openFolder'; - public static execute(executor: ICommandsExecutor, uri?: URI, forceNewWindow?: ConstrainBoolean): Promise { + public static execute(executor: ICommandsExecutor, uri?: URI, forceNewWindow?: boolean): Promise; + public static execute(executor: ICommandsExecutor, uri?: URI, options?: IOpenFolderAPICommandOptions): Promise; + public static execute(executor: ICommandsExecutor, uri?: URI, arg: boolean | IOpenFolderAPICommandOptions = {}): Promise { + if (typeof arg === 'boolean') { + arg = { forceNewWindow: arg }; + } if (!uri) { - return executor.executeCommand('_files.pickFolderAndOpen', forceNewWindow); + return executor.executeCommand('_files.pickFolderAndOpen', arg.forceNewWindow); + } + const options: IOpenSettings = { forceNewWindow: arg.forceNewWindow }; + if (arg.noRecentEntry) { + options.args = { _: [], 'skip-add-to-recently-opened': true }; } uri = URI.revive(uri); - return executor.executeCommand('_files.windowOpen', { urisToOpen: [{ uri }], forceNewWindow }); + return executor.executeCommand('_files.windowOpen', [{ uri }], options); } } CommandsRegistry.registerCommand({ id: OpenFolderAPICommand.ID, handler: adjustHandler(OpenFolderAPICommand.execute), description: { - description: `Open a folder`, - args: [{ - name: 'uri', - schema: { - 'type': 'string' - } - }, { - name: 'forceNewWindow', - schema: { - 'type': 'boolean' - } - }] + description: 'Open a folder or workspace in the current window or new window depending on the newWindow argument. Note that opening in the same window will shutdown the current extension host process and start a new one on the given folder/workspace unless the newWindow parameter is set to true.', + args: [ + { name: 'uri', description: '(optional) Uri of the folder or workspace file to open. If not provided, a native dialog will ask the user for the folder', constraint: (value: any) => value === undefined || value instanceof URI }, + { name: 'options', description: '(optional) Options. Object with the following properties: `forceNewWindow `: Whether to open the folder/workspace in a new window or the same. Defaults to opening in the same window. `noRecentEntry`: Wheter the opened URI will appear in the \'Open Recent\' list. Defaults to true. Note, for backward compatibility, options can also be of type boolean, representing the `forceNewWindow` setting.', constraint: (value: any) => value === undefined || typeof value === 'object' || typeof value === 'boolean' } + ] } }); diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 2c21e157732..1f1c31c72cc 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -636,6 +636,7 @@ export type DebugSessionUUID = string; export interface MainThreadDebugServiceShape extends IDisposable { $registerDebugTypes(debugTypes: string[]): void; + $sessionCached(sessionID: string): void; $acceptDAMessage(handle: number, message: DebugProtocol.ProtocolMessage): void; $acceptDAError(handle: number, name: string, message: string, stack: string): void; $acceptDAExit(handle: number, code: number, signal: string): void; diff --git a/src/vs/workbench/api/node/extHostApiCommands.ts b/src/vs/workbench/api/node/extHostApiCommands.ts index ffd3502e0b7..af855784aff 100644 --- a/src/vs/workbench/api/node/extHostApiCommands.ts +++ b/src/vs/workbench/api/node/extHostApiCommands.ts @@ -223,7 +223,7 @@ export class ExtHostApiCommands { description: 'Open a folder or workspace in the current window or new window depending on the newWindow argument. Note that opening in the same window will shutdown the current extension host process and start a new one on the given folder/workspace unless the newWindow parameter is set to true.', args: [ { name: 'uri', description: '(optional) Uri of the folder or workspace file to open. If not provided, a native dialog will ask the user for the folder', constraint: (value: any) => value === undefined || value instanceof URI }, - { name: 'newWindow', description: '(optional) Whether to open the folder/workspace in a new window or the same. Defaults to opening in the same window.', constraint: (value: any) => value === undefined || typeof value === 'boolean' } + { name: 'options', description: '(optional) Options. Object with the following properties: `forceNewWindow `: Whether to open the folder/workspace in a new window or the same. Defaults to opening in the same window. `noRecentEntry`: Wheter the opened URI will appear in the \'Open Recent\' list. Defaults to true. Note, for backward compatibility, options can also be of type boolean, representing the `forceNewWindow` setting.', constraint: (value: any) => value === undefined || typeof value === 'object' || typeof value === 'boolean' } ] }); diff --git a/src/vs/workbench/api/node/extHostCLIServer.ts b/src/vs/workbench/api/node/extHostCLIServer.ts index a2311b7f69e..fa7a9b70747 100644 --- a/src/vs/workbench/api/node/extHostCLIServer.ts +++ b/src/vs/workbench/api/node/extHostCLIServer.ts @@ -85,7 +85,7 @@ export class CLIServer { if (!forceReuseWindow && urisToOpen.some(o => o.typeHint === 'folder' || (o.typeHint === 'file' && hasWorkspaceFileExtension(o.uri.path)))) { forceNewWindow = true; } - this._commands.executeCommand('_files.windowOpen', { urisToOpen, forceNewWindow, diffMode, addMode, forceReuseWindow }); + this._commands.executeCommand('_files.windowOpen', urisToOpen, { forceNewWindow, diffMode, addMode, forceReuseWindow }); } res.writeHead(200); res.end(); diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index 880a550dab4..1ffffaaa231 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -794,19 +794,23 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { if (typeof dto === 'string') { return this._debugSessions.get(dto); } else { - const folder = await this.getFolder(dto.folderUri); - const debugSession = new ExtHostDebugSession(this._debugServiceProxy, dto.id, dto.type, dto.name, folder, dto.configuration); - this._debugSessions.set(debugSession.id, debugSession); - return debugSession; + let ds = this._debugSessions.get(dto.id); + if (!ds) { + const folder = await this.getFolder(dto.folderUri); + ds = new ExtHostDebugSession(this._debugServiceProxy, dto.id, dto.type, dto.name, folder, dto.configuration); + this._debugSessions.set(ds.id, ds); + this._debugServiceProxy.$sessionCached(ds.id); + } + return ds; } } return undefined; } - private async getFolder(_folderUri: UriComponents | undefined): Promise { + private getFolder(_folderUri: UriComponents | undefined): Promise { if (_folderUri) { const folderURI = URI.revive(_folderUri); - return await this._workspaceService.resolveWorkspaceFolder(folderURI); + return this._workspaceService.resolveWorkspaceFolder(folderURI); } return undefined; } diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index 2bd7af71847..84082ef037d 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -8,12 +8,11 @@ import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { URI, UriComponents } from 'vs/base/common/uri'; import * as extfs from 'vs/base/node/extfs'; import { ILogService } from 'vs/platform/log/common/log'; -import { IFileQuery, IFolderQuery, IRawFileQuery, IRawQuery, IRawTextQuery, ISearchCompleteStats, ITextQuery } from 'vs/workbench/services/search/common/search'; +import { IFileQuery, IFolderQuery, IRawFileQuery, IRawQuery, IRawTextQuery, ISearchCompleteStats, ITextQuery, isSerializedFileMatch } from 'vs/workbench/services/search/common/search'; import { FileSearchManager } from 'vs/workbench/services/search/node/fileSearchManager'; import { SearchService } from 'vs/workbench/services/search/node/rawSearchService'; import { RipgrepSearchProvider } from 'vs/workbench/services/search/node/ripgrepSearchProvider'; import { OutputChannel } from 'vs/workbench/services/search/node/ripgrepSearchUtils'; -import { isSerializedFileMatch } from 'vs/workbench/services/search/node/search'; import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager'; import * as vscode from 'vscode'; import { ExtHostSearchShape, IMainContext, MainContext, MainThreadSearchShape } from './extHost.protocol'; diff --git a/src/vs/workbench/browser/actions/workspaceCommands.ts b/src/vs/workbench/browser/actions/workspaceCommands.ts index c9843ad60c7..f30677babbe 100644 --- a/src/vs/workbench/browser/actions/workspaceCommands.ts +++ b/src/vs/workbench/browser/actions/workspaceCommands.ts @@ -34,7 +34,7 @@ CommandsRegistry.registerCommand({ CommandsRegistry.registerCommand({ id: '_files.pickFolderAndOpen', - handler: (accessor: ServicesAccessor, forceNewWindow: boolean) => accessor.get(IFileDialogService).pickFolderAndOpen({ forceNewWindow }) + handler: (accessor: ServicesAccessor, options: { forceNewWindow: boolean }) => accessor.get(IFileDialogService).pickFolderAndOpen(options) }); CommandsRegistry.registerCommand({ diff --git a/src/vs/workbench/contrib/debug/common/debugModel.ts b/src/vs/workbench/contrib/debug/common/debugModel.ts index 039d7200591..e63883be5b5 100644 --- a/src/vs/workbench/contrib/debug/common/debugModel.ts +++ b/src/vs/workbench/contrib/debug/common/debugModel.ts @@ -916,7 +916,7 @@ export class DebugModel implements IDebugModel { } addBreakpoints(uri: uri, rawData: IBreakpointData[], fireEvent = true): IBreakpoint[] { - const newBreakpoints = rawData.map(rawBp => new Breakpoint(uri, rawBp.lineNumber, rawBp.column, !!rawBp.enabled, rawBp.condition, rawBp.hitCondition, rawBp.logMessage, undefined, this.textFileService, rawBp.id)); + const newBreakpoints = rawData.map(rawBp => new Breakpoint(uri, rawBp.lineNumber, rawBp.column, rawBp.enabled === false ? false : true, rawBp.condition, rawBp.hitCondition, rawBp.logMessage, undefined, this.textFileService, rawBp.id)); newBreakpoints.forEach(bp => bp.setSessionId(this.breakpointsSessionId)); this.breakpoints = this.breakpoints.concat(newBreakpoints); this.breakpointsActivated = true; diff --git a/src/vs/workbench/contrib/debug/electron-browser/watchExpressionsView.ts b/src/vs/workbench/contrib/debug/electron-browser/watchExpressionsView.ts index 4cc548d6a97..52a74b89bad 100644 --- a/src/vs/workbench/contrib/debug/electron-browser/watchExpressionsView.ts +++ b/src/vs/workbench/contrib/debug/electron-browser/watchExpressionsView.ts @@ -141,6 +141,10 @@ export class WatchExpressionsView extends ViewletPanel { private onContextMenu(e: ITreeContextMenuEvent): void { const element = e.element; + const anchor = e.anchor; + if (!anchor) { + return; + } const actions: IAction[] = []; if (element instanceof Expression) { @@ -167,7 +171,7 @@ export class WatchExpressionsView extends ViewletPanel { } this.contextMenuService.showContextMenu({ - getAnchor: () => e.anchor, + getAnchor: () => anchor, getActions: () => actions, getActionsContext: () => element }); @@ -184,11 +188,9 @@ class WatchExpressionsDelegate implements IListVirtualDelegate { if (element instanceof Expression) { return WatchExpressionsRenderer.ID; } - if (element instanceof Variable) { - return VariablesRenderer.ID; - } - return undefined; + // Variable + return VariablesRenderer.ID; } } @@ -198,7 +200,7 @@ function isDebugService(element: any): element is IDebugService { class WatchExpressionsDataSource implements IAsyncDataSource { - hasChildren(element: IExpression | null): boolean { + hasChildren(element: IExpression | IDebugService): boolean { return isDebugService(element) || element.hasChildren; } @@ -208,7 +210,7 @@ class WatchExpressionsDataSource implements IAsyncDataSource !!we.name - ? we.evaluate(viewModel.focusedSession, viewModel.focusedStackFrame, 'watch').then(() => we) + ? we.evaluate(viewModel.focusedSession!, viewModel.focusedStackFrame!, 'watch').then(() => we) : Promise.resolve(we))); } @@ -258,11 +260,9 @@ class WatchExpressionsAccessibilityProvider implements IAccessibilityProviderelement).name, (element).value); } - if (element instanceof Variable) { - return nls.localize('watchVariableAriaLabel', "{0} value {1}, watch, debug", (element).name, (element).value); - } - return null; + // Variable + return nls.localize('watchVariableAriaLabel', "{0} value {1}, watch, debug", (element).name, (element).value); } } diff --git a/src/vs/workbench/contrib/emmet/electron-browser/actions/expandAbbreviation.ts b/src/vs/workbench/contrib/emmet/browser/actions/expandAbbreviation.ts similarity index 94% rename from src/vs/workbench/contrib/emmet/electron-browser/actions/expandAbbreviation.ts rename to src/vs/workbench/contrib/emmet/browser/actions/expandAbbreviation.ts index 72c5ed4a9c4..18aa8533f44 100644 --- a/src/vs/workbench/contrib/emmet/electron-browser/actions/expandAbbreviation.ts +++ b/src/vs/workbench/contrib/emmet/browser/actions/expandAbbreviation.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import { EmmetEditorAction } from 'vs/workbench/contrib/emmet/electron-browser/emmetActions'; +import { EmmetEditorAction } from 'vs/workbench/contrib/emmet/browser/emmetActions'; import { registerEditorAction } from 'vs/editor/browser/editorExtensions'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { KeyCode } from 'vs/base/common/keyCodes'; diff --git a/src/vs/workbench/contrib/emmet/browser/emmet.browser.contribution.ts b/src/vs/workbench/contrib/emmet/browser/emmet.browser.contribution.ts deleted file mode 100644 index e6aa9d4055b..00000000000 --- a/src/vs/workbench/contrib/emmet/browser/emmet.browser.contribution.ts +++ /dev/null @@ -1,6 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import './actions/showEmmetCommands'; diff --git a/src/vs/workbench/contrib/emmet/electron-browser/emmet.contribution.ts b/src/vs/workbench/contrib/emmet/browser/emmet.contribution.ts similarity index 91% rename from src/vs/workbench/contrib/emmet/electron-browser/emmet.contribution.ts rename to src/vs/workbench/contrib/emmet/browser/emmet.contribution.ts index f29d6b2c022..b603e987b29 100644 --- a/src/vs/workbench/contrib/emmet/electron-browser/emmet.contribution.ts +++ b/src/vs/workbench/contrib/emmet/browser/emmet.contribution.ts @@ -3,5 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import './actions/showEmmetCommands'; import './actions/expandAbbreviation'; diff --git a/src/vs/workbench/contrib/emmet/electron-browser/emmetActions.ts b/src/vs/workbench/contrib/emmet/browser/emmetActions.ts similarity index 98% rename from src/vs/workbench/contrib/emmet/electron-browser/emmetActions.ts rename to src/vs/workbench/contrib/emmet/browser/emmetActions.ts index 8c83a335415..607da869cc3 100644 --- a/src/vs/workbench/contrib/emmet/electron-browser/emmetActions.ts +++ b/src/vs/workbench/contrib/emmet/browser/emmetActions.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { EditorAction, ServicesAccessor, IActionOptions } from 'vs/editor/browser/editorExtensions'; -import { grammarsExtPoint, ITMSyntaxExtensionPoint } from 'vs/workbench/services/textMate/electron-browser/TMGrammars'; +import { grammarsExtPoint, ITMSyntaxExtensionPoint } from 'vs/workbench/services/textMate/common/TMGrammars'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IExtensionService, ExtensionPointContribution } from 'vs/workbench/services/extensions/common/extensions'; import { ICommandService } from 'vs/platform/commands/common/commands'; diff --git a/src/vs/workbench/contrib/emmet/test/electron-browser/emmetAction.test.ts b/src/vs/workbench/contrib/emmet/test/browser/emmetAction.test.ts similarity index 97% rename from src/vs/workbench/contrib/emmet/test/electron-browser/emmetAction.test.ts rename to src/vs/workbench/contrib/emmet/test/browser/emmetAction.test.ts index 7aefb85575b..8e32b760063 100644 --- a/src/vs/workbench/contrib/emmet/test/electron-browser/emmetAction.test.ts +++ b/src/vs/workbench/contrib/emmet/test/browser/emmetAction.test.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IGrammarContributions, ILanguageIdentifierResolver, EmmetEditorAction } from 'vs/workbench/contrib/emmet/electron-browser/emmetActions'; +import { IGrammarContributions, ILanguageIdentifierResolver, EmmetEditorAction } from 'vs/workbench/contrib/emmet/browser/emmetActions'; import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; import * as assert from 'assert'; import { LanguageId, LanguageIdentifier } from 'vs/editor/common/modes'; diff --git a/src/vs/workbench/contrib/files/browser/fileCommands.ts b/src/vs/workbench/contrib/files/browser/fileCommands.ts index 94504bb9958..996b2094926 100644 --- a/src/vs/workbench/contrib/files/browser/fileCommands.ts +++ b/src/vs/workbench/contrib/files/browser/fileCommands.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { URI } from 'vs/base/common/uri'; import { toResource, IEditorCommandsContext } from 'vs/workbench/common/editor'; -import { IWindowsService, IWindowService, IURIToOpen } from 'vs/platform/windows/common/windows'; +import { IWindowsService, IWindowService, IURIToOpen, IOpenSettings } from 'vs/platform/windows/common/windows'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -76,13 +76,10 @@ export const ResourceSelectedForCompareContext = new RawContextKey('res export const REMOVE_ROOT_FOLDER_COMMAND_ID = 'removeRootFolder'; export const REMOVE_ROOT_FOLDER_LABEL = nls.localize('removeFolderFromWorkspace', "Remove Folder from Workspace"); -export const openWindowCommand = (accessor: ServicesAccessor, input: Array | { urisToOpen: IURIToOpen[], forceNewWindow: boolean, forceReuseWindow?: boolean, diffMode?: boolean, addMode?: boolean }, forceNewWindow: boolean) => { - const windowService = accessor.get(IWindowService); - - if (Array.isArray(input)) { - windowService.openWindow(input.map(p => ({ uri: typeof p === 'string' ? URI.file(p) : p }), { forceNewWindow })); - } else if (input) { - windowService.openWindow(input.urisToOpen, { forceNewWindow: input.forceNewWindow, diffMode: input.diffMode, addMode: input.addMode, forceReuseWindow: input.forceReuseWindow }); +export const openWindowCommand = (accessor: ServicesAccessor, urisToOpen: IURIToOpen[], options?: IOpenSettings) => { + if (Array.isArray(urisToOpen)) { + const windowService = accessor.get(IWindowService); + windowService.openWindow(urisToOpen, options); } }; diff --git a/src/vs/workbench/contrib/search/common/queryBuilder.ts b/src/vs/workbench/contrib/search/common/queryBuilder.ts index c1e525e22a8..f4d479fa1f2 100644 --- a/src/vs/workbench/contrib/search/common/queryBuilder.ts +++ b/src/vs/workbench/contrib/search/common/queryBuilder.ts @@ -332,7 +332,7 @@ export class QueryBuilder { searchPath = normalizeSlashes(searchPath); if (strings.startsWith(searchPath, '../')) { - const resolvedPath = path.resolve(workspaceUri.path, searchPath); + const resolvedPath = path.posix.resolve(workspaceUri.path, searchPath); return [{ searchPath: workspaceUri.with({ path: resolvedPath }) }]; diff --git a/src/vs/workbench/contrib/search/test/common/queryBuilder.test.ts b/src/vs/workbench/contrib/search/test/common/queryBuilder.test.ts index 77279512b17..5eec2e0c82d 100644 --- a/src/vs/workbench/contrib/search/test/common/queryBuilder.test.ts +++ b/src/vs/workbench/contrib/search/test/common/queryBuilder.test.ts @@ -659,22 +659,22 @@ suite('QueryBuilder', () => { }] } ], - // [ - // '../', - // { - // searchPaths: [{ - // searchPath: getUri('/foo') - // }] - // } - // ], - // [ - // '..\\bar', - // { - // searchPaths: [{ - // searchPath: getUri('/foo/bar') - // }] - // } - // ] + [ + '../', + { + searchPaths: [{ + searchPath: getUri('/foo') + }] + } + ], + [ + '..\\bar', + { + searchPaths: [{ + searchPath: getUri('/foo/bar') + }] + } + ] ]; cases.forEach(testIncludesDataItem); }); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index b8ef5a55e61..78b84ba1935 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -577,10 +577,6 @@ export class TerminalInstance implements ITerminalInstance { if (this._processManager) { this._widgetManager = new TerminalWidgetManager(this._wrapperElement); - // HACK: This can be removed once this is fixed upstream xtermjs/xterm.js#1908 - this._disposables.push(dom.addDisposableListener(this._xterm.element, 'mouseleave', () => { - this._widgetManager.closeMessage(); - })); this._linkHandler.setWidgetManager(this._widgetManager); } diff --git a/src/vs/workbench/services/configuration/common/configurationModels.ts b/src/vs/workbench/services/configuration/common/configurationModels.ts index 92a3834f1d9..6644ee75e04 100644 --- a/src/vs/workbench/services/configuration/common/configurationModels.ts +++ b/src/vs/workbench/services/configuration/common/configurationModels.ts @@ -136,11 +136,11 @@ export class Configuration extends BaseConfiguration { folders: ResourceMap, memoryConfiguration: ConfigurationModel, memoryConfigurationByResource: ResourceMap, - private readonly _workspace: Workspace) { + private readonly _workspace?: Workspace) { super(defaults, user, workspaceConfiguration, folders, memoryConfiguration, memoryConfigurationByResource); } - getValue(key: string, overrides: IConfigurationOverrides = {}): any { + getValue(key: string | undefined, overrides: IConfigurationOverrides = {}): any { return super.getValue(key, overrides, this._workspace); } diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index 61a17082dca..d7949b7b5b8 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -108,7 +108,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic return WorkbenchState.EMPTY; } - public getWorkspaceFolder(resource: URI): IWorkspaceFolder { + public getWorkspaceFolder(resource: URI): IWorkspaceFolder | null { return this.workspace.getFolder(resource); } @@ -152,7 +152,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic // Remove first (if any) let currentWorkspaceFolders = this.getWorkspace().folders; - let newStoredFolders: IStoredWorkspaceFolder[] = currentWorkspaceFolders.map(f => f.raw).filter((folder, index) => { + let newStoredFolders: IStoredWorkspaceFolder[] = currentWorkspaceFolders.map(f => f.raw).filter((folder, index): folder is IStoredWorkspaceFolder => { if (!isStoredWorkspaceFolder(folder)) { return true; // keep entries which are unrelated } @@ -168,7 +168,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic if (foldersToAdd.length) { // Recompute current workspace folders if we have folders to add - const workspaceConfigFolder = dirname(this.getWorkspace().configuration); + const workspaceConfigFolder = dirname(this.getWorkspace().configuration!); currentWorkspaceFolders = toWorkspaceFolders(newStoredFolders, workspaceConfigFolder); const currentWorkspaceFolderUris = currentWorkspaceFolders.map(folder => folder.uri); @@ -246,7 +246,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic const overrides = isConfigurationOverrides(arg3) ? arg3 : undefined; const target = this.deriveConfigurationTarget(key, value, overrides, overrides ? arg4 : arg3); return target ? this.writeConfigurationValue(key, value, target, overrides, donotNotifyError) - : Promise.resolve(null); + : Promise.resolve(); } reloadConfiguration(folder?: IWorkspaceFolder, key?: string): Promise { @@ -332,7 +332,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic const workspaceFolders = toWorkspaceFolders(this.workspaceConfiguration.getFolders(), dirname(workspaceConfigPath)); const workspaceId = workspaceIdentifier.id; const workspace = new Workspace(workspaceId, workspaceFolders, workspaceConfigPath); - if (workspace.configuration.scheme === Schemas.file) { + if (workspace.configuration!.scheme === Schemas.file) { this.releaseWorkspaceBarrier(); // Release barrier as workspace is complete because it is from disk. } return workspace; @@ -369,7 +369,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic private updateWorkspaceAndInitializeConfiguration(workspace: Workspace, postInitialisationTask: () => void): Promise { const hasWorkspaceBefore = !!this.workspace; let previousState: WorkbenchState; - let previousWorkspacePath: string; + let previousWorkspacePath: string | undefined; let previousFolders: WorkspaceFolder[]; if (hasWorkspaceBefore) { @@ -461,7 +461,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic folderConfigurations.forEach((folderConfiguration, index) => folderConfigurationModels.set(folders[index].uri, folderConfiguration)); const currentConfiguration = this._configuration; - this._configuration = new Configuration(this.defaultConfiguration, userConfigurationModel, workspaceConfiguration, folderConfigurationModels, new ConfigurationModel(), new ResourceMap(), this.getWorkbenchState() !== WorkbenchState.EMPTY ? this.workspace : null); //TODO: Sandy Avoid passing null + this._configuration = new Configuration(this.defaultConfiguration, userConfigurationModel, workspaceConfiguration, folderConfigurationModels, new ConfigurationModel(), new ResourceMap(), this.workspace); if (currentConfiguration) { const changedKeys = this._configuration.compare(currentConfiguration); @@ -489,10 +489,10 @@ export class WorkspaceService extends Disposable implements IConfigurationServic if (this.workspace && this._configuration) { this._configuration.updateDefaultConfiguration(this.defaultConfiguration); if (this.getWorkbenchState() === WorkbenchState.FOLDER) { - this._configuration.updateWorkspaceConfiguration(this.cachedFolderConfigs.get(this.workspace.folders[0].uri).reprocess()); + this._configuration.updateWorkspaceConfiguration(this.cachedFolderConfigs.get(this.workspace.folders[0].uri)!.reprocess()); } else { this._configuration.updateWorkspaceConfiguration(this.workspaceConfiguration.reprocessWorkspaceSettings()); - this.workspace.folders.forEach(folder => this._configuration.updateFolderConfiguration(folder.uri, this.cachedFolderConfigs.get(folder.uri).reprocess())); + this.workspace.folders.forEach(folder => this._configuration.updateFolderConfiguration(folder.uri, this.cachedFolderConfigs.get(folder.uri)!.reprocess())); } this.triggerConfigurationChange(new ConfigurationChangeEvent().change(keys), ConfigurationTarget.DEFAULT); } @@ -572,7 +572,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic for (const key of this.cachedFolderConfigs.keys()) { if (!this.workspace.folders.filter(folder => folder.uri.toString() === key.toString())[0]) { const folderConfiguration = this.cachedFolderConfigs.get(key); - folderConfiguration.dispose(); + folderConfiguration!.dispose(); this.cachedFolderConfigs.delete(key); changeEvent = changeEvent.change(this._configuration.compareAndDeleteFolderConfiguration(key)); } @@ -610,7 +610,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic if (target === ConfigurationTarget.MEMORY) { this._configuration.updateValue(key, value, overrides); - this.triggerConfigurationChange(new ConfigurationChangeEvent().change(overrides && overrides.overrideIdentifier ? [keyFromOverrideIdentifier(overrides.overrideIdentifier)] : [key], overrides && overrides.resource), target); + this.triggerConfigurationChange(new ConfigurationChangeEvent().change(overrides && overrides.overrideIdentifier ? [keyFromOverrideIdentifier(overrides.overrideIdentifier)] : [key], overrides && overrides.resource || undefined), target); return Promise.resolve(undefined); } @@ -618,20 +618,20 @@ export class WorkspaceService extends Disposable implements IConfigurationServic .then(() => { switch (target) { case ConfigurationTarget.USER: - return this.reloadUserConfiguration(); + return this.reloadUserConfiguration().then(_ => Promise.resolve()); case ConfigurationTarget.WORKSPACE: return this.reloadWorkspaceConfiguration(); case ConfigurationTarget.WORKSPACE_FOLDER: const workspaceFolder = overrides && overrides.resource ? this.workspace.getFolder(overrides.resource) : null; if (workspaceFolder) { - return this.reloadWorkspaceFolderConfiguration(this.workspace.getFolder(overrides.resource), key).then(() => null); + return this.reloadWorkspaceFolderConfiguration(workspaceFolder, key); } } - return null; + return Promise.resolve(); }); } - private deriveConfigurationTarget(key: string, value: any, overrides: IConfigurationOverrides, target: ConfigurationTarget): ConfigurationTarget { + private deriveConfigurationTarget(key: string, value: any, overrides: IConfigurationOverrides | undefined, target: ConfigurationTarget): ConfigurationTarget | undefined { if (target) { return target; } @@ -682,7 +682,7 @@ interface IExportedConfigurationNode { name: string; description: string; default: any; - type: string | string[]; + type?: string | string[]; enum?: any[]; enumDescriptions?: string[]; } @@ -690,8 +690,8 @@ interface IExportedConfigurationNode { interface IConfigurationExport { settings: IExportedConfigurationNode[]; buildTime: number; - commit: string; - buildNumber: number; + commit?: string; + buildNumber?: number; } export class DefaultConfigurationExportHelper { diff --git a/src/vs/workbench/services/extensions/node/proxyResolver.ts b/src/vs/workbench/services/extensions/node/proxyResolver.ts index 1643badcc71..32a6306198a 100644 --- a/src/vs/workbench/services/extensions/node/proxyResolver.ts +++ b/src/vs/workbench/services/extensions/node/proxyResolver.ts @@ -5,7 +5,11 @@ import * as http from 'http'; import * as https from 'https'; +import * as tls from 'tls'; import * as nodeurl from 'url'; +import * as os from 'os'; +import * as fs from 'fs'; +import * as cp from 'child_process'; import { assign } from 'vs/base/common/objects'; import { endsWith } from 'vs/base/common/strings'; @@ -17,6 +21,7 @@ import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; import { URI } from 'vs/base/common/uri'; +import { promisify } from 'util'; interface ConnectionResult { proxy: string; @@ -118,11 +123,23 @@ function setupProxyResolution( results = []; } - function resolveProxy(req: http.ClientRequest, opts: http.RequestOptions, url: string, callback: (proxy?: string) => void) { + function resolveProxy(flags: { useProxySettings: boolean, useSystemCertificates: boolean }, req: http.ClientRequest, opts: http.RequestOptions, url: string, callback: (proxy?: string) => void) { if (!timeout) { timeout = setTimeout(logEvent, 10 * 60 * 1000); } + useSystemCertificates(extHostLogService, flags.useSystemCertificates, opts, () => { + useProxySettings(flags.useProxySettings, req, opts, url, callback); + }); + } + + function useProxySettings(useProxySettings: boolean, req: http.ClientRequest, opts: http.RequestOptions, url: string, callback: (proxy?: string) => void) { + + if (!useProxySettings) { + callback('DIRECT'); + return; + } + const parsedUrl = nodeurl.parse(url); // Coming from Node's URL, sticking with that. const hostname = parsedUrl.hostname; @@ -254,34 +271,43 @@ function noProxyFromEnv(envValue?: string) { } function createPatchedModules(configProvider: ExtHostConfigProvider, resolveProxy: ReturnType) { - const setting = { + const proxySetting = { config: configProvider.getConfiguration('http') .get('proxySupport') || 'off' }; configProvider.onDidChangeConfiguration(e => { - setting.config = configProvider.getConfiguration('http') + proxySetting.config = configProvider.getConfiguration('http') .get('proxySupport') || 'off'; }); + const certSetting = { + config: !!configProvider.getConfiguration('http') + .get('systemCertificates') + }; + configProvider.onDidChangeConfiguration(e => { + certSetting.config = !!configProvider.getConfiguration('http') + .get('systemCertificates'); + }); return { http: { - off: assign({}, http, patches(http, resolveProxy, { config: 'off' }, true)), - on: assign({}, http, patches(http, resolveProxy, { config: 'on' }, true)), - override: assign({}, http, patches(http, resolveProxy, { config: 'override' }, true)), - onRequest: assign({}, http, patches(http, resolveProxy, setting, true)), - default: assign(http, patches(http, resolveProxy, setting, false)) // run last + off: assign({}, http, patches(http, resolveProxy, { config: 'off' }, certSetting, true)), + on: assign({}, http, patches(http, resolveProxy, { config: 'on' }, certSetting, true)), + override: assign({}, http, patches(http, resolveProxy, { config: 'override' }, certSetting, true)), + onRequest: assign({}, http, patches(http, resolveProxy, proxySetting, certSetting, true)), + default: assign(http, patches(http, resolveProxy, proxySetting, certSetting, false)) // run last }, https: { - off: assign({}, https, patches(https, resolveProxy, { config: 'off' }, true)), - on: assign({}, https, patches(https, resolveProxy, { config: 'on' }, true)), - override: assign({}, https, patches(https, resolveProxy, { config: 'override' }, true)), - onRequest: assign({}, https, patches(https, resolveProxy, setting, true)), - default: assign(https, patches(https, resolveProxy, setting, false)) // run last - } + off: assign({}, https, patches(https, resolveProxy, { config: 'off' }, certSetting, true)), + on: assign({}, https, patches(https, resolveProxy, { config: 'on' }, certSetting, true)), + override: assign({}, https, patches(https, resolveProxy, { config: 'override' }, certSetting, true)), + onRequest: assign({}, https, patches(https, resolveProxy, proxySetting, certSetting, true)), + default: assign(https, patches(https, resolveProxy, proxySetting, certSetting, false)) // run last + }, + tls: assign(tls, tlsPatches(tls)) }; } -function patches(originals: typeof http | typeof https, resolveProxy: ReturnType, setting: { config: string; }, onRequest: boolean) { +function patches(originals: typeof http | typeof https, resolveProxy: ReturnType, proxySetting: { config: string }, certSetting: { config: boolean }, onRequest: boolean) { return { get: patch(originals.get), request: patch(originals.request) @@ -300,12 +326,15 @@ function patches(originals: typeof http | typeof https, resolveProxy: ReturnType } options = options || {}; - const config = onRequest && ((options)._vscodeProxySupport || /* LS */ (options)._vscodeSystemProxy) || setting.config; - if (config === 'off') { + if (options.socketPath) { return original.apply(null, arguments as unknown as any[]); } - if (!options.socketPath && (config === 'override' || config === 'on' && !options.agent) && !(options.agent instanceof ProxyAgent)) { + const config = onRequest && ((options)._vscodeProxySupport || /* LS */ (options)._vscodeSystemProxy) || proxySetting.config; + const useProxySettings = (config === 'override' || config === 'on' && !options.agent) && !(options.agent instanceof ProxyAgent); + const useSystemCertificates = certSetting.config && originals === https && !(options as https.RequestOptions).ca; + + if (useProxySettings || useSystemCertificates) { if (url) { const parsed = typeof url === 'string' ? new nodeurl.URL(url) : url; const urlOptions = { @@ -322,7 +351,7 @@ function patches(originals: typeof http | typeof https, resolveProxy: ReturnType options = { ...options }; } options.agent = new ProxyAgent({ - resolveProxy, + resolveProxy: resolveProxy.bind(undefined, { useProxySettings, useSystemCertificates }), defaultPort: originals === https ? 443 : 80, originalAgent: options.agent }); @@ -335,12 +364,35 @@ function patches(originals: typeof http | typeof https, resolveProxy: ReturnType } } +function tlsPatches(originals: typeof tls) { + return { + createSecureContext: patch(originals.createSecureContext) + }; + + function patch(original: typeof tls.createSecureContext): typeof tls.createSecureContext { + return function (details: tls.SecureContextOptions): ReturnType { + const context = original.apply(null, arguments as unknown as any[]); + const certs = (details as any)._vscodeAdditionalCaCerts; + if (certs) { + for (const cert of certs) { + context.context.addCACert(cert); + } + } + return context; + }; + } +} + function configureModuleLoading(extensionService: ExtHostExtensionService, lookup: ReturnType): Promise { return extensionService.getExtensionPathIndex() .then(extensionPaths => { const node_module = require.__$__nodeRequire('module'); const original = node_module._load; node_module._load = function load(request: string, parent: any, isMain: any) { + if (request === 'tls') { + return lookup.tls; + } + if (request !== 'http' && request !== 'https') { return original.apply(this, arguments); } @@ -353,4 +405,120 @@ function configureModuleLoading(extensionService: ExtHostExtensionService, looku return modules.default; }; }); -} \ No newline at end of file +} + +function useSystemCertificates(extHostLogService: ExtHostLogService, useSystemCertificates: boolean, opts: http.RequestOptions, callback: () => void) { + if (useSystemCertificates) { + getCaCertificates(extHostLogService) + .then(caCertificates => { + if (caCertificates) { + if (caCertificates.append) { + (opts as any)._vscodeAdditionalCaCerts = caCertificates.certs; + } else { + (opts as https.RequestOptions).ca = caCertificates.certs; + } + } + callback(); + }) + .catch(err => { + extHostLogService.error('ProxyResolver#useSystemCertificates', toErrorMessage(err)); + }); + } else { + callback(); + } +} + +let _caCertificates: ReturnType | Promise; +async function getCaCertificates(extHostLogService: ExtHostLogService) { + if (!_caCertificates) { + _caCertificates = readCaCertificates() + .then(res => res && res.certs.length ? res : undefined) + .catch(err => { + extHostLogService.error('ProxyResolver#getCertificates', toErrorMessage(err)); + return undefined; + }); + } + return _caCertificates; +} + +async function readCaCertificates() { + if (process.platform === 'win32') { + return readWindowsCaCertificates(); + } + if (process.platform === 'darwin') { + return readMacCaCertificates(); + } + if (process.platform === 'linux') { + return readLinuxCaCertificates(); + } + return undefined; +} + +function readWindowsCaCertificates() { + const winCA = require.__$__nodeRequire('win-ca-lib'); + + let ders = []; + const store = winCA(); + try { + let der; + while (der = store.next()) { + ders.push(der); + } + } finally { + store.done(); + } + + const seen = {}; + const certs = ders.map(derToPem) + .filter(pem => !seen[pem] && (seen[pem] = true)); + return { + certs, + append: true + }; +} + +async function readMacCaCertificates() { + const stdout = (await promisify(cp.execFile)('/usr/bin/security', ['find-certificate', '-a', '-p'], { encoding: 'utf8' })).stdout; + const seen = {}; + const certs = stdout.split(/(?=-----BEGIN CERTIFICATE-----)/g) + .filter(pem => !!pem.length && !seen[pem] && (seen[pem] = true)); + return { + certs, + append: true + }; +} + +const linuxCaCertificatePaths = [ + '/etc/ssl/certs/ca-certificates.crt', + '/etc/ssl/certs/ca-bundle.crt', +]; + +async function readLinuxCaCertificates() { + for (const certPath of linuxCaCertificatePaths) { + try { + const content = await promisify(fs.readFile)(certPath, { encoding: 'utf8' }); + const seen = {}; + const certs = content.split(/(?=-----BEGIN CERTIFICATE-----)/g) + .filter(pem => !!pem.length && !seen[pem] && (seen[pem] = true)); + return { + certs, + append: false + }; + } catch (err) { + if (err.code !== 'ENOENT') { + throw err; + } + } + } + return undefined; +} + +function derToPem(blob) { + const lines = ['-----BEGIN CERTIFICATE-----']; + const der = blob.toString('base64'); + for (let i = 0; i < der.length; i += 64) { + lines.push(der.substr(i, 64)); + } + lines.push('-----END CERTIFICATE-----', ''); + return lines.join(os.EOL); +} diff --git a/src/vs/workbench/services/search/common/search.ts b/src/vs/workbench/services/search/common/search.ts index 580edd70908..f911f942a5d 100644 --- a/src/vs/workbench/services/search/common/search.ts +++ b/src/vs/workbench/services/search/common/search.ts @@ -13,6 +13,8 @@ import { getNLines } from 'vs/base/common/strings'; import { URI, UriComponents } from 'vs/base/common/uri'; import { IFilesConfiguration } from 'vs/platform/files/common/files'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; +import { Event } from 'vs/base/common/event'; export const VIEW_ID = 'workbench.view.search'; @@ -381,3 +383,196 @@ export function serializeSearchError(searchError: SearchError): Error { const details = { message: searchError.message, code: searchError.code }; return new Error(JSON.stringify(details)); } +export interface ITelemetryEvent { + eventName: string; + data: ITelemetryData; +} + +export interface IRawSearchService { + fileSearch(search: IRawFileQuery): Event; + textSearch(search: IRawTextQuery): Event; + clearCache(cacheKey: string): Promise; +} + +export interface IRawFileMatch { + base?: string; + relativePath: string; + basename: string; + size?: number; +} + +export interface ISearchEngine { + search: (onResult: (matches: T) => void, onProgress: (progress: IProgress) => void, done: (error: Error | null, complete: ISearchEngineSuccess) => void) => void; + cancel: () => void; +} + +export interface ISerializedSearchSuccess { + type: 'success'; + limitHit: boolean; + stats: IFileSearchStats | ITextSearchStats | null; +} + +export interface ISearchEngineSuccess { + limitHit: boolean; + stats: ISearchEngineStats; +} + +export interface ISerializedSearchError { + type: 'error'; + error: { + message: string, + stack: string + }; +} + +export type ISerializedSearchComplete = ISerializedSearchSuccess | ISerializedSearchError; + +export function isSerializedSearchComplete(arg: ISerializedSearchProgressItem | ISerializedSearchComplete): arg is ISerializedSearchComplete { + if ((arg as any).type === 'error') { + return true; + } else if ((arg as any).type === 'success') { + return true; + } else { + return false; + } +} + +export function isSerializedSearchSuccess(arg: ISerializedSearchComplete): arg is ISerializedSearchSuccess { + return arg.type === 'success'; +} + +export function isSerializedFileMatch(arg: ISerializedSearchProgressItem): arg is ISerializedFileMatch { + return !!(arg).path; +} + +export interface ISerializedFileMatch { + path?: string; + results?: ITextSearchResult[]; + numMatches?: number; +} + +// Type of the possible values for progress calls from the engine +export type ISerializedSearchProgressItem = ISerializedFileMatch | ISerializedFileMatch[] | IProgress; +export type IFileSearchProgressItem = IRawFileMatch | IRawFileMatch[] | IProgress; + + +export class SerializableFileMatch implements ISerializedFileMatch { + path: string; + results: ITextSearchMatch[]; + + constructor(path: string) { + this.path = path; + this.results = []; + } + + addMatch(match: ITextSearchMatch): void { + this.results.push(match); + } + + serialize(): ISerializedFileMatch { + return { + path: this.path, + results: this.results, + numMatches: this.results.length + }; + } +} + +/** + * Computes the patterns that the provider handles. Discards sibling clauses and 'false' patterns + */ +export function resolvePatternsForProvider(globalPattern: glob.IExpression | undefined, folderPattern: glob.IExpression | undefined): string[] { + const merged = { + ...(globalPattern || {}), + ...(folderPattern || {}) + }; + + return Object.keys(merged) + .filter(key => { + const value = merged[key]; + return typeof value === 'boolean' && value; + }); +} + +export class QueryGlobTester { + + private _excludeExpression: glob.IExpression; + private _parsedExcludeExpression: glob.ParsedExpression; + + private _parsedIncludeExpression: glob.ParsedExpression; + + constructor(config: ISearchQuery, folderQuery: IFolderQuery) { + this._excludeExpression = { + ...(config.excludePattern || {}), + ...(folderQuery.excludePattern || {}) + }; + this._parsedExcludeExpression = glob.parse(this._excludeExpression); + + // Empty includeExpression means include nothing, so no {} shortcuts + let includeExpression: glob.IExpression | undefined = config.includePattern; + if (folderQuery.includePattern) { + if (includeExpression) { + includeExpression = { + ...includeExpression, + ...folderQuery.includePattern + }; + } else { + includeExpression = folderQuery.includePattern; + } + } + + if (includeExpression) { + this._parsedIncludeExpression = glob.parse(includeExpression); + } + } + + /** + * Guaranteed sync - siblingsFn should not return a promise. + */ + includedInQuerySync(testPath: string, basename?: string, hasSibling?: (name: string) => boolean): boolean { + if (this._parsedExcludeExpression && this._parsedExcludeExpression(testPath, basename, hasSibling)) { + return false; + } + + if (this._parsedIncludeExpression && !this._parsedIncludeExpression(testPath, basename, hasSibling)) { + return false; + } + + return true; + } + + /** + * Guaranteed async. + */ + includedInQuery(testPath: string, basename?: string, hasSibling?: (name: string) => boolean | Promise): Promise { + const excludeP = this._parsedExcludeExpression ? + Promise.resolve(this._parsedExcludeExpression(testPath, basename, hasSibling)).then(result => !!result) : + Promise.resolve(false); + + return excludeP.then(excluded => { + if (excluded) { + return false; + } + + return this._parsedIncludeExpression ? + Promise.resolve(this._parsedIncludeExpression(testPath, basename, hasSibling)).then(result => !!result) : + Promise.resolve(true); + }).then(included => { + return included; + }); + } + + hasSiblingExcludeClauses(): boolean { + return hasSiblingClauses(this._excludeExpression); + } +} + +function hasSiblingClauses(pattern: glob.IExpression): boolean { + for (const key in pattern) { + if (typeof pattern[key] !== 'boolean') { + return true; + } + } + + return false; +} diff --git a/src/vs/workbench/services/search/node/fileSearch.ts b/src/vs/workbench/services/search/node/fileSearch.ts index 9d4553aa00e..c9db0fc66ff 100644 --- a/src/vs/workbench/services/search/node/fileSearch.ts +++ b/src/vs/workbench/services/search/node/fileSearch.ts @@ -21,8 +21,7 @@ import * as types from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import * as extfs from 'vs/base/node/extfs'; import * as flow from 'vs/base/node/flow'; -import { IFileQuery, IFolderQuery, IProgress, ISearchEngineStats } from 'vs/workbench/services/search/common/search'; -import { IRawFileMatch, ISearchEngine, ISearchEngineSuccess } from 'vs/workbench/services/search/node/search'; +import { IFileQuery, IFolderQuery, IProgress, ISearchEngineStats, IRawFileMatch, ISearchEngine, ISearchEngineSuccess } from 'vs/workbench/services/search/common/search'; import { spawnRipgrepCmd } from './ripgrepFileSearch'; interface IDirectoryEntry { diff --git a/src/vs/workbench/services/search/node/fileSearchManager.ts b/src/vs/workbench/services/search/node/fileSearchManager.ts index 6ffabf94a20..5f9cc9add44 100644 --- a/src/vs/workbench/services/search/node/fileSearchManager.ts +++ b/src/vs/workbench/services/search/node/fileSearchManager.ts @@ -10,8 +10,7 @@ import * as glob from 'vs/base/common/glob'; import * as resources from 'vs/base/common/resources'; import { StopWatch } from 'vs/base/common/stopwatch'; import { URI } from 'vs/base/common/uri'; -import { IFileMatch, IFileSearchProviderStats, IFolderQuery, ISearchCompleteStats, IFileQuery } from 'vs/workbench/services/search/common/search'; -import { QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/node/search'; +import { IFileMatch, IFileSearchProviderStats, IFolderQuery, ISearchCompleteStats, IFileQuery, QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/common/search'; import * as vscode from 'vscode'; export interface IInternalFileMatch { diff --git a/src/vs/workbench/services/search/node/rawSearchService.ts b/src/vs/workbench/services/search/node/rawSearchService.ts index 436fc42af4f..26a01c678ea 100644 --- a/src/vs/workbench/services/search/node/rawSearchService.ts +++ b/src/vs/workbench/services/search/node/rawSearchService.ts @@ -17,10 +17,9 @@ import * as strings from 'vs/base/common/strings'; import { URI, UriComponents } from 'vs/base/common/uri'; import { compareItemsByScore, IItemAccessor, prepareQuery, ScorerCache } from 'vs/base/parts/quickopen/common/quickOpenScorer'; import { MAX_FILE_SIZE } from 'vs/platform/files/node/files'; -import { ICachedSearchStats, IFileQuery, IFileSearchStats, IFolderQuery, IProgress, IRawFileQuery, IRawQuery, IRawTextQuery, ITextQuery } from 'vs/workbench/services/search/common/search'; +import { ICachedSearchStats, IFileQuery, IFileSearchStats, IFolderQuery, IProgress, IRawFileQuery, IRawQuery, IRawTextQuery, ITextQuery, IFileSearchProgressItem, IRawFileMatch, IRawSearchService, ISearchEngine, ISearchEngineSuccess, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ISerializedSearchSuccess } from 'vs/workbench/services/search/common/search'; import { Engine as FileSearchEngine } from 'vs/workbench/services/search/node/fileSearch'; import { TextSearchEngineAdapter } from 'vs/workbench/services/search/node/textSearchAdapter'; -import { IFileSearchProgressItem, IRawFileMatch, IRawSearchService, ISearchEngine, ISearchEngineSuccess, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ISerializedSearchSuccess } from './search'; gracefulFs.gracefulify(fs); diff --git a/src/vs/workbench/services/search/node/search.ts b/src/vs/workbench/services/search/node/search.ts deleted file mode 100644 index 635c1c1d1b1..00000000000 --- a/src/vs/workbench/services/search/node/search.ts +++ /dev/null @@ -1,203 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Event } from 'vs/base/common/event'; -import * as glob from 'vs/base/common/glob'; -import { IFileSearchStats, IFolderQuery, IProgress, IRawFileQuery, IRawTextQuery, ISearchEngineStats, ISearchQuery, ITextSearchMatch, ITextSearchStats, ITextSearchResult } from 'vs/workbench/services/search/common/search'; -import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; - -export interface ITelemetryEvent { - eventName: string; - data: ITelemetryData; -} - -export interface IRawSearchService { - fileSearch(search: IRawFileQuery): Event; - textSearch(search: IRawTextQuery): Event; - clearCache(cacheKey: string): Promise; -} - -export interface IRawFileMatch { - base?: string; - relativePath: string; - basename: string; - size?: number; -} - -export interface ISearchEngine { - search: (onResult: (matches: T) => void, onProgress: (progress: IProgress) => void, done: (error: Error | null, complete: ISearchEngineSuccess) => void) => void; - cancel: () => void; -} - -export interface ISerializedSearchSuccess { - type: 'success'; - limitHit: boolean; - stats: IFileSearchStats | ITextSearchStats | null; -} - -export interface ISearchEngineSuccess { - limitHit: boolean; - stats: ISearchEngineStats; -} - -export interface ISerializedSearchError { - type: 'error'; - error: { - message: string, - stack: string - }; -} - -export type ISerializedSearchComplete = ISerializedSearchSuccess | ISerializedSearchError; - -export function isSerializedSearchComplete(arg: ISerializedSearchProgressItem | ISerializedSearchComplete): arg is ISerializedSearchComplete { - if ((arg as any).type === 'error') { - return true; - } else if ((arg as any).type === 'success') { - return true; - } else { - return false; - } -} - -export function isSerializedSearchSuccess(arg: ISerializedSearchComplete): arg is ISerializedSearchSuccess { - return arg.type === 'success'; -} - -export function isSerializedFileMatch(arg: ISerializedSearchProgressItem): arg is ISerializedFileMatch { - return !!(arg).path; -} - -export interface ISerializedFileMatch { - path?: string; - results?: ITextSearchResult[]; - numMatches?: number; -} - -// Type of the possible values for progress calls from the engine -export type ISerializedSearchProgressItem = ISerializedFileMatch | ISerializedFileMatch[] | IProgress; -export type IFileSearchProgressItem = IRawFileMatch | IRawFileMatch[] | IProgress; - - -export class FileMatch implements ISerializedFileMatch { - path: string; - results: ITextSearchMatch[]; - - constructor(path: string) { - this.path = path; - this.results = []; - } - - addMatch(match: ITextSearchMatch): void { - this.results.push(match); - } - - serialize(): ISerializedFileMatch { - return { - path: this.path, - results: this.results, - numMatches: this.results.length - }; - } -} - -/** - * Computes the patterns that the provider handles. Discards sibling clauses and 'false' patterns - */ -export function resolvePatternsForProvider(globalPattern: glob.IExpression | undefined, folderPattern: glob.IExpression | undefined): string[] { - const merged = { - ...(globalPattern || {}), - ...(folderPattern || {}) - }; - - return Object.keys(merged) - .filter(key => { - const value = merged[key]; - return typeof value === 'boolean' && value; - }); -} - -export class QueryGlobTester { - - private _excludeExpression: glob.IExpression; - private _parsedExcludeExpression: glob.ParsedExpression; - - private _parsedIncludeExpression: glob.ParsedExpression; - - constructor(config: ISearchQuery, folderQuery: IFolderQuery) { - this._excludeExpression = { - ...(config.excludePattern || {}), - ...(folderQuery.excludePattern || {}) - }; - this._parsedExcludeExpression = glob.parse(this._excludeExpression); - - // Empty includeExpression means include nothing, so no {} shortcuts - let includeExpression: glob.IExpression | undefined = config.includePattern; - if (folderQuery.includePattern) { - if (includeExpression) { - includeExpression = { - ...includeExpression, - ...folderQuery.includePattern - }; - } else { - includeExpression = folderQuery.includePattern; - } - } - - if (includeExpression) { - this._parsedIncludeExpression = glob.parse(includeExpression); - } - } - - /** - * Guaranteed sync - siblingsFn should not return a promise. - */ - includedInQuerySync(testPath: string, basename?: string, hasSibling?: (name: string) => boolean): boolean { - if (this._parsedExcludeExpression && this._parsedExcludeExpression(testPath, basename, hasSibling)) { - return false; - } - - if (this._parsedIncludeExpression && !this._parsedIncludeExpression(testPath, basename, hasSibling)) { - return false; - } - - return true; - } - - /** - * Guaranteed async. - */ - includedInQuery(testPath: string, basename?: string, hasSibling?: (name: string) => boolean | Promise): Promise { - const excludeP = this._parsedExcludeExpression ? - Promise.resolve(this._parsedExcludeExpression(testPath, basename, hasSibling)).then(result => !!result) : - Promise.resolve(false); - - return excludeP.then(excluded => { - if (excluded) { - return false; - } - - return this._parsedIncludeExpression ? - Promise.resolve(this._parsedIncludeExpression(testPath, basename, hasSibling)).then(result => !!result) : - Promise.resolve(true); - }).then(included => { - return included; - }); - } - - hasSiblingExcludeClauses(): boolean { - return hasSiblingClauses(this._excludeExpression); - } -} - -function hasSiblingClauses(pattern: glob.IExpression): boolean { - for (const key in pattern) { - if (typeof pattern[key] !== 'boolean') { - return true; - } - } - - return false; -} diff --git a/src/vs/workbench/services/search/node/searchIpc.ts b/src/vs/workbench/services/search/node/searchIpc.ts index 3d3b0ad9364..6c22c60cb37 100644 --- a/src/vs/workbench/services/search/node/searchIpc.ts +++ b/src/vs/workbench/services/search/node/searchIpc.ts @@ -5,8 +5,7 @@ import { Event } from 'vs/base/common/event'; import { IChannel, IServerChannel } from 'vs/base/parts/ipc/node/ipc'; -import { IRawFileQuery, IRawTextQuery } from 'vs/workbench/services/search/common/search'; -import { IRawSearchService, ISerializedSearchComplete, ISerializedSearchProgressItem } from './search'; +import { IRawFileQuery, IRawTextQuery, IRawSearchService, ISerializedSearchComplete, ISerializedSearchProgressItem } from 'vs/workbench/services/search/common/search'; export class SearchChannel implements IServerChannel { diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index e0514eeaab5..7840cbaae6a 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -20,13 +20,12 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { IDebugParams, IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; -import { deserializeSearchError, FileMatch, ICachedSearchStats, IFileMatch, IFileQuery, IFileSearchStats, IFolderQuery, IProgress, ISearchComplete, ISearchEngineStats, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, ITextQuery, pathIncludedInQuery, QueryType, SearchError, SearchErrorCode, SearchProviderType, ISearchConfiguration } from 'vs/workbench/services/search/common/search'; +import { deserializeSearchError, FileMatch, ICachedSearchStats, IFileMatch, IFileQuery, IFileSearchStats, IFolderQuery, IProgress, ISearchComplete, ISearchEngineStats, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, ITextQuery, pathIncludedInQuery, QueryType, SearchError, SearchErrorCode, SearchProviderType, ISearchConfiguration, IRawSearchService, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, isSerializedSearchComplete, isSerializedSearchSuccess } from 'vs/workbench/services/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { addContextToEditorMatches, editorMatchesToTextSearchResults } from 'vs/workbench/services/search/common/searchHelpers'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; -import { IRawSearchService, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, isSerializedSearchComplete, isSerializedSearchSuccess } from './search'; import { SearchChannelClient } from './searchIpc'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; diff --git a/src/vs/workbench/services/search/node/textSearchAdapter.ts b/src/vs/workbench/services/search/node/textSearchAdapter.ts index 2308349c84d..86eaf80620e 100644 --- a/src/vs/workbench/services/search/node/textSearchAdapter.ts +++ b/src/vs/workbench/services/search/node/textSearchAdapter.ts @@ -5,10 +5,9 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import * as extfs from 'vs/base/node/extfs'; -import { IFileMatch, IProgress, ITextQuery, ITextSearchStats, ITextSearchMatch } from 'vs/workbench/services/search/common/search'; +import { IFileMatch, IProgress, ITextQuery, ITextSearchStats, ITextSearchMatch, ISerializedFileMatch, ISerializedSearchSuccess } from 'vs/workbench/services/search/common/search'; import { RipgrepTextSearchEngine } from 'vs/workbench/services/search/node/ripgrepTextSearchEngine'; import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager'; -import { ISerializedFileMatch, ISerializedSearchSuccess } from './search'; export class TextSearchEngineAdapter { diff --git a/src/vs/workbench/services/search/node/textSearchManager.ts b/src/vs/workbench/services/search/node/textSearchManager.ts index 9f2dd2b0c88..1be2b0334d8 100644 --- a/src/vs/workbench/services/search/node/textSearchManager.ts +++ b/src/vs/workbench/services/search/node/textSearchManager.ts @@ -12,8 +12,7 @@ import * as resources from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { toCanonicalName } from 'vs/base/node/encoding'; import * as extfs from 'vs/base/node/extfs'; -import { IExtendedExtensionSearchOptions, IFileMatch, IFolderQuery, IPatternInfo, ISearchCompleteStats, ITextQuery, ITextSearchContext, ITextSearchMatch, ITextSearchResult } from 'vs/workbench/services/search/common/search'; -import { QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/node/search'; +import { IExtendedExtensionSearchOptions, IFileMatch, IFolderQuery, IPatternInfo, ISearchCompleteStats, ITextQuery, ITextSearchContext, ITextSearchMatch, ITextSearchResult, QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/common/search'; import * as vscode from 'vscode'; export class TextSearchManager { diff --git a/src/vs/workbench/services/search/test/node/rawSearchService.test.ts b/src/vs/workbench/services/search/test/node/rawSearchService.test.ts index 7c156c5e583..a05e1e03a6c 100644 --- a/src/vs/workbench/services/search/test/node/rawSearchService.test.ts +++ b/src/vs/workbench/services/search/test/node/rawSearchService.test.ts @@ -9,9 +9,8 @@ import { getPathFromAmdModule } from 'vs/base/common/amd'; import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; import { URI } from 'vs/base/common/uri'; -import { IFileQuery, IFileSearchStats, IFolderQuery, IProgress, ISearchEngineStats, QueryType } from 'vs/workbench/services/search/common/search'; +import { IFileQuery, IFileSearchStats, IFolderQuery, IProgress, ISearchEngineStats, QueryType, IRawFileMatch, ISearchEngine, ISearchEngineSuccess, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ISerializedSearchSuccess } from 'vs/workbench/services/search/common/search'; import { SearchService as RawSearchService } from 'vs/workbench/services/search/node/rawSearchService'; -import { IRawFileMatch, ISearchEngine, ISearchEngineSuccess, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, ISerializedSearchSuccess } from 'vs/workbench/services/search/node/search'; import { DiskSearch } from 'vs/workbench/services/search/node/searchService'; const TEST_FOLDER_QUERIES = [ diff --git a/src/vs/workbench/services/search/test/node/search.test.ts b/src/vs/workbench/services/search/test/node/search.test.ts index 069ed3175ec..34d9c2bad1c 100644 --- a/src/vs/workbench/services/search/test/node/search.test.ts +++ b/src/vs/workbench/services/search/test/node/search.test.ts @@ -9,9 +9,8 @@ import { getPathFromAmdModule } from 'vs/base/common/amd'; import * as platform from 'vs/base/common/platform'; import { joinPath } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; -import { IFolderQuery, QueryType } from 'vs/workbench/services/search/common/search'; +import { IFolderQuery, QueryType, IRawFileMatch } from 'vs/workbench/services/search/common/search'; import { Engine as FileSearchEngine, FileWalker } from 'vs/workbench/services/search/node/fileSearch'; -import { IRawFileMatch } from 'vs/workbench/services/search/node/search'; const TEST_FIXTURES = path.normalize(getPathFromAmdModule(require, './fixtures')); const EXAMPLES_FIXTURES = URI.file(path.join(TEST_FIXTURES, 'examples')); diff --git a/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts b/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts index 02d457aaadd..b751b3b0c15 100644 --- a/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts +++ b/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts @@ -9,8 +9,7 @@ import { getPathFromAmdModule } from 'vs/base/common/amd'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import * as glob from 'vs/base/common/glob'; import { URI } from 'vs/base/common/uri'; -import { deserializeSearchError, IFolderQuery, ISearchRange, ITextQuery, ITextSearchContext, ITextSearchMatch, QueryType, SearchErrorCode } from 'vs/workbench/services/search/common/search'; -import { ISerializedFileMatch } from 'vs/workbench/services/search/node/search'; +import { deserializeSearchError, IFolderQuery, ISearchRange, ITextQuery, ITextSearchContext, ITextSearchMatch, QueryType, SearchErrorCode, ISerializedFileMatch } from 'vs/workbench/services/search/common/search'; import { TextSearchEngineAdapter } from 'vs/workbench/services/search/node/textSearchAdapter'; const TEST_FIXTURES = path.normalize(getPathFromAmdModule(require, './fixtures')); diff --git a/src/vs/workbench/services/textMate/electron-browser/TMGrammars.ts b/src/vs/workbench/services/textMate/common/TMGrammars.ts similarity index 100% rename from src/vs/workbench/services/textMate/electron-browser/TMGrammars.ts rename to src/vs/workbench/services/textMate/common/TMGrammars.ts diff --git a/src/vs/workbench/services/textMate/electron-browser/textMateService.ts b/src/vs/workbench/services/textMate/electron-browser/textMateService.ts index 224367b09e8..de5333bf4a8 100644 --- a/src/vs/workbench/services/textMate/electron-browser/textMateService.ts +++ b/src/vs/workbench/services/textMate/electron-browser/textMateService.ts @@ -20,7 +20,7 @@ import { IFileService } from 'vs/platform/files/common/files'; import { ILogService } from 'vs/platform/log/common/log'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ExtensionMessageCollector } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { IEmbeddedLanguagesMap, ITMSyntaxExtensionPoint, TokenTypesContribution, grammarsExtPoint } from 'vs/workbench/services/textMate/electron-browser/TMGrammars'; +import { IEmbeddedLanguagesMap, ITMSyntaxExtensionPoint, TokenTypesContribution, grammarsExtPoint } from 'vs/workbench/services/textMate/common/TMGrammars'; import { ITextMateService } from 'vs/workbench/services/textMate/common/textMateService'; import { ITokenColorizationRule, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IEmbeddedLanguagesMap as IEmbeddedLanguagesMap2, IGrammar, ITokenTypeMap, Registry, StackElement, StandardTokenType } from 'vscode-textmate'; diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 600e12c27bc..00ec860a12b 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -237,8 +237,7 @@ import 'vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution import 'vs/workbench/contrib/tasks/electron-browser/task.contribution'; // Emmet -import 'vs/workbench/contrib/emmet/browser/emmet.browser.contribution'; -import 'vs/workbench/contrib/emmet/electron-browser/emmet.contribution'; +import 'vs/workbench/contrib/emmet/browser/emmet.contribution'; // CodeEditor Contributions import 'vs/workbench/contrib/codeEditor/browser/codeEditor.contribution'; diff --git a/test/smoke/package.json b/test/smoke/package.json index 80351281340..bef1e5f59d5 100644 --- a/test/smoke/package.json +++ b/test/smoke/package.json @@ -22,7 +22,7 @@ "@types/webdriverio": "4.6.1", "concurrently": "^3.5.1", "cpx": "^1.5.0", - "electron": "3.1.3", + "electron": "3.1.6", "htmlparser2": "^3.9.2", "mkdirp": "^0.5.1", "mocha": "^5.2.0", diff --git a/test/smoke/yarn.lock b/test/smoke/yarn.lock index d1e614c487a..d90dbd6007a 100644 --- a/test/smoke/yarn.lock +++ b/test/smoke/yarn.lock @@ -596,10 +596,10 @@ electron-download@^4.1.0: semver "^5.4.1" sumchecker "^2.0.2" -electron@3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/electron/-/electron-3.1.3.tgz#848fa0fc62d131978cde15ec04ce195a08dc4155" - integrity sha512-Y1TbV5py2O0br0JVYh+ew1cW4cIOOgRNRMzwTwWuZNMZ9fK/XLlqsbZr1GpYHdiN2yIU1koO+g4Cw8VuW86NXQ== +electron@3.1.6: + version "3.1.6" + resolved "https://registry.yarnpkg.com/electron/-/electron-3.1.6.tgz#f6222e1964838b31c5806dd041b1b58a941998f6" + integrity sha512-elEKKlFMnR0bhR/Uttk0TI496ZadxYsecyKgj2tZgrWx/F/anzfxbEYNcv134vT+qMFC/BXvoaeaIIj2YYdVuA== dependencies: "@types/node" "^8.0.24" electron-download "^4.1.0" diff --git a/yarn.lock b/yarn.lock index 53dc4477514..d8d5f5d3ea3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5940,6 +5940,11 @@ node-abi@^2.2.0: dependencies: semver "^5.4.1" +node-addon-api@^1.3.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.6.2.tgz#d8aad9781a5cfc4132cc2fecdbdd982534265217" + integrity sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA== + node-libs-browser@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" @@ -9449,10 +9454,10 @@ vscode-windows-registry@1.0.1: dependencies: nan "^2.12.1" -vscode-xterm@3.12.0-beta5: - version "3.12.0-beta5" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.12.0-beta5.tgz#cc1ab88fd564c2ddc36269f7e2b5c9740243a409" - integrity sha512-/UiL1pPm5MKllLyUlKwD5TAOAO8PObWAKQ0Hg3Z3tkF2zkNnR+fT0u+J/J6yWFtOoZ27Cj6QhFEfoiH6WSoXVQ== +vscode-xterm@3.13.0-beta1: + version "3.13.0-beta1" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.13.0-beta1.tgz#c1f4d90fe201f7e3afe7e7e0835f0b093a09afd5" + integrity sha512-NxWVk+q5cbHpbLFME+RfQ2RmJdR95lxjnhZEkXgHPOkmblzoHxRsZY9yF85Zfl5oNaiLMre9OwuhkHAZBQX8vg== vso-node-api@6.1.2-preview: version "6.1.2-preview" @@ -9585,6 +9590,12 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +"win-ca-lib@https://github.com/chrmarti/win-ca/releases/download/v2.4.1-lib-test/win-ca-lib-2.4.1.tgz": + version "2.4.1" + resolved "https://github.com/chrmarti/win-ca/releases/download/v2.4.1-lib-test/win-ca-lib-2.4.1.tgz#92415b2c45d08b72217011db8050f8c957e208c4" + dependencies: + node-addon-api "^1.3.0" + window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"