Merge from vscode 2b0b9136329c181a9e381463a1f7dc3a2d105a34 (#4880)

This commit is contained in:
Karl Burtram
2019-04-05 10:09:18 -07:00
committed by GitHub
parent 9bd7e30d18
commit cb5bcf2248
433 changed files with 8915 additions and 8361 deletions

View File

@@ -23,7 +23,7 @@ import { IModelService } from 'vs/editor/common/services/modelService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { RunOnceScheduler, timeout } from 'vs/base/common/async';
import { ITextBufferFactory } from 'vs/editor/common/model';
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
import { hash } from 'vs/base/common/hash';
import { createTextBufferFactory } from 'vs/editor/common/model/textModel';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { isLinux } from 'vs/base/common/platform';
@@ -88,7 +88,6 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
@IBackupFileService private readonly backupFileService: IBackupFileService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IHashService private readonly hashService: IHashService,
@ILogService private readonly logService: ILogService
) {
super(modelService, modeService);
@@ -215,7 +214,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
// Unset flags
const undo = this.setDirty(false);
let loadPromise: Promise<any>;
let loadPromise: Promise<unknown>;
if (soft) {
loadPromise = Promise.resolve();
} else {
@@ -734,7 +733,6 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
this._onDidStateChange.fire(StateChange.SAVED);
// Telemetry
let telemetryPromise: Thenable<void>;
const settingsType = this.getTypeIfSettings();
if (settingsType) {
/* __GDPR__
@@ -743,22 +741,16 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
}
*/
this.telemetryService.publicLog('settingsWritten', { settingsType }); // Do not log write to user settings.json and .vscode folder as a filePUT event as it ruins our JSON usage data
telemetryPromise = Promise.resolve();
} else {
telemetryPromise = this.getTelemetryData(options.reason).then(data => {
/* __GDPR__
/* __GDPR__
"filePUT" : {
"${include}": [
"${FileTelemetryData}"
]
}
*/
this.telemetryService.publicLog('filePUT', data);
});
this.telemetryService.publicLog('filePUT', this.getTelemetryData(options.reason));
}
return telemetryPromise;
}, error => {
if (!error) {
error = new Error('Unknown Save Error'); // TODO@remote we should never get null as error (https://github.com/Microsoft/vscode/issues/55051)
@@ -824,32 +816,30 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
return '';
}
private getTelemetryData(reason: number | undefined): Thenable<object> {
return this.hashService.createSHA1(this.resource.fsPath).then(hashedPath => {
const ext = extname(this.resource);
const fileName = basename(this.resource);
const telemetryData = {
mimeType: guessMimeTypes(this.resource.fsPath).join(', '),
ext,
path: hashedPath,
reason
};
private getTelemetryData(reason: number | undefined): object {
const ext = extname(this.resource);
const fileName = basename(this.resource);
const telemetryData = {
mimeType: guessMimeTypes(this.resource.fsPath).join(', '),
ext,
path: hash(this.resource.fsPath),
reason
};
if (ext === '.json' && TextFileEditorModel.WHITELIST_JSON.indexOf(fileName) > -1) {
telemetryData['whitelistedjson'] = fileName;
if (ext === '.json' && TextFileEditorModel.WHITELIST_JSON.indexOf(fileName) > -1) {
telemetryData['whitelistedjson'] = fileName;
}
/* __GDPR__FRAGMENT__
"FileTelemetryData" : {
"mimeType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"ext": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"path": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"whitelistedjson": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
/* __GDPR__FRAGMENT__
"FileTelemetryData" : {
"mimeType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"ext": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"path": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"whitelistedjson": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
return telemetryData;
});
*/
return telemetryData;
}
private doTouch(versionId: number): Promise<void> {
@@ -918,7 +908,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
}
}
private onSaveError(error: any): void {
private onSaveError(error: Error): void {
// Prepare handler
if (!TextFileEditorModel.saveErrorHandler) {
@@ -1151,7 +1141,7 @@ class DefaultSaveErrorHandler implements ISaveErrorHandler {
constructor(@INotificationService private readonly notificationService: INotificationService) { }
onSaveError(error: any, model: TextFileEditorModel): void {
onSaveError(error: Error, model: TextFileEditorModel): void {
this.notificationService.error(nls.localize('genericSaveError', "Failed to save '{0}': {1}", basename(model.getResource()), toErrorMessage(error, false)));
}
}

View File

@@ -22,7 +22,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel';
import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
import { ResourceMap } from 'vs/base/common/map';
import { Schemas } from 'vs/base/common/network';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
@@ -50,7 +50,7 @@ export interface IBackupResult {
*/
export class TextFileService extends Disposable implements ITextFileService {
_serviceBrand: any;
_serviceBrand: ServiceIdentifier<any>;
private readonly _onAutoSaveConfigurationChange: Emitter<IAutoSaveConfiguration> = this._register(new Emitter<IAutoSaveConfiguration>());
get onAutoSaveConfigurationChange(): Event<IAutoSaveConfiguration> { return this._onAutoSaveConfigurationChange.event; }
@@ -118,7 +118,7 @@ export class TextFileService extends Disposable implements ITextFileService {
isReadonly: streamContent.isReadonly,
size: streamContent.size,
value: res
} as IRawTextContent;
};
});
});
}
@@ -292,7 +292,7 @@ export class TextFileService extends Disposable implements ITextFileService {
}
private backupBeforeShutdown(dirtyToBackup: URI[], textFileEditorModelManager: ITextFileEditorModelManager, reason: ShutdownReason): Promise<IBackupResult> {
return this.windowsService.getWindowCount().then(windowCount => {
return this.windowsService.getWindowCount().then<IBackupResult>(windowCount => {
// When quit is requested skip the confirm callback and attempt to backup all workspaces.
// When quit is not requested the confirm callback should be shown when the window being
@@ -534,7 +534,7 @@ export class TextFileService extends Disposable implements ITextFileService {
saveAll(includeUntitled?: boolean, options?: ISaveOptions): Promise<ITextFileOperationResult>;
saveAll(resources: URI[], options?: ISaveOptions): Promise<ITextFileOperationResult>;
saveAll(arg1?: any, options?: ISaveOptions): Promise<ITextFileOperationResult> {
saveAll(arg1?: boolean | URI[], options?: ISaveOptions): Promise<ITextFileOperationResult> {
// get all dirty
let toSave: URI[] = [];
@@ -649,9 +649,7 @@ export class TextFileService extends Disposable implements ITextFileService {
})).then(r => ({ results: mapResourceToResult.values() }));
}
private getFileModels(resources?: URI[]): ITextFileEditorModel[];
private getFileModels(resource?: URI): ITextFileEditorModel[];
private getFileModels(arg1?: any): ITextFileEditorModel[] {
private getFileModels(arg1?: URI | URI[]): ITextFileEditorModel[] {
if (Array.isArray(arg1)) {
const models: ITextFileEditorModel[] = [];
(<URI[]>arg1).forEach(resource => {
@@ -664,10 +662,8 @@ export class TextFileService extends Disposable implements ITextFileService {
return this._models.getAll(<URI>arg1);
}
private getDirtyFileModels(resources?: URI[]): ITextFileEditorModel[];
private getDirtyFileModels(resource?: URI): ITextFileEditorModel[];
private getDirtyFileModels(arg1?: any): ITextFileEditorModel[] {
return this.getFileModels(arg1).filter(model => model.isDirty());
private getDirtyFileModels(resources?: URI | URI[]): ITextFileEditorModel[] {
return this.getFileModels(resources).filter(model => model.isDirty());
}
saveAs(resource: URI, target?: URI, options?: ISaveOptions): Promise<URI | undefined> {
@@ -748,7 +744,7 @@ export class TextFileService extends Disposable implements ITextFileService {
// Otherwise create the target file empty if it does not exist already and resolve it from there
else {
targetModelResolver = this.fileService.exists(target).then<any>(exists => {
targetModelResolver = this.fileService.exists(target).then(exists => {
targetExists = exists;
// create target model adhoc if file does not exist yet
@@ -756,7 +752,7 @@ export class TextFileService extends Disposable implements ITextFileService {
return this.fileService.updateContent(target, '');
}
return undefined;
return Promise.resolve(undefined);
}).then(() => this.models.loadOrCreate(target));
}
@@ -899,13 +895,13 @@ export class TextFileService extends Disposable implements ITextFileService {
}
move(source: URI, target: URI, overwrite?: boolean): Promise<void> {
const waitForPromises: Promise<any>[] = [];
const waitForPromises: Promise<unknown>[] = [];
// Event
this._onWillMove.fire({
oldResource: source,
newResource: target,
waitUntil(promise: Promise<any>) {
waitUntil(promise: Promise<unknown>) {
waitForPromises.push(promise.then(undefined, errors.onUnexpectedError));
}
});
@@ -916,7 +912,7 @@ export class TextFileService extends Disposable implements ITextFileService {
return Promise.all(waitForPromises).then(() => {
// Handle target models if existing (if target URI is a folder, this can be multiple)
let handleTargetModelPromise: Promise<any> = Promise.resolve();
let handleTargetModelPromise: Promise<unknown> = Promise.resolve();
const dirtyTargetModels = this.getDirtyFileModels().filter(model => isEqualOrParent(model.getResource(), target, false /* do not ignorecase, see https://github.com/Microsoft/vscode/issues/56384 */));
if (dirtyTargetModels.length) {
handleTargetModelPromise = this.revertAll(dirtyTargetModels.map(targetModel => targetModel.getResource()), { soft: true });
@@ -925,7 +921,7 @@ export class TextFileService extends Disposable implements ITextFileService {
return handleTargetModelPromise.then(() => {
// Handle dirty source models if existing (if source URI is a folder, this can be multiple)
let handleDirtySourceModels: Promise<any>;
let handleDirtySourceModels: Promise<unknown>;
const dirtySourceModels = this.getDirtyFileModels().filter(model => isEqualOrParent(model.getResource(), source, !platform.isLinux /* ignorecase */));
const dirtyTargetModels: URI[] = [];
if (dirtySourceModels.length) {

View File

@@ -265,7 +265,7 @@ export interface IResolvedTextFileEditorModel extends ITextFileEditorModel {
export interface IWillMoveEvent {
oldResource: URI;
newResource: URI;
waitUntil(p: Promise<any>): void;
waitUntil(p: Promise<unknown>): void;
}
export interface ITextFileService extends IDisposable {