diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index 97f3a7f14aa..bad64ca55ae 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -18,7 +18,7 @@ import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingReso import { IKeybindingEvent, KeybindingSource, IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IConfirmation, IMessageService } from 'vs/platform/message/common/message'; -import { IWorkspaceContextService, IWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, IWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { Selection } from 'vs/editor/common/core/selection'; @@ -535,7 +535,7 @@ export class SimpleWorkspaceContextService implements IWorkspaceContextService { constructor() { const resource = URI.from({ scheme: SimpleWorkspaceContextService.SCHEME, authority: 'model', path: '/' }); - this.workspace = { id: '4064f6ec-cb38-4ad0-af64-ee6467e63c82', folders: [{ uri: resource, raw: { path: resource.toString() }, name: '', index: 0, }], name: resource.fsPath }; + this.workspace = { id: '4064f6ec-cb38-4ad0-af64-ee6467e63c82', folders: [new WorkspaceFolder({ uri: resource, name: '', index: 0 })], name: resource.fsPath }; } public getWorkspace(): IWorkspace { diff --git a/src/vs/platform/workspace/common/workspace.ts b/src/vs/platform/workspace/common/workspace.ts index 755eb652c21..00b3c8a61cd 100644 --- a/src/vs/platform/workspace/common/workspace.ts +++ b/src/vs/platform/workspace/common/workspace.ts @@ -75,11 +75,6 @@ export interface IWorkspaceContextService { * Returns if the provided resource is inside the workspace or not. */ isInsideWorkspace(resource: URI): boolean; - - /** - * Given a workspace relative path and workspace folder, returns the resource with the absolute path. - */ - toResource: (workspaceRelativePath: string, workspaceFolder: IWorkspaceFolder) => URI; } export interface IWorkspace { @@ -105,8 +100,7 @@ export interface IWorkspace { readonly configuration?: URI; } -export interface IWorkspaceFolder { - +export interface IWorkspaceFolderData { /** * The associated URI for this workspace folder. */ @@ -122,22 +116,25 @@ export interface IWorkspaceFolder { * The ordinal number of this workspace folder. */ readonly index: number; +} + +export interface IWorkspaceFolder extends IWorkspaceFolderData { /** - * The raw path of this workspace folder + * Given workspace folder relative path, returns the resource with the absolute path. */ - readonly raw: IStoredWorkspaceFolder; + toResource: (relativePath: string) => URI; } export class Workspace implements IWorkspace { - private _foldersMap: TrieMap = new TrieMap(); - private _folders: IWorkspaceFolder[]; + private _foldersMap: TrieMap = new TrieMap(); + private _folders: WorkspaceFolder[]; constructor( private _id: string, private _name: string = '', - folders: IWorkspaceFolder[] = [], + folders: WorkspaceFolder[] = [], private _configuration: URI = null, private _ctime?: number ) { @@ -152,11 +149,11 @@ export class Workspace implements IWorkspace { this.folders = workspace.folders; } - public get folders(): IWorkspaceFolder[] { + public get folders(): WorkspaceFolder[] { return this._folders; } - public set folders(folders: IWorkspaceFolder[]) { + public set folders(folders: WorkspaceFolder[]) { this._folders = folders; this.updateFoldersMap(); } @@ -194,7 +191,7 @@ export class Workspace implements IWorkspace { } private updateFoldersMap(): void { - this._foldersMap = new TrieMap(); + this._foldersMap = new TrieMap(); for (const folder of this.folders) { this._foldersMap.insert(folder.uri.toString(), folder); } @@ -205,19 +202,41 @@ export class Workspace implements IWorkspace { } } -export function toWorkspaceFolders(configuredFolders: IStoredWorkspaceFolder[], relativeTo?: URI): IWorkspaceFolder[] { - let workspaceFolders = parseWorkspaceFolders(configuredFolders, relativeTo); - return ensureUnique(coalesce(workspaceFolders)) - .map(({ uri, raw, name }, index) => ({ uri, raw, name: name || paths.basename(uri.fsPath), index })); +export class WorkspaceFolder implements IWorkspaceFolder { + + readonly uri: URI; + readonly name: string; + readonly index: number; + + constructor(data: IWorkspaceFolderData, + readonly raw?: IStoredWorkspaceFolder) { + this.uri = data.uri; + this.index = data.index; + this.name = data.name; + } + + toResource(relativePath: string): URI { + return URI.file(paths.join(this.uri.fsPath, relativePath)); + } + + public toJSON(): IWorkspaceFolderData { + return { uri: this.uri, name: this.name, index: this.index }; + } } -function parseWorkspaceFolders(configuredFolders: IStoredWorkspaceFolder[], relativeTo: URI): IWorkspaceFolder[] { +export function toWorkspaceFolders(configuredFolders: IStoredWorkspaceFolder[], relativeTo?: URI): WorkspaceFolder[] { + let workspaceFolders = parseWorkspaceFolders(configuredFolders, relativeTo); + return ensureUnique(coalesce(workspaceFolders)) + .map(({ uri, raw, name }, index) => new WorkspaceFolder({ uri, name: name || paths.basename(uri.fsPath), index }, raw)); +} + +function parseWorkspaceFolders(configuredFolders: IStoredWorkspaceFolder[], relativeTo: URI): WorkspaceFolder[] { return configuredFolders.map((configuredFolder, index) => { const uri = toUri(configuredFolder.path, relativeTo); if (!uri) { return void 0; } - return { uri, raw: configuredFolder, index, name: configuredFolder.name }; + return new WorkspaceFolder({ uri, name: configuredFolder.name, index }, configuredFolder); }); } @@ -233,6 +252,6 @@ function toUri(path: string, relativeTo: URI): URI { return null; } -function ensureUnique(folders: IWorkspaceFolder[]): IWorkspaceFolder[] { +function ensureUnique(folders: WorkspaceFolder[]): WorkspaceFolder[] { return distinct(folders, folder => isLinux ? folder.uri.fsPath : folder.uri.fsPath.toLowerCase()); } diff --git a/src/vs/platform/workspace/test/common/workspace.test.ts b/src/vs/platform/workspace/test/common/workspace.test.ts index b25db238f1e..130aebe39d6 100644 --- a/src/vs/platform/workspace/test/common/workspace.test.ts +++ b/src/vs/platform/workspace/test/common/workspace.test.ts @@ -6,14 +6,14 @@ 'use strict'; import * as assert from 'assert'; -import { Workspace, IWorkspaceFolder, toWorkspaceFolders } from 'vs/platform/workspace/common/workspace'; +import { Workspace, toWorkspaceFolders, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import URI from 'vs/base/common/uri'; suite('Workspace', () => { test('getFolder returns the folder with given uri', () => { - const expected = aWorkspaceFolder(URI.file('/src/test')); - let testObject = new Workspace('', '', [aWorkspaceFolder(URI.file('/src/main')), expected, aWorkspaceFolder(URI.file('/src/code'))]); + const expected = new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 2 }); + let testObject = new Workspace('', '', [new WorkspaceFolder({ uri: URI.file('/src/main'), name: '', index: 0 }), expected, new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 2 })]); const actual = testObject.getFolder(expected.uri); @@ -21,8 +21,8 @@ suite('Workspace', () => { }); test('getFolder returns the folder if the uri is sub', () => { - const expected = aWorkspaceFolder(URI.file('/src/test')); - let testObject = new Workspace('', '', [expected, aWorkspaceFolder(URI.file('/src/main')), aWorkspaceFolder(URI.file('/src/code'))]); + const expected = new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 0 }); + let testObject = new Workspace('', '', [expected, new WorkspaceFolder({ uri: URI.file('/src/main'), name: '', index: 1 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 2 })]); const actual = testObject.getFolder(URI.file('/src/test/a')); @@ -30,8 +30,8 @@ suite('Workspace', () => { }); test('getFolder returns the closest folder if the uri is sub', () => { - const expected = aWorkspaceFolder(URI.file('/src/test')); - let testObject = new Workspace('', '', [aWorkspaceFolder(URI.file('/src/code')), aWorkspaceFolder(URI.file('/src')), expected]); + const expected = new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 2 }); + let testObject = new Workspace('', '', [new WorkspaceFolder({ uri: URI.file('/src/main'), name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 }), expected]); const actual = testObject.getFolder(URI.file('/src/test/a')); @@ -39,7 +39,7 @@ suite('Workspace', () => { }); test('getFolder returns null if the uri is not sub', () => { - let testObject = new Workspace('', '', [aWorkspaceFolder(URI.file('/src/code')), aWorkspaceFolder(URI.file('/src/test'))]); + let testObject = new Workspace('', '', [new WorkspaceFolder({ uri: URI.file('/src/test'), name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 })]); const actual = testObject.getFolder(URI.file('/src/main/a')); @@ -190,11 +190,4 @@ suite('Workspace', () => { assert.equal(actual[2].index, 2); assert.equal(actual[2].name, 'test1'); }); - - function aWorkspaceFolder(uri: URI, index: number = 0): IWorkspaceFolder { - return { - uri, raw: { path: uri.fsPath }, index, name: '' - }; - } - }); \ No newline at end of file diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 5dfdba9d121..e71bcb49058 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -47,7 +47,7 @@ import { ITreeItem } from 'vs/workbench/common/views'; import { ThemeColor } from 'vs/platform/theme/common/themeService'; import { IDisposable } from 'vs/base/common/lifecycle'; import { SerializedError } from 'vs/base/common/errors'; -import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace'; import { IStat, IFileChange } from 'vs/platform/files/common/files'; export interface IEnvironment { @@ -65,7 +65,7 @@ export interface IEnvironment { export interface IWorkspaceData { id: string; name: string; - folders: IWorkspaceFolder[]; + folders: IWorkspaceFolderData[]; } export interface IInitData { diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index a87f6751751..d6027a8e703 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -9,7 +9,7 @@ import Event, { Emitter } from 'vs/base/common/event'; import { normalize } from 'vs/base/common/paths'; import { delta } from 'vs/base/common/arrays'; import { relative } from 'path'; -import { Workspace } from 'vs/platform/workspace/common/workspace'; +import { Workspace, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IWorkspaceData, ExtHostWorkspaceShape, MainContext, MainThreadWorkspaceShape, IMainContext } from './extHost.protocol'; import * as vscode from 'vscode'; import { compare } from 'vs/base/common/strings'; @@ -25,7 +25,7 @@ class Workspace2 extends Workspace { private readonly _structure = new TrieMap(s => s.split('/')); private constructor(data: IWorkspaceData) { - super(data.id, data.name, data.folders); + super(data.id, data.name, data.folders.map(folder => new WorkspaceFolder(folder))); // setup the workspace folder data structure this.folders.forEach(({ name, uri, index }) => { diff --git a/src/vs/workbench/parts/debug/browser/linkDetector.ts b/src/vs/workbench/parts/debug/browser/linkDetector.ts index 29dd86998c0..420c424b840 100644 --- a/src/vs/workbench/parts/debug/browser/linkDetector.ts +++ b/src/vs/workbench/parts/debug/browser/linkDetector.ts @@ -50,7 +50,7 @@ export class LinkDetector { if (workspaceFolder) { try { resource = (match && !strings.startsWith(match[0], 'http')) - && (match[2] || strings.startsWith(match[1], '/') ? uri.file(match[1]) : this.contextService.toResource(match[1], workspaceFolder)); // TODO@Michel TODO@Isidor (https://github.com/Microsoft/vscode/issues/29190) + && (match[2] || strings.startsWith(match[1], '/') ? uri.file(match[1]) : workspaceFolder.toResource(match[1])); // TODO@Michel TODO@Isidor (https://github.com/Microsoft/vscode/issues/29190) } catch (e) { } } diff --git a/src/vs/workbench/parts/extensions/browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/browser/extensionsActions.ts index 531618cd8f2..401f5b0e0a3 100644 --- a/src/vs/workbench/parts/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/browser/extensionsActions.ts @@ -1370,7 +1370,7 @@ export class ConfigureWorkspaceRecommendedExtensionsAction extends AbstractConfi public run(event: any): TPromise { switch (this.contextService.getWorkbenchState()) { case WorkbenchState.FOLDER: - return this.openExtensionsFile(this.contextService.toResource(paths.join('.vscode', 'extensions.json'), this.contextService.getWorkspace().folders[0])); + return this.openExtensionsFile(this.contextService.getWorkspace().folders[0].toResource(paths.join('.vscode', 'extensions.json'))); case WorkbenchState.WORKSPACE: return this.openWorkspaceConfigurationFile(this.contextService.getWorkspace().configuration); } @@ -1413,7 +1413,7 @@ export class ConfigureWorkspaceFolderRecommendedExtensionsAction extends Abstrac return this.commandService.executeCommand(PICK_WORKSPACE_FOLDER_COMMAND) .then(workspaceFolder => { if (workspaceFolder) { - return this.openExtensionsFile(this.contextService.toResource(paths.join('.vscode', 'extensions.json'), workspaceFolder)); + return this.openExtensionsFile(workspaceFolder.toResource(paths.join('.vscode', 'extensions.json'))); } return null; }); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts index 538f56523ca..3918fe5f9f0 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts @@ -85,7 +85,7 @@ export class ExtensionTipsService implements IExtensionTipsService { } private resolveWorkspaceFolderRecommendations(workspaceFolder: IWorkspaceFolder): TPromise { - return this.fileService.resolveContent(this.contextService.toResource(paths.join('.vscode', 'extensions.json'), workspaceFolder)) + return this.fileService.resolveContent(workspaceFolder.toResource(paths.join('.vscode', 'extensions.json'))) .then(content => this.processWorkspaceRecommendations(json.parse(content.value, [])), err => []); } diff --git a/src/vs/workbench/parts/preferences/browser/preferencesService.ts b/src/vs/workbench/parts/preferences/browser/preferencesService.ts index 05fe0487f3e..c975dfe62f8 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesService.ts @@ -320,10 +320,10 @@ export class PreferencesService extends Disposable implements IPreferencesServic return null; } const workspace = this.contextService.getWorkspace(); - return workspace.configuration || this.contextService.toResource(paths.join('.vscode', 'settings.json'), workspace.folders[0]); + return workspace.configuration || workspace.folders[0].toResource(paths.join('.vscode', 'settings.json')); case ConfigurationTarget.FOLDER: const folder = this.contextService.getWorkspaceFolder(resource); - return folder ? this.contextService.toResource(paths.join('.vscode', 'settings.json'), folder) : null; + return folder ? folder.toResource(paths.join('.vscode', 'settings.json')) : null; } return null; } diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index a23135e551a..4d9bb12abeb 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -118,7 +118,7 @@ abstract class OpenTaskConfigurationAction extends Action { } let sideBySide = !!(event && (event.ctrlKey || event.metaKey)); let configFileCreated = false; - return this.fileService.resolveFile(this.contextService.toResource('.vscode/tasks.json', this.contextService.getWorkspace().folders[0])).then((success) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) + return this.fileService.resolveFile(this.contextService.getWorkspace().folders[0].toResource('.vscode/tasks.json')).then((success) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) return success; }, (err: any) => { @@ -169,7 +169,7 @@ abstract class OpenTaskConfigurationAction extends Action { content = content.replace(/(\n)(\t+)/g, (_, s1, s2) => s1 + strings.repeat(' ', s2.length * editorConfig.editor.tabSize)); } configFileCreated = true; - return this.fileService.createFile(this.contextService.toResource('.vscode/tasks.json', this.contextService.getWorkspace().folders[0]), content).then((result) => { + return this.fileService.createFile(this.contextService.getWorkspace().folders[0].toResource('.vscode/tasks.json'), content).then((result) => { this.telemetryService.publicLog(TaskService.TemplateTelemetryEventName, { templateId: selection.id, autoDetect: selection.autoDetect @@ -1166,7 +1166,7 @@ class TaskService extends EventEmitter implements ITaskService { if (editorConfig.editor.insertSpaces) { content = content.replace(/(\n)(\t+)/g, (_, s1, s2) => s1 + strings.repeat(' ', s2.length * editorConfig.editor.tabSize)); } - promise = this.fileService.createFile(this.contextService.toResource('.vscode/tasks.json', workspaceFolder), content).then(() => { }); + promise = this.fileService.createFile(workspaceFolder.toResource('.vscode/tasks.json'), content).then(() => { }); } else { let value: IConfigurationValue = { key: undefined, value: undefined }; // We have a global task configuration @@ -1205,7 +1205,7 @@ class TaskService extends EventEmitter implements ITaskService { }; this.telemetryService.publicLog(TaskService.CustomizationTelemetryEventName, event); if (openConfig) { - let resource = this.contextService.toResource('.vscode/tasks.json', workspaceFolder); + let resource = workspaceFolder.toResource('.vscode/tasks.json'); this.editorService.openEditor({ resource: resource, options: { @@ -1228,7 +1228,7 @@ class TaskService extends EventEmitter implements ITaskService { } public openConfig(task: CustomTask): TPromise { - let resource = this.contextService.toResource(task._source.config.file, Task.getWorkspaceFolder(task)); + let resource = Task.getWorkspaceFolder(task).toResource(task._source.config.file); return this.editorService.openEditor({ resource: resource, options: { diff --git a/src/vs/workbench/parts/tasks/node/processRunnerDetector.ts b/src/vs/workbench/parts/tasks/node/processRunnerDetector.ts index 6a8926fec1d..03e29fb4ade 100644 --- a/src/vs/workbench/parts/tasks/node/processRunnerDetector.ts +++ b/src/vs/workbench/parts/tasks/node/processRunnerDetector.ts @@ -228,7 +228,7 @@ export class ProcessRunnerDetector { } private tryDetectGulp(list: boolean): TPromise { - return this.fileService.resolveFile(this.contextService.toResource('gulpfile.js', this.contextService.getWorkspace().folders[0])).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) + return this.fileService.resolveFile(this.contextService.getWorkspace().folders[0].toResource('gulpfile.js')).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) let config = ProcessRunnerDetector.detectorConfig('gulp'); let process = new LineProcess('gulp', [config.arg, '--no-color'], true, { cwd: this._cwd }); return this.runDetection(process, 'gulp', true, config.matcher, ProcessRunnerDetector.DefaultProblemMatchers, list); @@ -238,7 +238,7 @@ export class ProcessRunnerDetector { } private tryDetectGrunt(list: boolean): TPromise { - return this.fileService.resolveFile(this.contextService.toResource('Gruntfile.js', this.contextService.getWorkspace().folders[0])).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) + return this.fileService.resolveFile(this.contextService.getWorkspace().folders[0].toResource('Gruntfile.js')).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) let config = ProcessRunnerDetector.detectorConfig('grunt'); let process = new LineProcess('grunt', [config.arg, '--no-color'], true, { cwd: this._cwd }); return this.runDetection(process, 'grunt', true, config.matcher, ProcessRunnerDetector.DefaultProblemMatchers, list); @@ -253,10 +253,10 @@ export class ProcessRunnerDetector { let process = new LineProcess('jake', [config.arg], true, { cwd: this._cwd }); return this.runDetection(process, 'jake', true, config.matcher, ProcessRunnerDetector.DefaultProblemMatchers, list); }; - return this.fileService.resolveFile(this.contextService.toResource('Jakefile', this.contextService.getWorkspace().folders[0])).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) + return this.fileService.resolveFile(this.contextService.getWorkspace().folders[0].toResource('Jakefile')).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) return run(); }, (err: any) => { - return this.fileService.resolveFile(this.contextService.toResource('Jakefile.js', this.contextService.getWorkspace().folders[0])).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) + return this.fileService.resolveFile(this.contextService.getWorkspace().folders[0].toResource('Jakefile.js')).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) return run(); }, (err: any) => { return null; diff --git a/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts b/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts index 8ffa18cdb49..85d747f12c3 100644 --- a/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts +++ b/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts @@ -12,17 +12,16 @@ import * as UUID from 'vs/base/common/uuid'; import * as Platform from 'vs/base/common/platform'; import { ValidationStatus } from 'vs/base/common/parsers'; import { ProblemMatcher, FileLocationKind, ProblemPattern, ApplyToKind } from 'vs/platform/markers/common/problemMatcher'; -import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceFolder, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import * as Tasks from 'vs/workbench/parts/tasks/common/tasks'; import { parse, ParseResult, IProblemReporter, ExternalTaskRunnerConfiguration, CustomTask } from 'vs/workbench/parts/tasks/node/taskConfiguration'; -const workspaceFolder: IWorkspaceFolder = { +const workspaceFolder: IWorkspaceFolder = new WorkspaceFolder({ uri: URI.file('/workspace/folderOne'), name: 'folderOne', - index: 0, - raw: { path: '../folderOne', name: 'folderOne' } -}; + index: 0 +}); class ProblemReporter implements IProblemReporter { diff --git a/src/vs/workbench/services/configuration/node/configuration.ts b/src/vs/workbench/services/configuration/node/configuration.ts index 5fb8a8f0b77..c059683d670 100644 --- a/src/vs/workbench/services/configuration/node/configuration.ts +++ b/src/vs/workbench/services/configuration/node/configuration.ts @@ -17,7 +17,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { readFile, stat, writeFile } from 'vs/base/node/pfs'; import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import * as extfs from 'vs/base/node/extfs'; -import { IWorkspaceContextService, IWorkspace, Workspace, WorkbenchState, IWorkspaceFolder, toWorkspaceFolders, IWorkspaceFoldersChangeEvent } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, Workspace, WorkbenchState, IWorkspaceFolder, toWorkspaceFolders, IWorkspaceFoldersChangeEvent } from 'vs/platform/workspace/common/workspace'; import { FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files'; import { isLinux } from 'vs/base/common/platform'; import { ConfigWatcher } from 'vs/base/node/config'; @@ -271,7 +271,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat this._register(this.baseConfigurationService.onDidUpdateConfiguration(e => this.onBaseConfigurationChanged(e))); } - public getWorkspace(): IWorkspace { + public getWorkspace(): Workspace { return this.workspace; } @@ -308,10 +308,6 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat return false; } - public toResource(workspaceRelativePath: string, workspaceFolder: IWorkspaceFolder): URI { - return URI.file(paths.join(workspaceFolder.uri.fsPath, workspaceRelativePath)); - } - public getConfigurationData(): IConfigurationData { return this._configuration.toData(); } diff --git a/src/vs/workbench/services/configuration/node/configurationEditingService.ts b/src/vs/workbench/services/configuration/node/configurationEditingService.ts index 409fbff7b9f..fa81d5be3cf 100644 --- a/src/vs/workbench/services/configuration/node/configurationEditingService.ts +++ b/src/vs/workbench/services/configuration/node/configurationEditingService.ts @@ -338,7 +338,7 @@ export class ConfigurationEditingService implements IConfigurationEditingService return workspace.configuration; } if (workbenchState === WorkbenchState.FOLDER) { - return this.contextService.toResource(relativePath, workspace.folders[0]); + return workspace.folders[0].toResource(relativePath); } } @@ -346,7 +346,7 @@ export class ConfigurationEditingService implements IConfigurationEditingService if (resource) { const folder = this.contextService.getWorkspaceFolder(resource); if (folder) { - return this.contextService.toResource(relativePath, folder); + return folder.toResource(relativePath); } } } diff --git a/src/vs/workbench/services/configuration/test/node/configuration.test.ts b/src/vs/workbench/services/configuration/test/node/configuration.test.ts index 32fc370158e..0a49d55728a 100644 --- a/src/vs/workbench/services/configuration/test/node/configuration.test.ts +++ b/src/vs/workbench/services/configuration/test/node/configuration.test.ts @@ -100,7 +100,6 @@ suite('WorkspaceContextService - Folder', () => { assert.equal(actual.folders[0].uri.fsPath, URI.file(workspaceResource).fsPath); assert.equal(actual.folders[0].name, workspaceName); assert.equal(actual.folders[0].index, 0); - assert.equal(actual.folders[0].raw.path.toLowerCase(), workspaceResource.toLowerCase()); assert.ok(!actual.configuration); }); diff --git a/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts b/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts index 0f8f279cda8..7841abf9606 100644 --- a/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts +++ b/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts @@ -30,7 +30,7 @@ suite('Configuration Resolver Service', () => { uri: uri.parse('file:///VSCode/workspaceLocation'), name: 'hey', index: 0, - raw: undefined + toResource: () => null }; configurationResolverService = new ConfigurationResolverService(envVariables, editorService, TestEnvironmentService, new TestConfigurationService(), mockCommandService); }); diff --git a/src/vs/workbench/services/files/test/node/fileService.test.ts b/src/vs/workbench/services/files/test/node/fileService.test.ts index b4ba620ede2..6559d99dc1e 100644 --- a/src/vs/workbench/services/files/test/node/fileService.test.ts +++ b/src/vs/workbench/services/files/test/node/fileService.test.ts @@ -20,7 +20,7 @@ import encodingLib = require('vs/base/node/encoding'); import utils = require('vs/workbench/services/files/test/node/utils'); import { onError } from 'vs/base/test/common/utils'; import { TestContextService, TestTextResourceConfigurationService } from 'vs/workbench/test/workbenchTestServices'; -import { Workspace, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { Workspace, toWorkspaceFolders } from 'vs/platform/workspace/common/workspace'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; suite('FileService', () => { @@ -38,7 +38,7 @@ suite('FileService', () => { return onError(error, done); } - service = new FileService(new TestContextService(new Workspace(testDir, testDir, [{ uri: uri.file(testDir), raw: { path: testDir }, index: 0, name: '' }])), new TestTextResourceConfigurationService(), new TestConfigurationService(), { disableWatcher: true }); + service = new FileService(new TestContextService(new Workspace(testDir, testDir, toWorkspaceFolders([{ path: testDir }]))), new TestTextResourceConfigurationService(), new TestConfigurationService(), { disableWatcher: true }); done(); }); }); @@ -784,7 +784,7 @@ suite('FileService', () => { const textResourceConfigurationService = new TestTextResourceConfigurationService(configurationService); - const _service = new FileService(new TestContextService(new Workspace(_testDir, _testDir, [aWorkspaceFolder(_testDir, 0)])), textResourceConfigurationService, configurationService, { + const _service = new FileService(new TestContextService(new Workspace(_testDir, _testDir, toWorkspaceFolders([{ path: _testDir }]))), textResourceConfigurationService, configurationService, { encodingOverride, disableWatcher: true }); @@ -811,7 +811,7 @@ suite('FileService', () => { const _sourceDir = require.toUrl('./fixtures/service'); const resource = uri.file(path.join(testDir, 'index.html')); - const _service = new FileService(new TestContextService(new Workspace(_testDir, _testDir, [aWorkspaceFolder(_testDir, 0)])), new TestTextResourceConfigurationService(), new TestConfigurationService(), { + const _service = new FileService(new TestContextService(new Workspace(_testDir, _testDir, toWorkspaceFolders([{ path: _testDir }]))), new TestTextResourceConfigurationService(), new TestConfigurationService(), { disableWatcher: true }); @@ -852,13 +852,4 @@ suite('FileService', () => { }); }); }); - - function aWorkspaceFolder(path: string, index: number, name: string = ''): IWorkspaceFolder { - return { - uri: uri.file(path), - index, - raw: { path: path }, - name - }; - } }); diff --git a/src/vs/workbench/services/keybinding/test/node/keybindingEditing.test.ts b/src/vs/workbench/services/keybinding/test/node/keybindingEditing.test.ts index de3d3e48d7e..9ee62bfdc44 100644 --- a/src/vs/workbench/services/keybinding/test/node/keybindingEditing.test.ts +++ b/src/vs/workbench/services/keybinding/test/node/keybindingEditing.test.ts @@ -9,7 +9,6 @@ import assert = require('assert'); import os = require('os'); import path = require('path'); import fs = require('fs'); -import uri from 'vs/base/common/uri'; import * as json from 'vs/base/common/json'; import { OS } from 'vs/base/common/platform'; import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding'; @@ -18,7 +17,7 @@ import { KeyCode, SimpleKeybinding, ChordKeybinding } from 'vs/base/common/keyCo import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import extfs = require('vs/base/node/extfs'); import { TestTextFileService, TestEditorGroupService, TestLifecycleService, TestBackupFileService, TestContextService, TestTextResourceConfigurationService } from 'vs/workbench/test/workbenchTestServices'; -import { IWorkspaceContextService, Workspace } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, Workspace, toWorkspaceFolders } from 'vs/platform/workspace/common/workspace'; import uuid = require('vs/base/common/uuid'); import { ConfigurationService } from 'vs/platform/configuration/node/configurationService'; import { FileService } from 'vs/workbench/services/files/node/fileService'; @@ -74,7 +73,7 @@ suite('Keybindings Editing', () => { instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(IModeService, ModeServiceImpl); instantiationService.stub(IModelService, instantiationService.createInstance(ModelServiceImpl)); - instantiationService.stub(IFileService, new FileService(new TestContextService(new Workspace(testDir, testDir, [{ uri: uri.file(testDir), raw: { path: testDir }, index: 0, name: '' }])), new TestTextResourceConfigurationService(), new TestConfigurationService(), { disableWatcher: true })); + instantiationService.stub(IFileService, new FileService(new TestContextService(new Workspace(testDir, testDir, toWorkspaceFolders([{ path: testDir }]))), new TestTextResourceConfigurationService(), new TestConfigurationService(), { disableWatcher: true })); instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService)); instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService)); instantiationService.stub(ITextModelService, instantiationService.createInstance(TextModelResolverService)); diff --git a/src/vs/workbench/services/workspace/node/workspaceEditingService.ts b/src/vs/workbench/services/workspace/node/workspaceEditingService.ts index e1789dfa8af..bfcc892a5ac 100644 --- a/src/vs/workbench/services/workspace/node/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspace/node/workspaceEditingService.ts @@ -33,7 +33,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { constructor( @IJSONEditingService private jsonEditingService: IJSONEditingService, - @IWorkspaceContextService private contextService: IWorkspaceContextService, + @IWorkspaceContextService private contextService: WorkspaceService, @IEnvironmentService private environmentService: IEnvironmentService, @IWindowsService private windowsService: IWindowsService, @IWindowService private windowService: IWindowService, diff --git a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts index c4fca1c3ef0..a935f3c9eed 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts @@ -15,8 +15,7 @@ import { ConfigurationTarget, ConfigurationEditingErrorCode, ConfigurationEditin import { ConfigurationModel } from 'vs/platform/configuration/common/configuration'; import { TestThreadService } from './testThreadService'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; -import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { IStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceFolder, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; suite('ExtHostConfiguration', function () { @@ -133,7 +132,7 @@ suite('ExtHostConfiguration', function () { new class extends mock() { }, new ExtHostWorkspace(new TestThreadService(), { 'id': 'foo', - 'folders': [aWorkspaceFolder({ path: 'foo' }, 0)], + 'folders': [aWorkspaceFolder(URI.file('foo'), 0)], 'name': 'foo' }), { @@ -205,7 +204,7 @@ suite('ExtHostConfiguration', function () { new class extends mock() { }, new ExtHostWorkspace(new TestThreadService(), { 'id': 'foo', - 'folders': [aWorkspaceFolder({ path: firstRoot.path }, 0), aWorkspaceFolder({ path: secondRoot.path }, 1)], + 'folders': [aWorkspaceFolder(firstRoot, 0), aWorkspaceFolder(secondRoot, 1)], 'name': 'foo' }), { @@ -405,12 +404,7 @@ suite('ExtHostConfiguration', function () { .then(() => assert.ok(false), err => { /* expecting rejection */ }); }); - function aWorkspaceFolder(raw: IStoredWorkspaceFolder, index: number, name: string = ''): IWorkspaceFolder { - return { - uri: URI.file(raw.path), - index, - raw, - name - }; + function aWorkspaceFolder(uri: URI, index: number, name: string = ''): IWorkspaceFolder { + return new WorkspaceFolder({ uri, name, index }); } }); diff --git a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts index b57a2b3d8a2..d9874115a7c 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts @@ -11,7 +11,7 @@ import { basename } from 'path'; import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; import { TestThreadService } from './testThreadService'; import { normalize } from 'vs/base/common/paths'; -import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace'; suite('ExtHostWorkspace', function () { @@ -26,7 +26,7 @@ suite('ExtHostWorkspace', function () { test('asRelativePath', function () { - const ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', folders: [aWorkspaceFolder(URI.file('/Coding/Applications/NewsWoWBot'), 0)], name: 'Test' }); + const ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/Applications/NewsWoWBot'), 0)], name: 'Test' }); assertAsRelativePath(ws, '/Coding/Applications/NewsWoWBot/bernd/das/brot', 'bernd/das/brot'); assertAsRelativePath(ws, '/Apps/DartPubCache/hosted/pub.dartlang.org/convert-2.0.1/lib/src/hex.dart', @@ -40,7 +40,7 @@ suite('ExtHostWorkspace', function () { test('asRelativePath, same paths, #11402', function () { const root = '/home/aeschli/workspaces/samples/docker'; const input = '/home/aeschli/workspaces/samples/docker'; - const ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', folders: [aWorkspaceFolder(URI.file(root), 0)], name: 'Test' }); + const ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }); assertAsRelativePath(ws, (input), input); @@ -55,14 +55,14 @@ suite('ExtHostWorkspace', function () { }); test('asRelativePath, multiple folders', function () { - const ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', folders: [aWorkspaceFolder(URI.file('/Coding/One'), 0), aWorkspaceFolder(URI.file('/Coding/Two'), 1)], name: 'Test' }); + const ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }); assertAsRelativePath(ws, '/Coding/One/file.txt', 'One/file.txt'); assertAsRelativePath(ws, '/Coding/Two/files/out.txt', 'Two/files/out.txt'); assertAsRelativePath(ws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt'); }); test('slightly inconsistent behaviour of asRelativePath and getWorkspaceFolder, #31553', function () { - const mrws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', folders: [aWorkspaceFolder(URI.file('/Coding/One'), 0), aWorkspaceFolder(URI.file('/Coding/Two'), 1)], name: 'Test' }); + const mrws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }); assertAsRelativePath(mrws, '/Coding/One/file.txt', 'One/file.txt'); assertAsRelativePath(mrws, '/Coding/One/file.txt', 'One/file.txt', true); @@ -74,7 +74,7 @@ suite('ExtHostWorkspace', function () { assertAsRelativePath(mrws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt', true); assertAsRelativePath(mrws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt', false); - const srws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', folders: [aWorkspaceFolder(URI.file('/Coding/One'), 0)], name: 'Test' }); + const srws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0)], name: 'Test' }); assertAsRelativePath(srws, '/Coding/One/file.txt', 'file.txt'); assertAsRelativePath(srws, '/Coding/One/file.txt', 'file.txt', false); assertAsRelativePath(srws, '/Coding/One/file.txt', 'One/file.txt', true); @@ -93,15 +93,15 @@ suite('ExtHostWorkspace', function () { ws = new ExtHostWorkspace(new TestThreadService(), undefined); assert.equal(ws.getPath(), undefined); - ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolder(URI.file('Folder'), 0), aWorkspaceFolder(URI.file('Another/Folder'), 1)] }); + ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('Folder'), 0), aWorkspaceFolderData(URI.file('Another/Folder'), 1)] }); assert.equal(ws.getPath().replace(/\\/g, '/'), '/Folder'); - ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolder(URI.file('/Folder'), 0)] }); + ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('/Folder'), 0)] }); assert.equal(ws.getPath().replace(/\\/g, '/'), '/Folder'); }); test('WorkspaceFolder has name and index', function () { - const ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', folders: [aWorkspaceFolder(URI.file('/Coding/One'), 0), aWorkspaceFolder(URI.file('/Coding/Two'), 1)], name: 'Test' }); + const ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }); const [one, two] = ws.getWorkspaceFolders(); @@ -112,7 +112,7 @@ suite('ExtHostWorkspace', function () { }); test('getContainingWorkspaceFolder', function () { - const ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolder(URI.file('/Coding/One'), 0), aWorkspaceFolder(URI.file('/Coding/Two'), 1), aWorkspaceFolder(URI.file('/Coding/Two/Nested'), 2)] }); + const ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1), aWorkspaceFolderData(URI.file('/Coding/Two/Nested'), 2)] }); let folder = ws.getWorkspaceFolder(URI.file('/foo/bar')); assert.equal(folder, undefined); @@ -157,7 +157,7 @@ suite('ExtHostWorkspace', function () { assert.equal(e.added.length, 1); assert.equal(e.added[0].uri.toString(), 'foo:bar'); }); - ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', folders: [aWorkspaceFolder(URI.parse('foo:bar'), 0)] }); + ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }); sub.dispose(); sub = ws.onDidChangeWorkspace(e => { @@ -165,7 +165,7 @@ suite('ExtHostWorkspace', function () { assert.equal(e.added.length, 1); assert.equal(e.added[0].uri.toString(), 'foo:bar2'); }); - ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', folders: [aWorkspaceFolder(URI.parse('foo:bar'), 0), aWorkspaceFolder(URI.parse('foo:bar2'), 1)] }); + ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0), aWorkspaceFolderData(URI.parse('foo:bar2'), 1)] }); sub.dispose(); sub = ws.onDidChangeWorkspace(e => { @@ -176,7 +176,7 @@ suite('ExtHostWorkspace', function () { assert.equal(e.added.length, 1); assert.equal(e.added[0].uri.toString(), 'foo:bar3'); }); - ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', folders: [aWorkspaceFolder(URI.parse('foo:bar3'), 0)] }); + ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar3'), 0)] }); sub.dispose(); }); @@ -195,13 +195,10 @@ suite('ExtHostWorkspace', function () { sub.dispose(); }); - function aWorkspaceFolder(uri: URI, index: number, name: string = ''): IWorkspaceFolder { + function aWorkspaceFolderData(uri: URI, index: number, name: string = ''): IWorkspaceFolderData { return { uri, index, - raw: { - path: uri.toString() - }, name: name || basename(uri.path) }; }