Skip to content

Commit e82d8bb

Browse files
committed
Strict null checking goToDefinition
1 parent 8446e3f commit e82d8bb

3 files changed

Lines changed: 38 additions & 32 deletions

File tree

src/vs/editor/browser/editorExtensions.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,9 @@ export interface IActionOptions extends ICommandOptions {
184184
}
185185
export abstract class EditorAction extends EditorCommand {
186186

187-
public label: string;
188-
public alias: string;
189-
private menuOpts: IEditorCommandMenuOptions | undefined;
187+
public readonly label: string;
188+
public readonly alias: string;
189+
private readonly menuOpts: IEditorCommandMenuOptions | undefined;
190190

191191
constructor(opts: IActionOptions) {
192192
super(opts);

src/vs/editor/contrib/goToDefinition/goToDefinitionCommands.ts

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ export class DefinitionAction extends EditorAction {
5151
}
5252

5353
public run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {
54+
if (!editor.hasModel()) {
55+
return Promise.resolve(undefined);
56+
}
5457
const notificationService = accessor.get(INotificationService);
5558
const editorService = accessor.get(ICodeEditorService);
5659
const progressService = accessor.get(IProgressService);
@@ -112,14 +115,14 @@ export class DefinitionAction extends EditorAction {
112115
return getDefinitionsAtPosition(model, position, token);
113116
}
114117

115-
protected _getNoResultFoundMessage(info?: IWordAtPosition): string {
118+
protected _getNoResultFoundMessage(info: IWordAtPosition | null): string {
116119
return info && info.word
117120
? nls.localize('noResultWord', "No definition found for '{0}'", info.word)
118121
: nls.localize('generic.noResults', "No definition found");
119122
}
120123

121124
protected _getMetaTitle(model: ReferencesModel): string {
122-
return model.references.length > 1 && nls.localize('meta.title', " – {0} definitions", model.references.length);
125+
return model.references.length > 1 ? nls.localize('meta.title', " – {0} definitions", model.references.length) : '';
123126
}
124127

125128
private async _onResult(editorService: ICodeEditorService, editor: ICodeEditor, model: ReferencesModel): Promise<void> {
@@ -129,21 +132,23 @@ export class DefinitionAction extends EditorAction {
129132

130133
if (this._configuration.openInPeek) {
131134
this._openInPeek(editorService, editor, model);
132-
} else {
135+
} else if (editor.hasModel()) {
133136
const next = model.nearestReference(editor.getModel().uri, editor.getPosition());
134-
const targetEditor = await this._openReference(editor, editorService, next, this._configuration.openToSide);
135-
if (targetEditor && model.references.length > 1) {
136-
this._openInPeek(editorService, targetEditor, model);
137-
} else {
138-
model.dispose();
137+
if (next) {
138+
const targetEditor = await this._openReference(editor, editorService, next, this._configuration.openToSide);
139+
if (targetEditor && model.references.length > 1) {
140+
this._openInPeek(editorService, targetEditor, model);
141+
} else {
142+
model.dispose();
143+
}
139144
}
140145
}
141146
}
142147

143-
private _openReference(editor: ICodeEditor, editorService: ICodeEditorService, reference: Location | LocationLink, sideBySide: boolean): Promise<ICodeEditor> {
148+
private _openReference(editor: ICodeEditor, editorService: ICodeEditorService, reference: Location | LocationLink, sideBySide: boolean): Promise<ICodeEditor | null> {
144149
// range is the target-selection-range when we have one
145150
// and the the fallback is the 'full' range
146-
let range: IRange = undefined;
151+
let range: IRange | undefined = undefined;
147152
if (isLocationLink(reference)) {
148153
range = reference.targetSelectionRange;
149154
}
@@ -265,14 +270,14 @@ export class DeclarationAction extends DefinitionAction {
265270
return getDeclarationsAtPosition(model, position, token);
266271
}
267272

268-
protected _getNoResultFoundMessage(info?: IWordAtPosition): string {
273+
protected _getNoResultFoundMessage(info: IWordAtPosition | null): string {
269274
return info && info.word
270275
? nls.localize('decl.noResultWord', "No declaration found for '{0}'", info.word)
271276
: nls.localize('decl.generic.noResults', "No declaration found");
272277
}
273278

274279
protected _getMetaTitle(model: ReferencesModel): string {
275-
return model.references.length > 1 && nls.localize('decl.meta.title', " – {0} declarations", model.references.length);
280+
return model.references.length > 1 ? nls.localize('decl.meta.title', " – {0} declarations", model.references.length) : '';
276281
}
277282
}
278283

@@ -295,14 +300,14 @@ export class GoToDeclarationAction extends DeclarationAction {
295300
});
296301
}
297302

298-
protected _getNoResultFoundMessage(info?: IWordAtPosition): string {
303+
protected _getNoResultFoundMessage(info: IWordAtPosition | null): string {
299304
return info && info.word
300305
? nls.localize('decl.noResultWord', "No declaration found for '{0}'", info.word)
301306
: nls.localize('decl.generic.noResults', "No declaration found");
302307
}
303308

304309
protected _getMetaTitle(model: ReferencesModel): string {
305-
return model.references.length > 1 && nls.localize('decl.meta.title', " – {0} declarations", model.references.length);
310+
return model.references.length > 1 ? nls.localize('decl.meta.title', " – {0} declarations", model.references.length) : '';
306311
}
307312
}
308313

@@ -329,14 +334,14 @@ export class ImplementationAction extends DefinitionAction {
329334
return getImplementationsAtPosition(model, position, token);
330335
}
331336

332-
protected _getNoResultFoundMessage(info?: IWordAtPosition): string {
337+
protected _getNoResultFoundMessage(info: IWordAtPosition | null): string {
333338
return info && info.word
334339
? nls.localize('goToImplementation.noResultWord', "No implementation found for '{0}'", info.word)
335340
: nls.localize('goToImplementation.generic.noResults', "No implementation found");
336341
}
337342

338343
protected _getMetaTitle(model: ReferencesModel): string {
339-
return model.references.length > 1 && nls.localize('meta.implementations.title', " – {0} implementations", model.references.length);
344+
return model.references.length > 1 ? nls.localize('meta.implementations.title', " – {0} implementations", model.references.length) : '';
340345
}
341346
}
342347

@@ -387,14 +392,14 @@ export class TypeDefinitionAction extends DefinitionAction {
387392
return getTypeDefinitionsAtPosition(model, position, token);
388393
}
389394

390-
protected _getNoResultFoundMessage(info?: IWordAtPosition): string {
395+
protected _getNoResultFoundMessage(info: IWordAtPosition | null): string {
391396
return info && info.word
392397
? nls.localize('goToTypeDefinition.noResultWord', "No type definition found for '{0}'", info.word)
393398
: nls.localize('goToTypeDefinition.generic.noResults', "No type definition found");
394399
}
395400

396401
protected _getMetaTitle(model: ReferencesModel): string {
397-
return model.references.length > 1 && nls.localize('meta.typeDefinitions.title', " – {0} type definitions", model.references.length);
402+
return model.references.length > 1 ? nls.localize('meta.typeDefinitions.title', " – {0} type definitions", model.references.length) : '';
398403
}
399404
}
400405

src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC
3434
private editor: ICodeEditor;
3535
private toUnhook: IDisposable[];
3636
private decorations: string[];
37-
private currentWordUnderMouse: IWordAtPosition;
38-
private previousPromise: CancelablePromise<LocationLink[]>;
37+
private currentWordUnderMouse: IWordAtPosition | null;
38+
private previousPromise: CancelablePromise<LocationLink[] | null> | null;
3939

4040
constructor(
4141
editor: ICodeEditor,
@@ -51,7 +51,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC
5151
this.toUnhook.push(linkGesture);
5252

5353
this.toUnhook.push(linkGesture.onMouseMoveOrRelevantKeyDown(([mouseEvent, keyboardEvent]) => {
54-
this.startFindDefinition(mouseEvent, keyboardEvent);
54+
this.startFindDefinition(mouseEvent, keyboardEvent || undefined);
5555
}));
5656

5757
this.toUnhook.push(linkGesture.onExecute((mouseEvent: ClickLinkMouseEvent) => {
@@ -79,20 +79,20 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC
7979
return;
8080
}
8181

82-
if (!this.isEnabled(mouseEvent, withKey)) {
82+
if (!this.editor.hasModel() || !this.isEnabled(mouseEvent, withKey)) {
8383
this.currentWordUnderMouse = null;
8484
this.removeDecorations();
8585
return;
8686
}
8787

8888
// Find word at mouse position
89-
let position = mouseEvent.target.position;
90-
let word = position ? this.editor.getModel().getWordAtPosition(position) : null;
89+
const word = mouseEvent.target.position ? this.editor.getModel().getWordAtPosition(mouseEvent.target.position) : null;
9190
if (!word) {
9291
this.currentWordUnderMouse = null;
9392
this.removeDecorations();
9493
return;
9594
}
95+
const position = mouseEvent.target.position!;
9696

9797
// Return early if word at position is still the same
9898
if (this.currentWordUnderMouse && this.currentWordUnderMouse.startColumn === word.startColumn && this.currentWordUnderMouse.endColumn === word.endColumn && this.currentWordUnderMouse.word === word.word) {
@@ -158,9 +158,10 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC
158158
wordRange = new Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn);
159159
}
160160

161+
const modeId = this.modeService.getModeIdByFilepathOrFirstLine(textEditorModel.uri.fsPath);
161162
this.addDecoration(
162163
wordRange,
163-
new MarkdownString().appendCodeblock(this.modeService.getModeIdByFilepathOrFirstLine(textEditorModel.uri.fsPath), previewValue)
164+
new MarkdownString().appendCodeblock(modeId ? modeId : '', previewValue)
164165
);
165166
ref.dispose();
166167
});
@@ -274,10 +275,10 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC
274275
}
275276

276277
private isEnabled(mouseEvent: ClickLinkMouseEvent, withKey?: ClickLinkKeyboardEvent): boolean {
277-
return this.editor.getModel() &&
278+
return this.editor.hasModel() &&
278279
mouseEvent.isNoneOrSingleMouseDown &&
279280
(mouseEvent.target.type === MouseTargetType.CONTENT_TEXT) &&
280-
(mouseEvent.hasTriggerModifier || (withKey && withKey.keyCodeIsTriggerKey)) &&
281+
(mouseEvent.hasTriggerModifier || (withKey ? withKey.keyCodeIsTriggerKey : false)) &&
281282
DefinitionProviderRegistry.has(this.editor.getModel());
282283
}
283284

@@ -287,11 +288,11 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC
287288
return Promise.resolve(null);
288289
}
289290

290-
return getDefinitionsAtPosition(model, target.position, token);
291+
return getDefinitionsAtPosition(model, target.position!, token);
291292
}
292293

293294
private gotoDefinition(target: IMouseTarget, sideBySide: boolean): Promise<any> {
294-
this.editor.setPosition(target.position);
295+
this.editor.setPosition(target.position!);
295296
const action = new DefinitionAction(new DefinitionActionConfig(sideBySide, false, true, false), { alias: undefined, label: undefined, id: undefined, precondition: undefined });
296297
return this.editor.invokeWithinContext(accessor => action.run(accessor, this.editor));
297298
}

0 commit comments

Comments
 (0)