提交 9ee60773 编写于 作者: M Matt Bierner

Strict null work in extHost

上级 d18d0edc
......@@ -19,7 +19,7 @@ export interface LanguageFilter {
export type LanguageSelector = string | LanguageFilter | Array<string | LanguageFilter>;
export function score(selector: LanguageSelector, candidateUri: URI, candidateLanguage: string, candidateIsSynchronized: boolean): number {
export function score(selector: LanguageSelector | undefined, candidateUri: URI, candidateLanguage: string, candidateIsSynchronized: boolean): number {
if (Array.isArray(selector)) {
// array -> take max individual value
......
......@@ -655,7 +655,7 @@ export interface ExtHostDiagnosticsShape {
}
export interface ExtHostDocumentContentProvidersShape {
$provideTextDocumentContent(handle: number, uri: UriComponents): Promise<string>;
$provideTextDocumentContent(handle: number, uri: UriComponents): Promise<string | null | undefined>;
}
export interface IModelAddedData {
......@@ -961,7 +961,7 @@ export interface ExtHostTerminalServiceShape {
}
export interface ExtHostSCMShape {
$provideOriginalResource(sourceControlHandle: number, uri: UriComponents, token: CancellationToken): Promise<UriComponents>;
$provideOriginalResource(sourceControlHandle: number, uri: UriComponents, token: CancellationToken): Promise<UriComponents | null>;
$onInputBoxValueChange(sourceControlHandle: number, value: string): void;
$executeResourceCommand(sourceControlHandle: number, groupHandle: number, handle: number): Promise<void>;
$validateInput(sourceControlHandle: number, value: string, cursorPosition: number): Promise<[string, number] | undefined>;
......
......@@ -45,7 +45,7 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro
this._documentContentProviders.set(handle, provider);
this._proxy.$registerTextContentProvider(handle, scheme);
let subscription: IDisposable;
let subscription: IDisposable | undefined;
if (typeof provider.onDidChange === 'function') {
subscription = provider.onDidChange(uri => {
if (uri.scheme !== scheme) {
......@@ -54,6 +54,9 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro
}
if (this._documentsAndEditors.getDocument(uri.toString())) {
this.$provideTextDocumentContent(handle, uri).then(value => {
if (!value) {
return;
}
const document = this._documentsAndEditors.getDocument(uri.toString());
if (!document) {
......@@ -84,7 +87,7 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro
});
}
$provideTextDocumentContent(handle: number, uri: UriComponents): Promise<string> {
$provideTextDocumentContent(handle: number, uri: UriComponents): Promise<string | null | undefined> {
const provider = this._documentContentProviders.get(handle);
if (!provider) {
return Promise.reject(new Error(`unsupported uri-scheme: ${uri.scheme}`));
......
......@@ -72,7 +72,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
private _deliverEventAsyncAndBlameBadListeners([listener, thisArg, extension]: Listener, stubEvent: vscode.TextDocumentWillSaveEvent): Promise<any> {
const errors = this._badListeners.get(listener);
if (errors > this._thresholds.errors) {
if (typeof errors === 'number' && errors > this._thresholds.errors) {
// bad listener - ignore
return Promise.resolve(false);
}
......@@ -90,7 +90,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
const errors = this._badListeners.get(listener);
this._badListeners.set(listener, !errors ? 1 : errors + 1);
if (errors > this._thresholds.errors) {
if (typeof errors === 'number' && errors > this._thresholds.errors) {
this._logService.info(`onWillSaveTextDocument-listener from extension '${extension.identifier.value}' will now be IGNORED because of timeouts and/or errors`);
}
}
......
......@@ -56,7 +56,7 @@ export class ExtHostDocuments implements ExtHostDocumentsShape {
return this._documentsAndEditors.allDocuments();
}
public getDocumentData(resource: vscode.Uri): ExtHostDocumentData {
public getDocumentData(resource: vscode.Uri): ExtHostDocumentData | undefined {
if (!resource) {
return undefined;
}
......
......@@ -81,13 +81,13 @@ class ExtensionMemento implements IExtensionMemento {
class ExtensionStoragePath {
private readonly _workspace: IStaticWorkspaceData;
private readonly _workspace?: IStaticWorkspaceData;
private readonly _environment: IEnvironment;
private readonly _ready: Promise<string>;
private _value: string;
private readonly _ready: Promise<string | undefined>;
private _value?: string;
constructor(workspace: IStaticWorkspaceData, environment: IEnvironment) {
constructor(workspace: IStaticWorkspaceData | undefined, environment: IEnvironment) {
this._workspace = workspace;
this._environment = environment;
this._ready = this._getOrCreateWorkspaceStoragePath().then(value => this._value = value);
......@@ -97,7 +97,7 @@ class ExtensionStoragePath {
return this._ready;
}
workspaceValue(extension: IExtensionDescription): string {
workspaceValue(extension: IExtensionDescription): string | undefined {
if (this._value) {
return path.join(this._value, extension.identifier.value);
}
......@@ -108,7 +108,7 @@ class ExtensionStoragePath {
return path.join(this._environment.globalStorageHome.fsPath, extension.identifier.value.toLowerCase());
}
private async _getOrCreateWorkspaceStoragePath(): Promise<string> {
private async _getOrCreateWorkspaceStoragePath(): Promise<string | undefined> {
if (!this._workspace) {
return Promise.resolve(undefined);
}
......@@ -493,7 +493,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
return this._handleWorkspaceContainsEagerExtensions(workspaceProvider.workspace);
}
private _handleWorkspaceContainsEagerExtensions(workspace: IWorkspace): Promise<void> {
private _handleWorkspaceContainsEagerExtensions(workspace: IWorkspace | undefined): Promise<void> {
if (!workspace || workspace.folders.length === 0) {
return Promise.resolve(undefined);
}
......@@ -567,7 +567,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
.then(undefined, err => console.error(err));
}, ExtHostExtensionService.WORKSPACE_CONTAINS_TIMEOUT);
let exists: boolean;
let exists: boolean = false;
try {
exists = await searchP;
} catch (err) {
......@@ -608,8 +608,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
}
// Require the test runner via node require from the provided path
let testRunner: ITestRunner;
let requireError: Error;
let testRunner: ITestRunner | undefined;
let requireError: Error | undefined;
try {
testRunner = <any>require.__$__nodeRequire(this._initData.environment.extensionTestsPath);
} catch (error) {
......@@ -619,7 +619,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
// Execute the runner if it follows our spec
if (testRunner && typeof testRunner.run === 'function') {
return new Promise<void>((c, e) => {
testRunner.run(this._initData.environment.extensionTestsPath, (error, failures) => {
testRunner!.run(this._initData.environment.extensionTestsPath, (error, failures) => {
if (error) {
e(error.toString());
} else {
......
......@@ -499,7 +499,7 @@ class RenameAdapter {
private readonly _provider: vscode.RenameProvider
) { }
provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto> {
provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto | undefined> {
let doc = this._documents.getDocumentData(resource).document;
let pos = typeConvert.Position.to(position);
......@@ -520,7 +520,7 @@ class RenameAdapter {
});
}
resolveRenameLocation(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.RenameLocation & modes.Rejection> {
resolveRenameLocation(resource: URI, position: IPosition, token: CancellationToken): Promise<(modes.RenameLocation & modes.Rejection) | undefined> {
if (typeof this._provider.prepareRename !== 'function') {
return Promise.resolve(undefined);
}
......@@ -530,7 +530,7 @@ class RenameAdapter {
return asPromise(() => this._provider.prepareRename(doc, pos, token)).then(rangeOrLocation => {
let range: vscode.Range;
let range: vscode.Range | undefined;
let text: string;
if (Range.isRange(rangeOrLocation)) {
range = rangeOrLocation;
......@@ -670,7 +670,7 @@ class SuggestAdapter {
this._cache.delete(id);
}
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, defaultRange: vscode.Range, _id: number, _parentId: number): SuggestionDto {
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, defaultRange: vscode.Range, _id: number, _parentId: number): SuggestionDto | undefined {
if (typeof item.label !== 'string' || item.label.length === 0) {
console.warn('INVALID text edit -> must have at least a label');
return undefined;
......@@ -930,7 +930,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
private static _handlePool: number = 0;
private readonly _schemeTransformer: ISchemeTransformer;
private readonly _schemeTransformer: ISchemeTransformer | null;
private _proxy: MainThreadLanguageFeaturesShape;
private _documents: ExtHostDocuments;
private _commands: ExtHostCommands;
......@@ -941,7 +941,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
constructor(
mainContext: IMainContext,
schemeTransformer: ISchemeTransformer,
schemeTransformer: ISchemeTransformer | null,
documents: ExtHostDocuments,
commands: ExtHostCommands,
heapMonitor: ExtHostHeapService,
......
......@@ -24,9 +24,10 @@ export class ExtHostLanguages {
return this._proxy.$getLanguages();
}
changeLanguage(uri: vscode.Uri, languageId: string): Promise<vscode.TextDocument> {
changeLanguage(uri: vscode.Uri, languageId: string): Promise<vscode.TextDocument | undefined> {
return this._proxy.$changeLanguage(uri, languageId).then(() => {
return this._documents.getDocumentData(uri).document;
const data = this._documents.getDocumentData(uri);
return data ? data.document : undefined;
});
}
}
......@@ -27,11 +27,11 @@ export class ExtHostProgress implements ExtHostProgressShape {
const { title, location, cancellable } = options;
const source = localize('extensionSource', "{0} (Extension)", extension.displayName || extension.name);
this._proxy.$startProgress(handle, { location: ProgressLocation.from(location), title, source, cancellable });
return this._withProgress(handle, task, cancellable);
return this._withProgress(handle, task, !!cancellable);
}
private _withProgress<R>(handle: number, task: (progress: Progress<IProgressStep>, token: CancellationToken) => Thenable<R>, cancellable: boolean): Thenable<R> {
let source: CancellationTokenSource;
let source: CancellationTokenSource | undefined;
if (cancellable) {
source = new CancellationTokenSource();
this._mapHandleToCancellationSource.set(handle, source);
......@@ -48,7 +48,7 @@ export class ExtHostProgress implements ExtHostProgressShape {
let p: Thenable<R>;
try {
p = task(new ProgressCallback(this._proxy, handle), cancellable ? source.token : CancellationToken.None);
p = task(new ProgressCallback(this._proxy, handle), cancellable && source ? source.token : CancellationToken.None);
} catch (err) {
progressEnd(handle);
throw err;
......
......@@ -35,12 +35,12 @@ export class ExtHostSearch implements ExtHostSearchShape {
private _handlePool: number = 0;
private _internalFileSearchHandle: number;
private _internalFileSearchProvider: SearchService;
private _internalFileSearchProvider: SearchService | null;
private _fileSearchManager: FileSearchManager;
private _fileIndexSearchManager: FileIndexSearchManager;
constructor(mainContext: IMainContext, private _schemeTransformer: ISchemeTransformer, private _logService: ILogService, private _extfs = extfs) {
constructor(mainContext: IMainContext, private _schemeTransformer: ISchemeTransformer | null, private _logService: ILogService, private _extfs = extfs) {
this._proxy = mainContext.getProxy(MainContext.MainThreadSearch);
this._fileSearchManager = new FileSearchManager();
this._fileIndexSearchManager = new FileIndexSearchManager();
......
......@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Emitter, Event } from 'vs/base/common/event';
import * as arrays from 'vs/base/common/arrays';
import { ExtHostEditorsShape, IEditorPropertiesChangeData, IMainContext, ITextDocumentShowOptions, ITextEditorPositionData, MainContext, MainThreadTextEditorsShape } from 'vs/workbench/api/node/extHost.protocol';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
import { ExtHostTextEditor, TextEditorDecorationType } from 'vs/workbench/api/node/extHostTextEditor';
......@@ -106,7 +107,7 @@ export class ExtHostEditors implements ExtHostEditorsShape {
textEditor._acceptSelections(selections);
}
if (data.visibleRanges) {
const visibleRanges = data.visibleRanges.map(TypeConverters.Range.to);
const visibleRanges = arrays.coalesce(data.visibleRanges.map(TypeConverters.Range.to));
textEditor._acceptVisibleRanges(visibleRanges);
}
......@@ -127,7 +128,7 @@ export class ExtHostEditors implements ExtHostEditorsShape {
});
}
if (data.visibleRanges) {
const visibleRanges = data.visibleRanges.map(TypeConverters.Range.to);
const visibleRanges = arrays.coalesce(data.visibleRanges.map(TypeConverters.Range.to));
this._onDidChangeTextEditorVisibleRanges.fire({
textEditor,
visibleRanges
......
......@@ -182,12 +182,12 @@ export namespace ViewColumn {
return ACTIVE_GROUP; // default is always the active group
}
export function to(position?: EditorViewColumn): vscode.ViewColumn | undefined {
export function to(position: EditorViewColumn): vscode.ViewColumn {
if (typeof position === 'number' && position >= 0) {
return position + 1; // adjust to index (ViewColumn.ONE => 1)
}
return undefined;
throw new Error(`invalid 'EditorViewColumn'`);
}
}
......@@ -908,13 +908,13 @@ export namespace EndOfLine {
}
export namespace ProgressLocation {
export function from(loc: vscode.ProgressLocation): MainProgressLocation | undefined {
export function from(loc: vscode.ProgressLocation): MainProgressLocation {
switch (loc) {
case types.ProgressLocation.SourceControl: return MainProgressLocation.Scm;
case types.ProgressLocation.Window: return MainProgressLocation.Window;
case types.ProgressLocation.Notification: return MainProgressLocation.Notification;
}
return undefined;
throw new Error(`Unknown 'ProgressLocation'`);
}
}
......@@ -986,7 +986,7 @@ export namespace GlobPattern {
export namespace LanguageSelector {
export function from(selector: vscode.DocumentSelector): languageSelector.LanguageSelector | undefined {
export function from(selector: vscode.DocumentSelector | undefined): languageSelector.LanguageSelector | undefined {
if (!selector) {
return undefined;
} else if (Array.isArray(selector)) {
......
......@@ -114,7 +114,7 @@ class UntitledEditorInputFactory implements IEditorInputFactory {
@ITextFileService private readonly textFileService: ITextFileService
) { }
serialize(editorInput: EditorInput): string {
serialize(editorInput: EditorInput): string | null {
if (!this.textFileService.isHotExitEnabled) {
return null; // never restore untitled unless hot exit is enabled
}
......@@ -165,7 +165,7 @@ interface ISerializedSideBySideEditorInput {
// Register Side by Side Editor Input Factory
class SideBySideEditorInputFactory implements IEditorInputFactory {
serialize(editorInput: EditorInput): string {
serialize(editorInput: EditorInput): string | null {
const input = <SideBySideEditorInput>editorInput;
if (input.details && input.master) {
......@@ -193,7 +193,7 @@ class SideBySideEditorInputFactory implements IEditorInputFactory {
return null;
}
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput {
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput | null {
const deserialized: ISerializedSideBySideEditorInput = JSON.parse(serializedEditorInput);
const registry = Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories);
......@@ -261,7 +261,7 @@ export class QuickOpenActionContributor extends ActionBarContributor {
return actions;
}
private getEntry(context: any): IEditorQuickOpenEntry {
private getEntry(context: any): IEditorQuickOpenEntry | null {
if (!context || !context.element) {
return null;
}
......
......@@ -244,7 +244,7 @@ export class NoTabsTitleControl extends TitleControl {
title = ''; // dont repeat what is already shown
}
this.editorLabel.setResource({ name, description, resource }, { title, italic: !isEditorPinned, extraClasses: ['no-tabs', 'title-label'] });
this.editorLabel.setResource({ name, description, resource: resource || undefined }, { title, italic: !isEditorPinned, extraClasses: ['no-tabs', 'title-label'] });
if (isGroupActive) {
this.editorLabel.element.style.color = this.getColor(TAB_ACTIVE_FOREGROUND);
} else {
......@@ -256,7 +256,7 @@ export class NoTabsTitleControl extends TitleControl {
}
}
private getVerbosity(style: string): Verbosity {
private getVerbosity(style: string | undefined): Verbosity {
switch (style) {
case 'short': return Verbosity.SHORT;
case 'long': return Verbosity.LONG;
......
......@@ -46,7 +46,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
super(id, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, windowService);
}
getTitle(): string {
getTitle(): string | null {
if (this.input) {
return this.input.getName();
}
......@@ -168,7 +168,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
super.saveState();
}
private saveTextResourceEditorViewState(input: EditorInput): void {
private saveTextResourceEditorViewState(input: EditorInput | null): void {
if (!(input instanceof UntitledEditorInput) && !(input instanceof ResourceEditorInput)) {
return; // only enabled for untitled and resource inputs
}
......
......@@ -184,13 +184,13 @@ export interface IEditorInputFactory {
* Returns a string representation of the provided editor input that contains enough information
* to deserialize back to the original editor input from the deserialize() method.
*/
serialize(editorInput: EditorInput): string;
serialize(editorInput: EditorInput): string | null;
/**
* Returns an editor input from the provided serialized form of the editor input. This form matches
* the value returned from the serialize() method.
*/
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput;
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput | null;
}
export interface IUntitledResourceInput extends IBaseResourceInput {
......
......@@ -678,7 +678,7 @@ export class EditorGroup extends Disposable {
this.editors = coalesce(data.editors.map(e => {
const factory = registry.getEditorInputFactory(e.id);
if (factory) {
const editor = factory.deserialize(this.instantiationService, e.value);
const editor = factory.deserialize(this.instantiationService, e.value)!;
this.registerEditorListeners(editor);
this.updateResourceMap(editor, false /* add */);
......
......@@ -899,7 +899,7 @@ export class HistoryService extends Disposable implements IHistoryService {
this.onEditorDispose(input, () => this.removeFromHistory(input), this.editorHistoryListeners);
}
return input;
return input || undefined;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册