Merge from vscode 05fc61ffb1aee9fd19173c32113daed079f9b7bd (#5074)

* Merge from vscode 05fc61ffb1aee9fd19173c32113daed079f9b7bd

* fix tests
This commit is contained in:
Anthony Dresser
2019-04-16 22:11:30 -07:00
committed by GitHub
parent 2f8519cb6b
commit 8956b591f7
217 changed files with 5120 additions and 3926 deletions

View File

@@ -13,25 +13,14 @@ import { startsWithIgnoreCase } from 'vs/base/common/strings';
import { IDisposable } from 'vs/base/common/lifecycle';
import { isEqualOrParent, isEqual } from 'vs/base/common/resources';
import { isUndefinedOrNull } from 'vs/base/common/types';
import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer';
import { VSBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer';
export const IFileService = createDecorator<IFileService>('fileService');
export interface IResourceEncodings {
getWriteEncoding(resource: URI, preferredEncoding?: string): IResourceEncoding;
}
export interface IResourceEncoding {
encoding: string;
hasBOM: boolean;
}
export interface IFileService {
_serviceBrand: ServiceIdentifier<any>;
//#region File System Provider
/**
* An event that is fired when a file system provider is added or removed
*/
@@ -63,13 +52,6 @@ export interface IFileService {
*/
hasCapability(resource: URI, capability: FileSystemProviderCapabilities): boolean;
//#endregion
/**
* Helper to determine read/write encoding for resources.
*/
encoding: IResourceEncodings;
/**
* Allows to listen for file changes. The event will fire for every file within the opened workspace
* (if any) as well as all files that have been watched explicitly using the #watch() API.
@@ -111,18 +93,14 @@ export interface IFileService {
exists(resource: URI): Promise<boolean>;
/**
* Resolve the contents of a file identified by the resource.
*
* The returned object contains properties of the file and the full value as string.
* Read the contents of the provided resource unbuffered.
*/
resolveContent(resource: URI, options?: IResolveContentOptions): Promise<IContent>;
readFile(resource: URI, options?: IReadFileOptions): Promise<IFileContent>;
/**
* Resolve the contents of a file identified by the resource.
*
* The returned object contains properties of the file and the value as a readable stream.
* Read the contents of the provided resource buffered as stream.
*/
resolveStreamContent(resource: URI, options?: IResolveContentOptions): Promise<IStreamContent>;
readFileStream(resource: URI, options?: IReadFileOptions): Promise<IFileStreamContent>;
/**
* Updates the content replacing its previous value.
@@ -228,11 +206,11 @@ export const enum FileSystemProviderCapabilities {
export interface IFileSystemProvider {
readonly capabilities: FileSystemProviderCapabilities;
onDidChangeCapabilities: Event<void>;
readonly onDidChangeCapabilities: Event<void>;
onDidErrorOccur?: Event<Error>; // TODO@ben remove once file watchers are solid
readonly onDidErrorOccur?: Event<Error>; // TODO@ben remove once file watchers are solid
onDidChangeFile: Event<IFileChange[]>;
readonly onDidChangeFile: Event<IFileChange[]>;
watch(resource: URI, opts: IWatchOptions): IDisposable;
stat(resource: URI): Promise<IStat>;
@@ -337,6 +315,13 @@ export function toFileSystemProviderErrorCode(error: Error): FileSystemProviderE
}
export function toFileOperationResult(error: Error): FileOperationResult {
// FileSystemProviderError comes with the result already
if (error instanceof FileOperationError) {
return error.fileOperationResult;
}
// Otherwise try to find from code
switch (toFileSystemProviderErrorCode(error)) {
case FileSystemProviderErrorCode.FileNotFound:
return FileOperationResult.FILE_NOT_FOUND;
@@ -576,8 +561,7 @@ export interface IBaseStatWithMetadata extends IBaseStat {
export interface IFileStat extends IBaseStat {
/**
* The resource is a directory. if {{true}}
* {{encoding}} has no meaning.
* The resource is a directory
*/
isDirectory: boolean;
@@ -608,147 +592,23 @@ export interface IResolveFileResultWithMetadata extends IResolveFileResult {
stat?: IFileStatWithMetadata;
}
/**
* Content and meta information of a file.
*/
export interface IContent extends IBaseStatWithMetadata {
export interface IFileContent extends IBaseStatWithMetadata {
/**
* The content of a text file.
* The content of a file as buffer.
*/
value: string;
value: VSBuffer;
}
export interface IFileStreamContent extends IBaseStatWithMetadata {
/**
* The encoding of the content if known.
* The content of a file as stream.
*/
encoding: string;
value: VSBufferReadableStream;
}
// this should eventually replace IContent such
// that we have a clear separation between content
// and metadata (TODO@Joh, TODO@Ben)
export interface IContentData {
encoding: string;
stream: IStringStream;
}
/**
* A Stream emitting strings.
*/
export interface IStringStream {
on(event: 'data', callback: (chunk: string) => void): void;
on(event: 'error', callback: (err: any) => void): void;
on(event: 'end', callback: () => void): void;
on(event: string, callback: any): void;
}
/**
* Text snapshot that works like an iterator.
* Will try to return chunks of roughly ~64KB size.
* Will return null when finished.
*/
export interface ITextSnapshot {
read(): string | null;
}
/**
* Helper method to convert a snapshot into its full string form.
*/
export function snapshotToString(snapshot: ITextSnapshot): string {
const chunks: string[] = [];
let chunk: string | null;
while (typeof (chunk = snapshot.read()) === 'string') {
chunks.push(chunk);
}
return chunks.join('');
}
export function stringToSnapshot(value: string): ITextSnapshot {
let done = false;
return {
read(): string | null {
if (!done) {
done = true;
return value;
}
return null;
}
};
}
export class TextSnapshotReadable implements VSBufferReadable {
private preambleHandled: boolean;
constructor(private snapshot: ITextSnapshot, private preamble?: string) { }
read(): VSBuffer | null {
let value = this.snapshot.read();
// Handle preamble if provided
if (!this.preambleHandled) {
this.preambleHandled = true;
if (typeof this.preamble === 'string') {
if (typeof value === 'string') {
value = this.preamble + value;
} else {
value = this.preamble;
}
}
}
if (typeof value === 'string') {
return VSBuffer.fromString(value);
}
return null;
}
}
export function toBufferOrReadable(value: string): VSBuffer;
export function toBufferOrReadable(value: ITextSnapshot): VSBufferReadable;
export function toBufferOrReadable(value: string | ITextSnapshot): VSBuffer | VSBufferReadable;
export function toBufferOrReadable(value: string | ITextSnapshot | undefined): VSBuffer | VSBufferReadable | undefined;
export function toBufferOrReadable(value: string | ITextSnapshot | undefined): VSBuffer | VSBufferReadable | undefined {
if (typeof value === 'undefined') {
return undefined;
}
if (typeof value === 'string') {
return VSBuffer.fromString(value);
}
return new TextSnapshotReadable(value);
}
/**
* Streamable content and meta information of a file.
*/
export interface IStreamContent extends IBaseStatWithMetadata {
/**
* The streamable content of a text file.
*/
value: IStringStream;
/**
* The encoding of the content if known.
*/
encoding: string;
}
export interface IResolveContentOptions {
/**
* The optional acceptTextOnly parameter allows to fail this request early if the file
* contents are not textual.
*/
acceptTextOnly?: boolean;
export interface IReadFileOptions {
/**
* The optional etag parameter allows to return early from resolving the resource if
@@ -758,22 +618,25 @@ export interface IResolveContentOptions {
*/
etag?: string;
/**
* The optional encoding parameter allows to specify the desired encoding when resolving
* the contents of the file.
*/
encoding?: string;
/**
* The optional guessEncoding parameter allows to guess encoding from content of the file.
*/
autoGuessEncoding?: boolean;
/**
* Is an integer specifying where to begin reading from in the file. If position is null,
* data will be read from the current file position.
*/
position?: number;
/**
* Is an integer specifying how many bytes to read from the file. By default, all bytes
* will be read.
*/
length?: number;
/**
* If provided, the size of the file will be checked against the limits.
*/
limits?: {
size?: number;
memory?: number;
};
}
export interface IWriteFileOptions {
@@ -789,30 +652,6 @@ export interface IWriteFileOptions {
etag?: string;
}
export interface IWriteTextFileOptions extends IWriteFileOptions {
/**
* The encoding to use when updating a file.
*/
encoding?: string;
/**
* If set to true, will enforce the selected encoding and not perform any detection using BOMs.
*/
overwriteEncoding?: boolean;
/**
* Whether to overwrite a file even if it is readonly.
*/
overwriteReadonly?: boolean;
/**
* Wether to write to the file as elevated (admin) user. When setting this option a prompt will
* ask the user to authenticate as super user.
*/
writeElevated?: boolean;
}
export interface IResolveFileOptions {
/**
@@ -847,7 +686,7 @@ export interface ICreateFileOptions {
}
export class FileOperationError extends Error {
constructor(message: string, public fileOperationResult: FileOperationResult, public options?: IResolveContentOptions & IWriteTextFileOptions & ICreateFileOptions) {
constructor(message: string, public fileOperationResult: FileOperationResult, public options?: IReadFileOptions & IWriteFileOptions & ICreateFileOptions) {
super(message);
}
@@ -857,7 +696,6 @@ export class FileOperationError extends Error {
}
export const enum FileOperationResult {
FILE_IS_BINARY,
FILE_IS_DIRECTORY,
FILE_NOT_FOUND,
FILE_NOT_MODIFIED_SINCE,
@@ -906,247 +744,6 @@ export interface IFilesConfiguration {
};
}
export const SUPPORTED_ENCODINGS: { [encoding: string]: { labelLong: string; labelShort: string; order: number; encodeOnly?: boolean; alias?: string } } = {
utf8: {
labelLong: 'UTF-8',
labelShort: 'UTF-8',
order: 1,
alias: 'utf8bom'
},
utf8bom: {
labelLong: 'UTF-8 with BOM',
labelShort: 'UTF-8 with BOM',
encodeOnly: true,
order: 2,
alias: 'utf8'
},
utf16le: {
labelLong: 'UTF-16 LE',
labelShort: 'UTF-16 LE',
order: 3
},
utf16be: {
labelLong: 'UTF-16 BE',
labelShort: 'UTF-16 BE',
order: 4
},
windows1252: {
labelLong: 'Western (Windows 1252)',
labelShort: 'Windows 1252',
order: 5
},
iso88591: {
labelLong: 'Western (ISO 8859-1)',
labelShort: 'ISO 8859-1',
order: 6
},
iso88593: {
labelLong: 'Western (ISO 8859-3)',
labelShort: 'ISO 8859-3',
order: 7
},
iso885915: {
labelLong: 'Western (ISO 8859-15)',
labelShort: 'ISO 8859-15',
order: 8
},
macroman: {
labelLong: 'Western (Mac Roman)',
labelShort: 'Mac Roman',
order: 9
},
cp437: {
labelLong: 'DOS (CP 437)',
labelShort: 'CP437',
order: 10
},
windows1256: {
labelLong: 'Arabic (Windows 1256)',
labelShort: 'Windows 1256',
order: 11
},
iso88596: {
labelLong: 'Arabic (ISO 8859-6)',
labelShort: 'ISO 8859-6',
order: 12
},
windows1257: {
labelLong: 'Baltic (Windows 1257)',
labelShort: 'Windows 1257',
order: 13
},
iso88594: {
labelLong: 'Baltic (ISO 8859-4)',
labelShort: 'ISO 8859-4',
order: 14
},
iso885914: {
labelLong: 'Celtic (ISO 8859-14)',
labelShort: 'ISO 8859-14',
order: 15
},
windows1250: {
labelLong: 'Central European (Windows 1250)',
labelShort: 'Windows 1250',
order: 16
},
iso88592: {
labelLong: 'Central European (ISO 8859-2)',
labelShort: 'ISO 8859-2',
order: 17
},
cp852: {
labelLong: 'Central European (CP 852)',
labelShort: 'CP 852',
order: 18
},
windows1251: {
labelLong: 'Cyrillic (Windows 1251)',
labelShort: 'Windows 1251',
order: 19
},
cp866: {
labelLong: 'Cyrillic (CP 866)',
labelShort: 'CP 866',
order: 20
},
iso88595: {
labelLong: 'Cyrillic (ISO 8859-5)',
labelShort: 'ISO 8859-5',
order: 21
},
koi8r: {
labelLong: 'Cyrillic (KOI8-R)',
labelShort: 'KOI8-R',
order: 22
},
koi8u: {
labelLong: 'Cyrillic (KOI8-U)',
labelShort: 'KOI8-U',
order: 23
},
iso885913: {
labelLong: 'Estonian (ISO 8859-13)',
labelShort: 'ISO 8859-13',
order: 24
},
windows1253: {
labelLong: 'Greek (Windows 1253)',
labelShort: 'Windows 1253',
order: 25
},
iso88597: {
labelLong: 'Greek (ISO 8859-7)',
labelShort: 'ISO 8859-7',
order: 26
},
windows1255: {
labelLong: 'Hebrew (Windows 1255)',
labelShort: 'Windows 1255',
order: 27
},
iso88598: {
labelLong: 'Hebrew (ISO 8859-8)',
labelShort: 'ISO 8859-8',
order: 28
},
iso885910: {
labelLong: 'Nordic (ISO 8859-10)',
labelShort: 'ISO 8859-10',
order: 29
},
iso885916: {
labelLong: 'Romanian (ISO 8859-16)',
labelShort: 'ISO 8859-16',
order: 30
},
windows1254: {
labelLong: 'Turkish (Windows 1254)',
labelShort: 'Windows 1254',
order: 31
},
iso88599: {
labelLong: 'Turkish (ISO 8859-9)',
labelShort: 'ISO 8859-9',
order: 32
},
windows1258: {
labelLong: 'Vietnamese (Windows 1258)',
labelShort: 'Windows 1258',
order: 33
},
gbk: {
labelLong: 'Simplified Chinese (GBK)',
labelShort: 'GBK',
order: 34
},
gb18030: {
labelLong: 'Simplified Chinese (GB18030)',
labelShort: 'GB18030',
order: 35
},
cp950: {
labelLong: 'Traditional Chinese (Big5)',
labelShort: 'Big5',
order: 36
},
big5hkscs: {
labelLong: 'Traditional Chinese (Big5-HKSCS)',
labelShort: 'Big5-HKSCS',
order: 37
},
shiftjis: {
labelLong: 'Japanese (Shift JIS)',
labelShort: 'Shift JIS',
order: 38
},
eucjp: {
labelLong: 'Japanese (EUC-JP)',
labelShort: 'EUC-JP',
order: 39
},
euckr: {
labelLong: 'Korean (EUC-KR)',
labelShort: 'EUC-KR',
order: 40
},
windows874: {
labelLong: 'Thai (Windows 874)',
labelShort: 'Windows 874',
order: 41
},
iso885911: {
labelLong: 'Latin/Thai (ISO 8859-11)',
labelShort: 'ISO 8859-11',
order: 42
},
koi8ru: {
labelLong: 'Cyrillic (KOI8-RU)',
labelShort: 'KOI8-RU',
order: 43
},
koi8t: {
labelLong: 'Tajik (KOI8-T)',
labelShort: 'KOI8-T',
order: 44
},
gb2312: {
labelLong: 'Simplified Chinese (GB 2312)',
labelShort: 'GB 2312',
order: 45
},
cp865: {
labelLong: 'Nordic DOS (CP 865)',
labelShort: 'CP 865',
order: 46
},
cp850: {
labelLong: 'Western European DOS (CP 850)',
labelShort: 'CP 850',
order: 47
}
};
export enum FileKind {
FILE,
FOLDER,
@@ -1165,20 +762,3 @@ export function etag(mtime: number | undefined, size: number | undefined): strin
return mtime.toString(29) + size.toString(31);
}
// TODO@ben remove traces of legacy file service
export const ILegacyFileService = createDecorator<ILegacyFileService>('legacyFileService');
export interface ILegacyFileService extends IDisposable {
_serviceBrand: any;
encoding: IResourceEncodings;
onAfterOperation: Event<FileOperationEvent>;
registerProvider(scheme: string, provider: IFileSystemProvider): IDisposable;
resolveContent(resource: URI, options?: IResolveContentOptions): Promise<IContent>;
resolveStreamContent(resource: URI, options?: IResolveContentOptions): Promise<IStreamContent>;
}