提交 a92031dc 编写于 作者: M Matt Bierner

Strict null check work in extHost and mainThread language Features

- annotate undefined returned types
- Don't call functions with null or undefined values.
- Refactor _convertCompletionItem so that we don't need to mutate the returned object
- Suppress a type error related to electricCharacters.
上级 6de764fb
......@@ -63,6 +63,7 @@
"./vs/workbench/api/electron-browser/mainThreadFileSystem.ts",
"./vs/workbench/api/electron-browser/mainThreadFileSystemEventService.ts",
"./vs/workbench/api/electron-browser/mainThreadHeapService.ts",
"./vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts",
"./vs/workbench/api/electron-browser/mainThreadLanguages.ts",
"./vs/workbench/api/electron-browser/mainThreadLogService.ts",
"./vs/workbench/api/electron-browser/mainThreadMessageService.ts",
......
......@@ -170,7 +170,7 @@ export interface IDocComment {
/**
* The string that appears on the last line and closes the doc comment (e.g. ' * /').
*/
close: string;
close?: string;
}
/**
......
......@@ -33,7 +33,7 @@ export class BracketElectricCharacterSupport {
this._complexAutoClosePairs = autoClosePairs.filter(pair => pair.open.length > 1 && !!pair.close).map(el => new StandardAutoClosingPairConditional(el));
if (contribution.docComment) {
// IDocComment is legacy, only partially supported
this._complexAutoClosePairs.push(new StandardAutoClosingPairConditional({ open: contribution.docComment.open, close: contribution.docComment.close }));
this._complexAutoClosePairs.push(new StandardAutoClosingPairConditional({ open: contribution.docComment.open, close: contribution.docComment.close || '' }));
}
}
......
......@@ -4592,7 +4592,7 @@ declare namespace monaco.languages {
/**
* The string that appears on the last line and closes the doc comment (e.g. ' * /').
*/
close: string;
close?: string;
}
/**
......
......@@ -137,17 +137,21 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
if (dto) {
dto.forEach(obj => {
this._heapService.trackObject(obj);
this._heapService.trackObject(obj.command);
if (obj.command) {
this._heapService.trackObject(obj.command);
}
});
}
return dto;
});
},
resolveCodeLens: (model: ITextModel, codeLens: modes.ICodeLensSymbol, token: CancellationToken): modes.ICodeLensSymbol | Promise<modes.ICodeLensSymbol> => {
resolveCodeLens: (model: ITextModel, codeLens: modes.ICodeLensSymbol, token: CancellationToken): Promise<modes.ICodeLensSymbol | undefined> => {
return this._proxy.$resolveCodeLens(handle, model.uri, codeLens, token).then(obj => {
if (obj) {
this._heapService.trackObject(obj);
this._heapService.trackObject(obj.command);
if (obj.command) {
this._heapService.trackObject(obj.command);
}
}
return obj;
});
......@@ -269,7 +273,13 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
this._registrations[handle] = modes.CodeActionProviderRegistry.register(typeConverters.LanguageSelector.from(selector), <modes.CodeActionProvider>{
provideCodeActions: (model: ITextModel, rangeOrSelection: EditorRange | Selection, context: modes.CodeActionContext, token: CancellationToken): Promise<modes.CodeAction[]> => {
return this._proxy.$provideCodeActions(handle, model.uri, rangeOrSelection, context, token).then(dto => {
if (dto) { dto.forEach(obj => this._heapService.trackObject(obj.command)); }
if (dto) {
dto.forEach(obj => {
if (obj.command) {
this._heapService.trackObject(obj.command);
}
});
}
return MainThreadLanguageFeatures._reviveCodeActionDto(dto);
});
},
......@@ -321,8 +331,13 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
return MainThreadLanguageFeatures._reviveWorkspaceSymbolDto(result.symbols);
});
},
resolveWorkspaceSymbol: (item: search.IWorkspaceSymbol, token: CancellationToken): Promise<search.IWorkspaceSymbol> => {
return this._proxy.$resolveWorkspaceSymbol(handle, item, token).then(i => MainThreadLanguageFeatures._reviveWorkspaceSymbolDto(i));
resolveWorkspaceSymbol: (item: search.IWorkspaceSymbol, token: CancellationToken): Promise<search.IWorkspaceSymbol | undefined> => {
return this._proxy.$resolveWorkspaceSymbol(handle, item, token).then(i => {
if (i) {
return MainThreadLanguageFeatures._reviveWorkspaceSymbolDto(i);
}
return undefined;
});
}
});
}
......@@ -346,7 +361,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
$registerSuggestSupport(handle: number, selector: ISerializedDocumentFilter[], triggerCharacters: string[], supportsResolveDetails: boolean): void {
this._registrations[handle] = modes.CompletionProviderRegistry.register(typeConverters.LanguageSelector.from(selector), <modes.CompletionItemProvider>{
triggerCharacters,
provideCompletionItems: (model: ITextModel, position: EditorPosition, context: modes.CompletionContext, token: CancellationToken): Promise<modes.CompletionList> => {
provideCompletionItems: (model: ITextModel, position: EditorPosition, context: modes.CompletionContext, token: CancellationToken): Promise<modes.CompletionList | undefined> => {
return this._proxy.$provideCompletionItems(handle, model.uri, position, context, token).then(result => {
if (!result) {
return result;
......@@ -354,7 +369,11 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
return {
suggestions: result.suggestions,
incomplete: result.incomplete,
dispose: () => this._proxy.$releaseCompletionItems(handle, result._id)
dispose: () => {
if (typeof result._id === 'number') {
this._proxy.$releaseCompletionItems(handle, result._id);
}
}
};
});
},
......@@ -372,7 +391,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
signatureHelpTriggerCharacters: metadata.triggerCharacters,
signatureHelpRetriggerCharacters: metadata.retriggerCharacters,
provideSignatureHelp: (model: ITextModel, position: EditorPosition, token: CancellationToken, context: modes.SignatureHelpContext): Promise<modes.SignatureHelp> => {
provideSignatureHelp: (model: ITextModel, position: EditorPosition, token: CancellationToken, context: modes.SignatureHelpContext): Promise<modes.SignatureHelp | undefined> => {
return this._proxy.$provideSignatureHelp(handle, model.uri, position, context, token);
}
});
......@@ -395,8 +414,10 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
},
resolveLink: (link, token) => {
return this._proxy.$resolveDocumentLink(handle, link, token).then(obj => {
MainThreadLanguageFeatures._reviveLinkDTO(obj);
this._heapService.trackObject(obj);
if (obj) {
MainThreadLanguageFeatures._reviveLinkDTO(obj);
this._heapService.trackObject(obj);
}
return obj;
});
}
......@@ -461,46 +482,28 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
// --- configuration
private static _reviveRegExp(regExp: ISerializedRegExp): RegExp {
if (typeof regExp === 'undefined') {
return undefined;
}
if (regExp === null) {
return null;
}
return new RegExp(regExp.pattern, regExp.flags);
}
private static _reviveIndentationRule(indentationRule: ISerializedIndentationRule): IndentationRule {
if (typeof indentationRule === 'undefined') {
return undefined;
}
if (indentationRule === null) {
return null;
}
return {
decreaseIndentPattern: MainThreadLanguageFeatures._reviveRegExp(indentationRule.decreaseIndentPattern),
increaseIndentPattern: MainThreadLanguageFeatures._reviveRegExp(indentationRule.increaseIndentPattern),
indentNextLinePattern: MainThreadLanguageFeatures._reviveRegExp(indentationRule.indentNextLinePattern),
unIndentedLinePattern: MainThreadLanguageFeatures._reviveRegExp(indentationRule.unIndentedLinePattern),
indentNextLinePattern: indentationRule.indentNextLinePattern ? MainThreadLanguageFeatures._reviveRegExp(indentationRule.indentNextLinePattern) : undefined,
unIndentedLinePattern: indentationRule.unIndentedLinePattern ? MainThreadLanguageFeatures._reviveRegExp(indentationRule.unIndentedLinePattern) : undefined,
};
}
private static _reviveOnEnterRule(onEnterRule: ISerializedOnEnterRule): OnEnterRule {
return {
beforeText: MainThreadLanguageFeatures._reviveRegExp(onEnterRule.beforeText),
afterText: MainThreadLanguageFeatures._reviveRegExp(onEnterRule.afterText),
oneLineAboveText: MainThreadLanguageFeatures._reviveRegExp(onEnterRule.oneLineAboveText),
afterText: onEnterRule.afterText ? MainThreadLanguageFeatures._reviveRegExp(onEnterRule.afterText) : undefined,
oneLineAboveText: onEnterRule.oneLineAboveText ? MainThreadLanguageFeatures._reviveRegExp(onEnterRule.oneLineAboveText) : undefined,
action: onEnterRule.action
};
}
private static _reviveOnEnterRules(onEnterRules: ISerializedOnEnterRule[]): OnEnterRule[] {
if (typeof onEnterRules === 'undefined') {
return undefined;
}
if (onEnterRules === null) {
return null;
}
return onEnterRules.map(MainThreadLanguageFeatures._reviveOnEnterRule);
}
......@@ -509,13 +512,13 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
const configuration: LanguageConfiguration = {
comments: _configuration.comments,
brackets: _configuration.brackets,
wordPattern: MainThreadLanguageFeatures._reviveRegExp(_configuration.wordPattern),
indentationRules: MainThreadLanguageFeatures._reviveIndentationRule(_configuration.indentationRules),
onEnterRules: MainThreadLanguageFeatures._reviveOnEnterRules(_configuration.onEnterRules),
wordPattern: _configuration.wordPattern ? MainThreadLanguageFeatures._reviveRegExp(_configuration.wordPattern) : undefined,
indentationRules: _configuration.indentationRules ? MainThreadLanguageFeatures._reviveIndentationRule(_configuration.indentationRules) : undefined,
onEnterRules: _configuration.onEnterRules ? MainThreadLanguageFeatures._reviveOnEnterRules(_configuration.onEnterRules) : undefined,
autoClosingPairs: null,
surroundingPairs: null,
__electricCharacterSupport: null
autoClosingPairs: undefined,
surroundingPairs: undefined,
__electricCharacterSupport: undefined
};
if (_configuration.__characterPairSupport) {
......
......@@ -312,7 +312,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
$unregister(handle: number): void;
$registerDocumentSymbolProvider(handle: number, selector: ISerializedDocumentFilter[], label: string): void;
$registerCodeLensSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number | undefined): void;
$registerCodeInsetSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number): void;
$registerCodeInsetSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number | undefined): void;
$emitCodeLensEvent(eventHandle: number, event?: any): void;
$registerDefinitionSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerDeclarationSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
......@@ -922,7 +922,7 @@ export interface ExtHostLanguageFeaturesShape {
$provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.DocumentSymbol[] | undefined>;
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeLensDto[]>;
$resolveCodeLens(handle: number, resource: UriComponents, symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto | undefined>;
$provideCodeInsets(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeInsetDto[]>;
$provideCodeInsets(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeInsetDto[] | undefined>;
$resolveCodeInset(handle: number, resource: UriComponents, symbol: CodeInsetDto, token: CancellationToken): Promise<CodeInsetDto>;
$provideDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<DefinitionLinkDto[]>;
$provideDeclaration(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<DefinitionLinkDto[]>;
......@@ -940,7 +940,7 @@ export interface ExtHostLanguageFeaturesShape {
$releaseWorkspaceSymbols(handle: number, id: number): void;
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto | undefined>;
$resolveRenameLocation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.RenameLocation | undefined>;
$provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<SuggestResultDto>;
$provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<SuggestResultDto | undefined>;
$resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, suggestion: modes.CompletionItem, token: CancellationToken): Promise<modes.CompletionItem>;
$releaseCompletionItems(handle: number, id: number): void;
$provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise<modes.SignatureHelp | undefined>;
......
......@@ -500,7 +500,7 @@ class NavigateTypeAdapter {
}
}).then(() => {
if (result.symbols.length > 0) {
this._resultCache[result._id] = [result.symbols[0]._id, result.symbols[result.symbols.length - 1]._id];
this._resultCache[result._id!] = [result.symbols[0]._id!, result.symbols[result.symbols.length - 1]._id!];
}
return result;
});
......@@ -633,12 +633,12 @@ class SuggestAdapter {
this._provider = provider;
}
provideCompletionItems(resource: URI, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<SuggestResultDto> {
provideCompletionItems(resource: URI, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<SuggestResultDto | undefined> {
const doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position);
return asPromise<vscode.CompletionItem[] | vscode.CompletionList>(
return asPromise<vscode.CompletionItem[] | vscode.CompletionList | null | undefined>(
() => this._provider.provideCompletionItems(doc, pos, token, typeConvert.CompletionContext.to(context))
).then(value => {
......@@ -720,7 +720,14 @@ class SuggestAdapter {
return undefined;
}
const result: SuggestionDto = {
// 'overwrite[Before|After]'-logic
const range = this.getRange(item, defaultRange);
if (!range.isSingleLine || range.start.line !== position.line) {
console.warn('INVALID text edit -> must be single line and on the same line');
return undefined;
}
return {
//
_id,
_parentId,
......@@ -733,46 +740,47 @@ class SuggestAdapter {
sortText: item.sortText,
preselect: item.preselect,
//
range: undefined,
insertText: undefined,
insertTextRules: item.keepWhitespace ? modes.CompletionItemInsertTextRule.KeepWhitespace : 0,
range: typeConvert.Range.from(range),
insertText: this.convertInsertText(item),
insertTextRules: this.convertInsertTextRules(item),
additionalTextEdits: item.additionalTextEdits && item.additionalTextEdits.map(typeConvert.TextEdit.from),
command: this._commands.toInternal(item.command),
commitCharacters: item.commitCharacters
};
}
private convertInsertText(item: vscode.CompletionItem): string {
// 'insertText'-logic
if (item.textEdit) {
result.insertText = item.textEdit.newText;
return item.textEdit.newText;
} else if (typeof item.insertText === 'string') {
result.insertText = item.insertText;
return item.insertText;
} else if (item.insertText instanceof SnippetString) {
result.insertText = item.insertText.value;
result.insertTextRules += modes.CompletionItemInsertTextRule.InsertAsSnippet;
return item.insertText.value;
} else {
result.insertText = item.label;
return item.label;
}
}
// 'overwrite[Before|After]'-logic
let range: vscode.Range;
private convertInsertTextRules(item: vscode.CompletionItem): modes.CompletionItemInsertTextRule {
let rules: modes.CompletionItemInsertTextRule = 0;
if (item.keepWhitespace) {
rules |= modes.CompletionItemInsertTextRule.KeepWhitespace;
}
if (item.insertText instanceof SnippetString) {
rules |= modes.CompletionItemInsertTextRule.InsertAsSnippet;
}
return rules;
}
private getRange(item: vscode.CompletionItem, defaultRange: vscode.Range) {
if (item.textEdit) {
range = item.textEdit.range;
return item.textEdit.range;
} else if (item.range) {
range = item.range;
return item.range;
} else {
range = defaultRange;
return defaultRange;
}
result.range = typeConvert.Range.from(range);
if (!range.isSingleLine || range.start.line !== position.line) {
console.warn('INVALID text edit -> must be single line and on the same line');
return undefined;
}
return result;
}
}
......@@ -1140,7 +1148,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
this._proxy.$registerCodeInsetSupport(handle, this._transformDocumentSelector(selector), eventHandle);
let result = this._createDisposable(handle);
if (eventHandle !== undefined) {
if (eventHandle !== undefined && provider.onDidChangeCodeInsets) {
const subscription = provider.onDidChangeCodeInsets(_ => this._proxy.$emitCodeLensEvent(eventHandle));
result = Disposable.from(result, subscription);
}
......@@ -1148,7 +1156,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return result;
}
$provideCodeInsets(handle: number, resource: UriComponents, token: CancellationToken): Promise<codeInset.ICodeInsetSymbol[]> {
$provideCodeInsets(handle: number, resource: UriComponents, token: CancellationToken): Promise<codeInset.ICodeInsetSymbol[] | undefined> {
return this._withAdapter(handle, CodeInsetAdapter, adapter => adapter.provideCodeInsets(URI.revive(resource), token));
}
......@@ -1328,7 +1336,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._createDisposable(handle);
}
$provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<SuggestResultDto> {
$provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<SuggestResultDto | undefined> {
return this._withAdapter(handle, SuggestAdapter, adapter => adapter.provideCompletionItems(URI.revive(resource), position, context, token));
}
......@@ -1411,12 +1419,6 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
// --- configuration
private static _serializeRegExp(regExp: RegExp): ISerializedRegExp {
if (typeof regExp === 'undefined') {
return undefined;
}
if (regExp === null) {
return null;
}
return {
pattern: regExp.source,
flags: regExpFlags(regExp),
......@@ -1424,36 +1426,24 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
}
private static _serializeIndentationRule(indentationRule: vscode.IndentationRule): ISerializedIndentationRule {
if (typeof indentationRule === 'undefined') {
return undefined;
}
if (indentationRule === null) {
return null;
}
return {
decreaseIndentPattern: ExtHostLanguageFeatures._serializeRegExp(indentationRule.decreaseIndentPattern),
increaseIndentPattern: ExtHostLanguageFeatures._serializeRegExp(indentationRule.increaseIndentPattern),
indentNextLinePattern: ExtHostLanguageFeatures._serializeRegExp(indentationRule.indentNextLinePattern),
unIndentedLinePattern: ExtHostLanguageFeatures._serializeRegExp(indentationRule.unIndentedLinePattern),
indentNextLinePattern: indentationRule.indentNextLinePattern ? ExtHostLanguageFeatures._serializeRegExp(indentationRule.indentNextLinePattern) : undefined,
unIndentedLinePattern: indentationRule.unIndentedLinePattern ? ExtHostLanguageFeatures._serializeRegExp(indentationRule.unIndentedLinePattern) : undefined,
};
}
private static _serializeOnEnterRule(onEnterRule: vscode.OnEnterRule): ISerializedOnEnterRule {
return {
beforeText: ExtHostLanguageFeatures._serializeRegExp(onEnterRule.beforeText),
afterText: ExtHostLanguageFeatures._serializeRegExp(onEnterRule.afterText),
oneLineAboveText: ExtHostLanguageFeatures._serializeRegExp(onEnterRule.oneLineAboveText),
afterText: onEnterRule.afterText ? ExtHostLanguageFeatures._serializeRegExp(onEnterRule.afterText) : undefined,
oneLineAboveText: onEnterRule.oneLineAboveText ? ExtHostLanguageFeatures._serializeRegExp(onEnterRule.oneLineAboveText) : undefined,
action: onEnterRule.action
};
}
private static _serializeOnEnterRules(onEnterRules: vscode.OnEnterRule[]): ISerializedOnEnterRule[] | undefined | null {
if (typeof onEnterRules === 'undefined') {
return undefined;
}
if (onEnterRules === null) {
return null;
}
private static _serializeOnEnterRules(onEnterRules: vscode.OnEnterRule[]): ISerializedOnEnterRule[] {
return onEnterRules.map(ExtHostLanguageFeatures._serializeOnEnterRule);
}
......@@ -1476,9 +1466,9 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
const serializedConfiguration: ISerializedLanguageConfiguration = {
comments: configuration.comments,
brackets: configuration.brackets,
wordPattern: ExtHostLanguageFeatures._serializeRegExp(configuration.wordPattern),
indentationRules: ExtHostLanguageFeatures._serializeIndentationRule(configuration.indentationRules),
onEnterRules: ExtHostLanguageFeatures._serializeOnEnterRules(configuration.onEnterRules),
wordPattern: configuration.wordPattern ? ExtHostLanguageFeatures._serializeRegExp(configuration.wordPattern) : undefined,
indentationRules: configuration.indentationRules ? ExtHostLanguageFeatures._serializeIndentationRule(configuration.indentationRules) : undefined,
onEnterRules: configuration.onEnterRules ? ExtHostLanguageFeatures._serializeOnEnterRules(configuration.onEnterRules) : undefined,
__electricCharacterSupport: configuration.__electricCharacterSupport,
__characterPairSupport: configuration.__characterPairSupport,
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册