提交 44cbf5af 编写于 作者: M Matt Bierner

Strict null check code lens

上级 82916c8f
......@@ -186,6 +186,8 @@
"./vs/editor/contrib/codeAction/codeActionTrigger.ts",
"./vs/editor/contrib/codeAction/lightBulbWidget.ts",
"./vs/editor/contrib/codelens/codelens.ts",
"./vs/editor/contrib/codelens/codelensController.ts",
"./vs/editor/contrib/codelens/codelensWidget.ts",
"./vs/editor/contrib/colorPicker/color.ts",
"./vs/editor/contrib/colorPicker/colorDetector.ts",
"./vs/editor/contrib/colorPicker/colorPickerModel.ts",
......
......@@ -27,9 +27,9 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
private _globalToDispose: IDisposable[];
private _localToDispose: IDisposable[];
private _lenses: CodeLens[];
private _currentFindCodeLensSymbolsPromise: CancelablePromise<ICodeLensData[]>;
private _currentFindCodeLensSymbolsPromise: CancelablePromise<ICodeLensData[]> | null;
private _modelChangeCounter: number;
private _currentResolveCodeLensSymbolsPromise: CancelablePromise<any>;
private _currentResolveCodeLensSymbolsPromise: CancelablePromise<any> | null;
private _detectVisibleLenses: RunOnceScheduler;
constructor(
......@@ -176,7 +176,7 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
scrollState.restore(this._editor);
} else {
// No accessors available
this._disposeAllLenses(null, null);
this._disposeAllLenses(void 0, void 0);
}
}));
this._localToDispose.push(this._editor.onDidChangeConfiguration(e => {
......@@ -187,11 +187,11 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
}
}));
this._localToDispose.push(this._editor.onMouseUp(e => {
if (e.target.type === editorBrowser.MouseTargetType.CONTENT_WIDGET && e.target.element.tagName === 'A') {
if (e.target.type === editorBrowser.MouseTargetType.CONTENT_WIDGET && e.target.element && e.target.element.tagName === 'A') {
for (const lens of this._lenses) {
let command = lens.getCommand(e.target.element as HTMLLinkElement);
if (command) {
this._commandService.executeCommand(command.id, ...command.arguments).catch(err => this._notificationService.error(err));
this._commandService.executeCommand(command.id, ...(command.arguments || [])).catch(err => this._notificationService.error(err));
break;
}
}
......@@ -200,7 +200,7 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
scheduler.schedule();
}
private _disposeAllLenses(decChangeAccessor: IModelDecorationsChangeAccessor, viewZoneChangeAccessor: editorBrowser.IViewZoneChangeAccessor): void {
private _disposeAllLenses(decChangeAccessor: IModelDecorationsChangeAccessor | undefined, viewZoneChangeAccessor: editorBrowser.IViewZoneChangeAccessor | undefined): void {
let helper = new CodeLensHelper();
this._lenses.forEach((lens) => lens.dispose(helper, viewZoneChangeAccessor));
if (decChangeAccessor) {
......@@ -210,13 +210,13 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
}
private _renderCodeLensSymbols(symbols: ICodeLensData[]): void {
if (!this._editor.getModel()) {
if (!this._editor.hasModel()) {
return;
}
let maxLineNumber = this._editor.getModel().getLineCount();
let groups: ICodeLensData[][] = [];
let lastGroup: ICodeLensData[];
let lastGroup: ICodeLensData[] | undefined;
for (let symbol of symbols) {
let line = symbol.symbol.range.startLineNumber;
......@@ -307,7 +307,7 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
const promises = toResolve.map((request, i) => {
const resolvedSymbols = new Array<ICodeLensSymbol>(request.length);
const resolvedSymbols = new Array<ICodeLensSymbol | undefined | null>(request.length);
const promises = request.map((request, i) => {
if (typeof request.provider.resolveCodeLens === 'function') {
return Promise.resolve(request.provider.resolveCodeLens(model, request.symbol, token)).then(symbol => {
......
......@@ -95,9 +95,9 @@ class CodeLensContentWidget implements editorBrowser.IContentWidget {
}
}
withCommands(symbols: ICodeLensSymbol[]): void {
withCommands(inSymbols: Array<ICodeLensSymbol | undefined | null>): void {
this._commands = Object.create(null);
symbols = coalesce(symbols);
const symbols = coalesce(inSymbols);
if (isFalsyOrEmpty(symbols)) {
this._domNode.innerHTML = 'no commands';
return;
......@@ -105,16 +105,18 @@ class CodeLensContentWidget implements editorBrowser.IContentWidget {
let html: string[] = [];
for (let i = 0; i < symbols.length; i++) {
let command = symbols[i].command;
let title = escape(command.title);
let part: string;
if (command.id) {
part = `<a id=${i}>${title}</a>`;
this._commands[i] = command;
} else {
part = `<span>${title}</span>`;
const command = symbols[i].command;
if (command) {
const title = escape(command.title);
let part: string;
if (command.id) {
part = `<a id=${i}>${title}</a>`;
this._commands[i] = command;
} else {
part = `<span>${title}</span>`;
}
html.push(part);
}
html.push(part);
}
this._domNode.innerHTML = html.join('<span>&nbsp;|&nbsp;</span>');
......@@ -136,6 +138,9 @@ class CodeLensContentWidget implements editorBrowser.IContentWidget {
}
setSymbolRange(range: Range): void {
if (!this._editor.hasModel()) {
return;
}
const lineNumber = range.startLineNumber;
const column = this._editor.getModel().getLineFirstNonWhitespaceColumn(lineNumber);
this._widgetPosition = {
......@@ -206,7 +211,7 @@ export class CodeLens {
this._data = data;
this._decorationIds = new Array<string>(this._data.length);
let range: Range;
let range: Range | undefined;
this._data.forEach((codeLensData, i) => {
helper.addDecoration({
......@@ -222,16 +227,18 @@ export class CodeLens {
}
});
this._contentWidget = new CodeLensContentWidget(editor, range);
this._viewZone = new CodeLensViewZone(range.startLineNumber - 1, updateCallback);
if (range) {
this._contentWidget = new CodeLensContentWidget(editor, range);
this._viewZone = new CodeLensViewZone(range.startLineNumber - 1, updateCallback);
this._viewZoneId = viewZoneChangeAccessor.addZone(this._viewZone);
this._editor.addContentWidget(this._contentWidget);
this._viewZoneId = viewZoneChangeAccessor.addZone(this._viewZone);
this._editor.addContentWidget(this._contentWidget);
}
}
dispose(helper: CodeLensHelper, viewZoneChangeAccessor: editorBrowser.IViewZoneChangeAccessor): void {
dispose(helper: CodeLensHelper, viewZoneChangeAccessor?: editorBrowser.IViewZoneChangeAccessor): void {
while (this._decorationIds.length) {
helper.removeDecoration(this._decorationIds.pop());
helper.removeDecoration(this._decorationIds.pop()!);
}
if (viewZoneChangeAccessor) {
viewZoneChangeAccessor.removeZone(this._viewZoneId);
......@@ -240,16 +247,20 @@ export class CodeLens {
}
isValid(): boolean {
if (!this._editor.hasModel()) {
return false;
}
const model = this._editor.getModel();
return this._decorationIds.some((id, i) => {
const range = this._editor.getModel().getDecorationRange(id);
const range = model.getDecorationRange(id);
const symbol = this._data[i].symbol;
return range && Range.isEmpty(symbol.range) === range.isEmpty();
return !!(range && Range.isEmpty(symbol.range) === range.isEmpty());
});
}
updateCodeLensSymbols(data: ICodeLensData[], helper: CodeLensHelper): void {
while (this._decorationIds.length) {
helper.removeDecoration(this._decorationIds.pop());
helper.removeDecoration(this._decorationIds.pop()!);
}
this._data = data;
this._decorationIds = new Array<string>(this._data.length);
......@@ -261,7 +272,7 @@ export class CodeLens {
});
}
computeIfNecessary(model: ITextModel): ICodeLensData[] {
computeIfNecessary(model: ITextModel): ICodeLensData[] | null {
this._contentWidget.updateVisibility(); // trigger the fade in
if (!this._contentWidget.isVisible()) {
return null;
......@@ -269,12 +280,15 @@ export class CodeLens {
// Read editor current state
for (let i = 0; i < this._decorationIds.length; i++) {
this._data[i].symbol.range = model.getDecorationRange(this._decorationIds[i]);
const range = model.getDecorationRange(this._decorationIds[i]);
if (range) {
this._data[i].symbol.range = range;
}
}
return this._data;
}
updateCommands(symbols: ICodeLensSymbol[]): void {
updateCommands(symbols: Array<ICodeLensSymbol | undefined | null>): void {
this._contentWidget.withCommands(symbols);
}
......@@ -287,22 +301,25 @@ export class CodeLens {
}
getLineNumber(): number {
const range = this._editor.getModel().getDecorationRange(this._decorationIds[0]);
if (range) {
return range.startLineNumber;
if (this._editor.hasModel()) {
const range = this._editor.getModel().getDecorationRange(this._decorationIds[0]);
if (range) {
return range.startLineNumber;
}
}
return -1;
}
update(viewZoneChangeAccessor: editorBrowser.IViewZoneChangeAccessor): void {
if (this.isValid()) {
if (this.isValid() && this._editor.hasModel()) {
const range = this._editor.getModel().getDecorationRange(this._decorationIds[0]);
if (range) {
this._viewZone.afterLineNumber = range.startLineNumber - 1;
viewZoneChangeAccessor.layoutZone(this._viewZoneId);
this._viewZone.afterLineNumber = range.startLineNumber - 1;
viewZoneChangeAccessor.layoutZone(this._viewZoneId);
this._contentWidget.setSymbolRange(range);
this._editor.layoutContentWidget(this._contentWidget);
this._contentWidget.setSymbolRange(range);
this._editor.layoutContentWidget(this._contentWidget);
}
}
}
}
......
......@@ -49,7 +49,7 @@ export abstract class TreeElement {
return id;
}
static getElementById(id: string, element: TreeElement): TreeElement {
static getElementById(id: string, element: TreeElement): TreeElement | undefined {
if (!id) {
return undefined;
}
......
......@@ -131,7 +131,7 @@ export class FindModelBoundToEditorModel {
// The find model is disposed during a find state changed event
return;
}
if (!this._editor.getModel()) {
if (!this._editor.hasModel()) {
// The find model will be disposed momentarily
return;
}
......
......@@ -461,7 +461,7 @@ export class AutoIndentOnPaste implements IEditorContribution {
}
// no model
if (!this.editor.getModel()) {
if (!this.editor.hasModel()) {
return;
}
......
......@@ -44,7 +44,7 @@ export interface ISerializedEditorGroup {
id: number;
editors: ISerializedEditorInput[];
mru: number[];
preview: number;
preview?: number;
}
export function isSerializedEditorGroup(obj?: any): obj is ISerializedEditorGroup {
......@@ -94,8 +94,8 @@ export class EditorGroup extends Disposable {
private mru: EditorInput[] = [];
private mapResourceToEditorCount: ResourceMap<number> = new ResourceMap<number>();
private preview: EditorInput; // editor in preview state
private active: EditorInput; // editor in active state
private preview: EditorInput | null; // editor in preview state
private active: EditorInput | null; // editor in active state
private editorOpenPositioning: 'left' | 'right' | 'first' | 'last';
......@@ -136,9 +136,9 @@ export class EditorGroup extends Disposable {
return mru ? this.mru.slice(0) : this.editors.slice(0);
}
getEditor(index: number): EditorInput;
getEditor(resource: URI): EditorInput;
getEditor(arg1: any): EditorInput {
getEditor(index: number): EditorInput | null;
getEditor(resource: URI): EditorInput | null;
getEditor(arg1: any): EditorInput | null {
if (typeof arg1 === 'number') {
return this.editors[arg1];
}
......@@ -159,7 +159,7 @@ export class EditorGroup extends Disposable {
return null;
}
get activeEditor(): EditorInput {
get activeEditor(): EditorInput | null {
return this.active;
}
......@@ -167,7 +167,7 @@ export class EditorGroup extends Disposable {
return this.matches(this.active, editor);
}
get previewEditor(): EditorInput {
get previewEditor(): EditorInput | null {
return this.preview;
}
......@@ -310,7 +310,7 @@ export class EditorGroup extends Disposable {
}
}
closeEditor(editor: EditorInput, openNext = true): number {
closeEditor(editor: EditorInput, openNext = true): number | undefined {
const event = this.doCloseEditor(editor, openNext, false);
if (event) {
......@@ -322,7 +322,7 @@ export class EditorGroup extends Disposable {
return void 0;
}
private doCloseEditor(editor: EditorInput, openNext: boolean, replaced: boolean): EditorCloseEvent {
private doCloseEditor(editor: EditorInput, openNext: boolean, replaced: boolean): EditorCloseEvent | null {
const index = this.indexOf(editor);
if (index === -1) {
return null; // not found
......@@ -384,7 +384,9 @@ export class EditorGroup extends Disposable {
// Optimize: close all non active editors first to produce less upstream work
this.mru.filter(e => !this.matches(e, this.active)).forEach(e => this.closeEditor(e));
this.closeEditor(this.active);
if (this.active) {
this.closeEditor(this.active);
}
}
moveEditor(editor: EditorInput, toIndex: number): void {
......@@ -455,7 +457,9 @@ export class EditorGroup extends Disposable {
this._onDidEditorUnpin.fire(editor);
// Close old preview editor if any
this.closeEditor(oldPreview);
if (oldPreview) {
this.closeEditor(oldPreview);
}
}
isPinned(editor: EditorInput): boolean;
......@@ -538,7 +542,7 @@ export class EditorGroup extends Disposable {
}
}
indexOf(candidate: EditorInput, editors = this.editors): number {
indexOf(candidate: EditorInput | null, editors = this.editors): number {
if (!candidate) {
return -1;
}
......@@ -591,7 +595,7 @@ export class EditorGroup extends Disposable {
this.mru.unshift(editor);
}
private matches(editorA: EditorInput, editorB: EditorInput): boolean {
private matches(editorA: EditorInput | null, editorB: EditorInput | null): boolean {
return !!editorA && !!editorB && editorA.matches(editorB);
}
......@@ -615,7 +619,7 @@ export class EditorGroup extends Disposable {
// from mru, active and preview if any.
let serializableEditors: EditorInput[] = [];
let serializedEditors: ISerializedEditorInput[] = [];
let serializablePreviewIndex: number;
let serializablePreviewIndex: number | undefined;
this.editors.forEach(e => {
let factory = registry.getEditorInputFactory(e.getTypeId());
if (factory) {
......@@ -667,6 +671,8 @@ export class EditorGroup extends Disposable {
}));
this.mru = data.mru.map(i => this.editors[i]);
this.active = this.mru[0];
this.preview = this.editors[data.preview];
if (typeof data.preview === 'number') {
this.preview = this.editors[data.preview];
}
}
}
......@@ -117,7 +117,7 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend
}
private onModelChanged(): void {
if (!this.editor.getModel()) {
if (!this.editor.hasModel()) {
// model could have been disposed during the delay
return;
}
......
......@@ -65,7 +65,7 @@ class InsertSnippetAction extends EditorAction {
const modeService = accessor.get(IModeService);
const snippetService = accessor.get(ISnippetsService);
if (!editor.getModel()) {
if (!editor.hasModel()) {
return undefined;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册