diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index c2902838625..3083ca76192 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -125,11 +125,6 @@ export interface IFileService { */ del(resource: URI, useTrash?: boolean): TPromise; - /** - * Imports the file to the parent identified by the resource. - */ - importFile(source: URI, targetFolder: URI): TPromise; - /** * Allows to start a watcher that reports file change events on the provided resource. */ @@ -178,8 +173,7 @@ export enum FileOperation { CREATE, DELETE, MOVE, - COPY, - IMPORT + COPY } export class FileOperationEvent { @@ -546,11 +540,6 @@ export interface ICreateFileOptions { overwrite?: boolean; } -export interface IImportResult { - stat: IFileStat; - isNew: boolean; -} - export class FileOperationError extends Error { constructor(message: string, public fileOperationResult: FileOperationResult, public options?: IResolveContentOptions & IUpdateContentOptions & ICreateFileOptions) { super(message); diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.ts index 7832bc03939..b37384da243 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.ts @@ -13,6 +13,7 @@ import { sequence, ITask, always } from 'vs/base/common/async'; import * as paths from 'vs/base/common/paths'; import * as resources from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; +import { posix } from 'path'; import * as errors from 'vs/base/common/errors'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import * as strings from 'vs/base/common/strings'; @@ -725,8 +726,8 @@ class BaseDeleteFileAction extends BaseFileAction { } } -/* Import File */ -export class ImportFileAction extends BaseFileAction { +/* Add File */ +export class AddFilesAction extends BaseFileAction { private tree: ITree; @@ -740,7 +741,7 @@ export class ImportFileAction extends BaseFileAction { @INotificationService notificationService: INotificationService, @ITextFileService textFileService: ITextFileService ) { - super('workbench.files.action.importFile', nls.localize('importFiles', "Import Files"), fileService, notificationService, textFileService); + super('workbench.files.action.addFile', nls.localize('addFiles', "Add Files"), fileService, notificationService, textFileService); this.tree = tree; this.element = element; @@ -753,10 +754,10 @@ export class ImportFileAction extends BaseFileAction { } public run(resources: URI[]): TPromise { - const importPromise = TPromise.as(null).then(() => { + const addPromise = TPromise.as(null).then(() => { if (resources && resources.length > 0) { - // Find parent for import + // Find parent to add to let targetElement: ExplorerItem; if (this.element) { targetElement = this.element; @@ -797,15 +798,15 @@ export class ImportFileAction extends BaseFileAction { return void 0; } - // Run import in sequence - const importPromisesFactory: ITask>[] = []; + // Run add in sequence + const addPromisesFactory: ITask>[] = []; resources.forEach(resource => { - importPromisesFactory.push(() => { + addPromisesFactory.push(() => { const sourceFile = resource; const targetFile = targetElement.resource.with({ path: paths.join(targetElement.resource.path, paths.basename(sourceFile.path)) }); // if the target exists and is dirty, make sure to revert it. otherwise the dirty contents - // of the target file would replace the contents of the imported file. since we already + // of the target file would replace the contents of the added file. since we already // confirmed the overwrite before, this is OK. let revertPromise = TPromise.wrap(null); if (this.textFileService.isDirty(targetFile)) { @@ -813,18 +814,19 @@ export class ImportFileAction extends BaseFileAction { } return revertPromise.then(() => { - return this.fileService.importFile(sourceFile, targetElement.resource).then(res => { + const target = targetElement.resource.with({ path: posix.join(targetElement.resource.path, posix.basename(sourceFile.path)) }); + return this.fileService.copyFile(sourceFile, target, true).then(stat => { - // if we only import one file, just open it directly + // if we only add one file, just open it directly if (resources.length === 1) { - this.editorService.openEditor({ resource: res.stat.resource, options: { pinned: true } }).done(null, errors.onUnexpectedError); + this.editorService.openEditor({ resource: stat.resource, options: { pinned: true } }).done(null, errors.onUnexpectedError); } }, error => this.onError(error)); }); }); }); - return sequence(importPromisesFactory); + return sequence(addPromisesFactory); }); }); } @@ -832,7 +834,7 @@ export class ImportFileAction extends BaseFileAction { return void 0; }); - return importPromise.then(() => { + return addPromise.then(() => { this.tree.clearHighlight(); }, (error: any) => { this.onError(error); diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts index 9a9c28d97ae..ea60112f840 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts @@ -470,7 +470,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView } // Add - if (e.operation === FileOperation.CREATE || e.operation === FileOperation.IMPORT || e.operation === FileOperation.COPY) { + if (e.operation === FileOperation.CREATE || e.operation === FileOperation.COPY) { const addedElement = e.target; const parentResource = resources.dirname(addedElement.resource); const parents = this.model.findAll(parentResource); diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts index 1d04e8a2165..acbf420ce1c 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts @@ -24,7 +24,7 @@ import { IFilesConfiguration, SortOrder } from 'vs/workbench/parts/files/common/ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { FileOperationError, FileOperationResult, IFileService, FileKind } from 'vs/platform/files/common/files'; import { ResourceMap } from 'vs/base/common/map'; -import { DuplicateFileAction, ImportFileAction, IEditableData, IFileViewletState, FileCopiedContext } from 'vs/workbench/parts/files/electron-browser/fileActions'; +import { DuplicateFileAction, AddFilesAction, IEditableData, IFileViewletState, FileCopiedContext } from 'vs/workbench/parts/files/electron-browser/fileActions'; import { IDataSource, ITree, IAccessibilityProvider, IRenderer, ContextMenuEvent, ISorter, IFilter, IDragAndDropData, IDragOverReaction, DRAG_OVER_ACCEPT_BUBBLE_DOWN, DRAG_OVER_ACCEPT_BUBBLE_DOWN_COPY, DRAG_OVER_ACCEPT_BUBBLE_UP, DRAG_OVER_ACCEPT_BUBBLE_UP_COPY, DRAG_OVER_REJECT } from 'vs/base/parts/tree/browser/tree'; import { DesktopDragAndDropData, ExternalElementsDragAndDropData } from 'vs/base/parts/tree/browser/treeDnd'; import { ClickBehavior } from 'vs/base/parts/tree/browser/treeDefaults'; @@ -921,9 +921,9 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop { // Handle dropped files (only support FileStat as target) else if (target instanceof ExplorerItem) { - const importAction = this.instantiationService.createInstance(ImportFileAction, tree, target, null); + const addFilesAction = this.instantiationService.createInstance(AddFilesAction, tree, target, null); - return importAction.run(droppedResources.map(res => res.resource)); + return addFilesAction.run(droppedResources.map(res => res.resource)); } return void 0; diff --git a/src/vs/workbench/services/files/electron-browser/fileService.ts b/src/vs/workbench/services/files/electron-browser/fileService.ts index cce04a6b64f..5ac2af00b64 100644 --- a/src/vs/workbench/services/files/electron-browser/fileService.ts +++ b/src/vs/workbench/services/files/electron-browser/fileService.ts @@ -10,7 +10,7 @@ import * as fs from 'fs'; import * as os from 'os'; import * as crypto from 'crypto'; import * as assert from 'assert'; -import { isParent, FileOperation, FileOperationEvent, IContent, IFileService, IResolveFileOptions, IResolveFileResult, IResolveContentOptions, IFileStat, IStreamContent, FileOperationError, FileOperationResult, IUpdateContentOptions, FileChangeType, IImportResult, FileChangesEvent, ICreateFileOptions, IContentData, ITextSnapshot, IFilesConfiguration } from 'vs/platform/files/common/files'; +import { isParent, FileOperation, FileOperationEvent, IContent, IFileService, IResolveFileOptions, IResolveFileResult, IResolveContentOptions, IFileStat, IStreamContent, FileOperationError, FileOperationResult, IUpdateContentOptions, FileChangeType, FileChangesEvent, ICreateFileOptions, IContentData, ITextSnapshot, IFilesConfiguration } from 'vs/platform/files/common/files'; import { MAX_FILE_SIZE, MAX_HEAP_SIZE } from 'vs/platform/files/node/files'; import { isEqualOrParent } from 'vs/base/common/paths'; import { ResourceMap } from 'vs/base/common/map'; @@ -47,6 +47,42 @@ import product from 'vs/platform/node/product'; import { WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces'; import { shell } from 'electron'; +class BufferPool { + + static _64K = new BufferPool(64 * 1024, 5); + + constructor( + readonly bufferSize: number, + private readonly _capacity: number, + private readonly _free: Buffer[] = [], + ) { } + + acquire(): Buffer { + if (this._free.length === 0) { + return Buffer.allocUnsafe(this.bufferSize); + } else { + return this._free.shift(); + } + } + + release(buf: Buffer): void { + if (this._free.length <= this._capacity) { + this._free.push(buf); + } + } +} + +export interface IEncodingOverride { + parent?: uri; + extension?: string; + encoding: string; +} + +export interface IFileServiceTestOptions { + disableWatcher?: boolean; + encodingOverride?: IEncodingOverride[]; +} + export class FileService implements IFileService { public _serviceBrand: any; @@ -191,12 +227,6 @@ export class FileService implements IFileService { return this._onAfterOperation.event; } - public updateOptions(options: IFileServiceTestOptions): void { - if (options) { - objects.mixin(this.options, options); // overwrite current options - } - } - private setupFileWatching(): void { // dispose old if any @@ -213,10 +243,11 @@ export class FileService implements IFileService { // new watcher: use it if setting tells us so or we run in multi-root environment const configuration = this.configurationService.getValue(); if ((configuration.files && configuration.files.useExperimentalFileWatcher) || workbenchState === WorkbenchState.WORKSPACE) { - this.activeWorkspaceFileChangeWatcher = toDisposable(this.setupNsfwWorkspaceWatching().startWatching()); + const multiRootWatcher = new NsfwWatcherService(this.contextService, this.configurationService, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose); + this.activeWorkspaceFileChangeWatcher = toDisposable(multiRootWatcher.startWatching()); } - // old watcher + // legacy watcher else { let watcherIgnoredPatterns: string[] = []; if (configuration.files && configuration.files.watcherExclude) { @@ -224,25 +255,15 @@ export class FileService implements IFileService { } if (isWindows) { - this.activeWorkspaceFileChangeWatcher = toDisposable(this.setupWin32WorkspaceWatching(watcherIgnoredPatterns).startWatching()); + const legacyWindowsWatcher = new WindowsWatcherService(this.contextService, watcherIgnoredPatterns, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose); + this.activeWorkspaceFileChangeWatcher = toDisposable(legacyWindowsWatcher.startWatching()); } else { - this.activeWorkspaceFileChangeWatcher = toDisposable(this.setupUnixWorkspaceWatching(watcherIgnoredPatterns).startWatching()); + const legacyUnixWatcher = new UnixWatcherService(this.contextService, watcherIgnoredPatterns, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose); + this.activeWorkspaceFileChangeWatcher = toDisposable(legacyUnixWatcher.startWatching()); } } } - private setupWin32WorkspaceWatching(watcherIgnoredPatterns: string[]): WindowsWatcherService { - return new WindowsWatcherService(this.contextService, watcherIgnoredPatterns, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose); - } - - private setupUnixWorkspaceWatching(watcherIgnoredPatterns: string[]): UnixWatcherService { - return new UnixWatcherService(this.contextService, watcherIgnoredPatterns, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose); - } - - private setupNsfwWorkspaceWatching(): NsfwWatcherService { - return new NsfwWatcherService(this.contextService, this.configurationService, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose); - } - public resolveFile(resource: uri, options?: IResolveFileOptions): TPromise { return this.resolve(resource, options); } @@ -512,9 +533,10 @@ export class FileService implements IFileService { } else { // when receiving the first chunk of data we need to create the // decoding stream which is then used to drive the string stream. + const autoGuessEncoding = (options && options.autoGuessEncoding) || this.textResourceConfigurationService.getValue(resource, 'files.autoGuessEncoding'); TPromise.as(encoding.detectEncodingFromBuffer( { buffer: chunkBuffer, bytesRead }, - options && options.autoGuessEncoding || this.configuredAutoGuessEncoding(resource) + autoGuessEncoding )).then(detected => { if (options && options.acceptTextOnly && detected.seemsBinary) { @@ -920,32 +942,6 @@ export class FileService implements IFileService { }); } - public importFile(source: uri, targetFolder: uri): TPromise { - const sourcePath = this.toAbsolutePath(source); - const targetResource = uri.file(paths.join(targetFolder.fsPath, paths.basename(source.fsPath))); - const targetPath = this.toAbsolutePath(targetResource); - - // 1.) resolve - return pfs.stat(sourcePath).then(stat => { - if (stat.isDirectory()) { - return TPromise.wrapError(new Error(nls.localize('foldersCopyError', "Folders cannot be copied into the workspace. Please select individual files to copy them."))); // for now we do not allow to import a folder into a workspace - } - - // 2.) copy - return this.doMoveOrCopyFile(sourcePath, targetPath, true, true).then(exists => { - - // 3.) resolve - return this.resolve(targetResource).then(stat => { - - // Events - this._onAfterOperation.fire(new FileOperationEvent(source, FileOperation.IMPORT, stat)); - - return { isNew: !exists, stat }; - }); - }); - }); - } - public del(resource: uri, useTrash?: boolean): TPromise { if (useTrash) { return this.doMoveItemToTrash(resource); @@ -992,8 +988,7 @@ export class FileService implements IFileService { } private resolve(resource: uri, options: IResolveFileOptions = Object.create(null)): TPromise { - return this.toStatResolver(resource) - .then(model => model.resolve(options)); + return this.toStatResolver(resource).then(model => model.resolve(options)); } private toStatResolver(resource: uri): TPromise { @@ -1043,10 +1038,6 @@ export class FileService implements IFileService { return fileEncoding; } - private configuredAutoGuessEncoding(resource: uri): boolean { - return this.textResourceConfigurationService.getValue(resource, 'files.autoGuessEncoding'); - } - private configuredEncoding(resource: uri): string { return this.textResourceConfigurationService.getValue(resource, 'files.encoding'); } @@ -1181,17 +1172,6 @@ export class FileService implements IFileService { } } -export interface IEncodingOverride { - parent?: uri; - extension?: string; - encoding: string; -} - -export interface IFileServiceTestOptions { - disableWatcher?: boolean; - encodingOverride?: IEncodingOverride[]; -} - function etag(stat: fs.Stats): string; function etag(size: number, mtime: number): string; function etag(arg1: any, arg2?: any): string { @@ -1208,33 +1188,6 @@ function etag(arg1: any, arg2?: any): string { return `"${crypto.createHash('sha1').update(String(size) + String(mtime)).digest('hex')}"`; } -class BufferPool { - - static _64K = new BufferPool(64 * 1024, 5); - - constructor( - readonly bufferSize: number, - private readonly _capacity: number, - private readonly _free: Buffer[] = [], - ) { - // - } - - acquire(): Buffer { - if (this._free.length === 0) { - return Buffer.allocUnsafe(this.bufferSize); - } else { - return this._free.shift(); - } - } - - release(buf: Buffer): void { - if (this._free.length <= this._capacity) { - this._free.push(buf); - } - } -} - export class StatResolver { private name: string; private etag: string; diff --git a/src/vs/workbench/services/files/electron-browser/remoteFileService.ts b/src/vs/workbench/services/files/electron-browser/remoteFileService.ts index bfe2289123d..abc97ccf5b6 100644 --- a/src/vs/workbench/services/files/electron-browser/remoteFileService.ts +++ b/src/vs/workbench/services/files/electron-browser/remoteFileService.ts @@ -6,7 +6,7 @@ import URI from 'vs/base/common/uri'; import { FileService } from 'vs/workbench/services/files/electron-browser/fileService'; -import { IContent, IStreamContent, IFileStat, IResolveContentOptions, IUpdateContentOptions, IResolveFileOptions, IResolveFileResult, FileOperationEvent, FileOperation, IFileSystemProvider, IStat, FileType2, IImportResult, FileChangesEvent, ICreateFileOptions, FileOperationError, FileOperationResult, ITextSnapshot, snapshotToString } from 'vs/platform/files/common/files'; +import { IContent, IStreamContent, IFileStat, IResolveContentOptions, IUpdateContentOptions, IResolveFileOptions, IResolveFileResult, FileOperationEvent, FileOperation, IFileSystemProvider, IStat, FileType2, FileChangesEvent, ICreateFileOptions, FileOperationError, FileOperationResult, ITextSnapshot, snapshotToString } from 'vs/platform/files/common/files'; import { TPromise } from 'vs/base/common/winjs.base'; import { posix } from 'path'; import { IDisposable } from 'vs/base/common/lifecycle'; @@ -430,15 +430,6 @@ export class RemoteFileService extends FileService { }); } - importFile(source: URI, targetFolder: URI): TPromise { - if (source.scheme === targetFolder.scheme && source.scheme === Schemas.file) { - return super.importFile(source, targetFolder); - } else { - const target = targetFolder.with({ path: posix.join(targetFolder.path, posix.basename(source.path)) }); - return this.copyFile(source, target, false).then(stat => ({ stat, isNew: false })); - } - } - copyFile(source: URI, target: URI, overwrite?: boolean): TPromise { if (source.scheme === target.scheme && source.scheme === Schemas.file) { return super.copyFile(source, target, overwrite); diff --git a/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts b/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts index 959d774f9d9..2da2215a85f 100644 --- a/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts +++ b/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts @@ -426,36 +426,18 @@ suite('FileService', () => { }); }); - test('importFile', function () { - let event: FileOperationEvent; - const toDispose = service.onAfterOperation(e => { - event = e; - }); - - return service.resolveFile(uri.file(path.join(testDir, 'deep'))).then(target => { - const resource = uri.file(require.toUrl('./fixtures/service/index.html')); - return service.importFile(resource, target.resource).then(res => { - assert.equal(res.isNew, true); - assert.equal(fs.existsSync(res.stat.resource.fsPath), true); - - assert.ok(event); - assert.equal(event.resource.fsPath, resource.fsPath); - assert.equal(event.operation, FileOperation.IMPORT); - assert.equal(event.target.resource.fsPath, res.stat.resource.fsPath); - toDispose.dispose(); - }); - }); - }); - - test('importFile - MIX CASE', function () { + test('copyFile - MIX CASE', function () { return service.resolveFile(uri.file(path.join(testDir, 'index.html'))).then(source => { return service.rename(source.resource, 'CONWAY.js').then(renamed => { // index.html => CONWAY.js assert.equal(fs.existsSync(renamed.resource.fsPath), true); assert.ok(fs.readdirSync(testDir).some(f => f === 'CONWAY.js')); return service.resolveFile(uri.file(path.join(testDir, 'deep', 'conway.js'))).then(source => { - return service.importFile(source.resource, uri.file(testDir)).then(res => { // CONWAY.js => conway.js - assert.equal(fs.existsSync(res.stat.resource.fsPath), true); + const targetParent = uri.file(testDir); + const target = targetParent.with({ path: path.posix.join(targetParent.path, path.posix.basename(source.resource.path)) }); + + return service.copyFile(source.resource, target, true).then(res => { // CONWAY.js => conway.js + assert.equal(fs.existsSync(res.resource.fsPath), true); assert.ok(fs.readdirSync(testDir).some(f => f === 'conway.js')); }); }); @@ -463,48 +445,12 @@ suite('FileService', () => { }); }); - test('importFile - overwrite folder with file', function () { - let createEvent: FileOperationEvent; - let importEvent: FileOperationEvent; - let deleteEvent: FileOperationEvent; - const toDispose = service.onAfterOperation(e => { - if (e.operation === FileOperation.CREATE) { - createEvent = e; - } else if (e.operation === FileOperation.DELETE) { - deleteEvent = e; - } else if (e.operation === FileOperation.IMPORT) { - importEvent = e; - } - }); - - return service.resolveFile(uri.file(testDir)).then(parent => { - const folderResource = uri.file(path.join(parent.resource.fsPath, 'conway.js')); - return service.createFolder(folderResource).then(f => { - const resource = uri.file(path.join(testDir, 'deep', 'conway.js')); - return service.importFile(resource, uri.file(testDir)).then(res => { - assert.equal(fs.existsSync(res.stat.resource.fsPath), true); - assert.ok(fs.readdirSync(testDir).some(f => f === 'conway.js')); - assert.ok(fs.statSync(res.stat.resource.fsPath).isFile); - - assert.ok(createEvent); - assert.ok(deleteEvent); - assert.ok(importEvent); - - assert.equal(importEvent.resource.fsPath, resource.fsPath); - assert.equal(importEvent.target.resource.fsPath, res.stat.resource.fsPath); - - assert.equal(deleteEvent.resource.fsPath, folderResource.fsPath); - - toDispose.dispose(); - }); - }); - }); - }); - - test('importFile - same file', function () { + test('copyFile - same file', function () { return service.resolveFile(uri.file(path.join(testDir, 'index.html'))).then(source => { - return service.importFile(source.resource, uri.file(path.dirname(source.resource.fsPath))).then(imported => { - assert.equal(imported.stat.size, source.size); + const targetParent = uri.file(path.dirname(source.resource.fsPath)); + const target = targetParent.with({ path: path.posix.join(targetParent.path, path.posix.basename(source.resource.path)) }); + return service.copyFile(source.resource, target, true).then(copied => { + assert.equal(copied.size, source.size); }); }); }); diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 1fea905ffe0..5ad987e0651 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -32,7 +32,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { IEditorGroupService, GroupArrangement, GroupOrientation, IEditorTabOptions, IMoveOptions } from 'vs/workbench/services/group/common/groupService'; import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService'; -import { FileOperationEvent, IFileService, IResolveContentOptions, FileOperationError, IFileStat, IResolveFileResult, IImportResult, FileChangesEvent, IResolveFileOptions, IContent, IUpdateContentOptions, IStreamContent, ICreateFileOptions, ITextSnapshot } from 'vs/platform/files/common/files'; +import { FileOperationEvent, IFileService, IResolveContentOptions, FileOperationError, IFileStat, IResolveFileResult, FileChangesEvent, IResolveFileOptions, IContent, IUpdateContentOptions, IStreamContent, ICreateFileOptions, ITextSnapshot } from 'vs/platform/files/common/files'; import { IModelService } from 'vs/editor/common/services/modelService'; import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl'; import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; @@ -805,10 +805,6 @@ export class TestFileService implements IFileService { return TPromise.as(null); } - importFile(source: URI, targetFolder: URI): TPromise { - return TPromise.as(null); - } - watchFileChanges(resource: URI): void { }