Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strict nulls for everything except logconsole #7657

Merged
merged 16 commits into from Dec 23, 2019
11 changes: 4 additions & 7 deletions buildutils/src/utils.ts
Expand Up @@ -341,18 +341,15 @@ export function ensureUnixPathSep(source: string) {
/**
* Get the last portion of a path, without its extension (if any).
*
* @param path - The file path.
* @param pathArg - The file path.
*
* @returns the last part of the path, sans extension.
*/
export function stem(path: string): string {
export function stem(pathArg: string): string {
return path
.split('\\')
.pop()
.split('/')
.pop()
.basename(pathArg)
.split('.')
.shift();
.shift()!;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/apputils/src/clipboard.ts
Expand Up @@ -70,8 +70,8 @@ export namespace Clipboard {

// Save the current selection.
let savedRanges: any[] = [];
for (let i = 0, len = sel.rangeCount; i < len; ++i) {
savedRanges[i] = sel.getRangeAt(i).cloneRange();
for (let i = 0, len = sel?.rangeCount || 0; i < len; ++i) {
savedRanges[i] = sel!.getRangeAt(i).cloneRange();
}

// Select the node content.
Expand Down
3 changes: 2 additions & 1 deletion packages/apputils/src/printing.ts
Expand Up @@ -90,10 +90,11 @@ export namespace Printing {
await resolveWhenLoaded(iframe);
} else {
iframe.src = 'about:blank';
await resolveWhenLoaded(iframe);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this resolves a possible race condition?

setIFrameNode(iframe, textOrEl as HTMLElement);
}
const printed = resolveAfterEvent();
launchPrint(iframe.contentWindow);
launchPrint(iframe.contentWindow!);
// Once the print dialog has been dismissed, we regain event handling,
// and it should be safe to discard the hidden iframe.
await printed;
Expand Down
2 changes: 1 addition & 1 deletion packages/completer/src/model.ts
Expand Up @@ -101,7 +101,7 @@ export class CompleterModel implements Completer.IModel {
return;
}

const { start, end } = this._cursor;
const { start, end } = cursor;
// Clip the front of the current line.
let query = current.text.substring(start);
// Clip the back of the current line by calculating the end of the original.
Expand Down
10 changes: 6 additions & 4 deletions packages/coreutils/src/settingregistry.ts
Expand Up @@ -312,8 +312,9 @@ export class SettingRegistry implements ISettingRegistry {
const { composite, user } = plugins[plugin].data;

return {
composite: key in composite ? copy(composite[key]) : undefined,
user: key in user ? copy(user[key]) : undefined
composite:
composite[key] !== undefined ? copy(composite[key]!) : undefined,
user: user[key] !== undefined ? copy(user[key]!) : undefined
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should behave correctly, but it is a logic change.

};
}

Expand Down Expand Up @@ -785,8 +786,9 @@ export class Settings implements ISettingRegistry.ISettings {
const { composite, user } = this;

return {
composite: key in composite ? copy(composite[key]) : undefined,
user: key in user ? copy(user[key]) : undefined
composite:
composite[key] !== undefined ? copy(composite[key]!) : undefined,
user: user[key] !== undefined ? copy(user[key]!) : undefined
};
}

Expand Down
8 changes: 5 additions & 3 deletions packages/csvviewer/src/parse.ts
Expand Up @@ -401,9 +401,11 @@ export function parseDSV(options: IParser.IOptions): IParser.IResults {
case NEW_ROW:
nrows++;

// If we just parsed the first row and the ncols is undefined, set it to
// the number of columns we found in the first row.
if (nrows === 1 && ncols === undefined) {
// If ncols is undefined, set it to the number of columns in this row (first row implied).
if (ncols === undefined) {
if (nrows !== 1) {
throw new Error('Error parsing default number of columns');
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jasongrout Will these be logically equivalent?

ncols = col;
}

Expand Down
35 changes: 35 additions & 0 deletions packages/docmanager-extension/src/index.ts
Expand Up @@ -468,6 +468,13 @@ function addCommands(
}
const context = docManager.contextForWidget(shell.currentWidget!);
const type = fileType(shell.currentWidget!, docManager);
if (!context) {
return showDialog({
title: 'Cannot Reload',
body: 'No context found for current widget!',
buttons: [Dialog.okButton()]
});
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a bunch of failure dialogs like this here, based on the pattern for one of the commands. Not sure if silent failure is better?

return showDialog({
title: `Reload ${type} from Disk`,
body: `Are you sure you want to reload
Expand All @@ -492,6 +499,13 @@ function addCommands(
return;
}
const context = docManager.contextForWidget(shell.currentWidget!);
if (!context) {
return showDialog({
title: 'Cannot Revert',
body: 'No context found for current widget!',
buttons: [Dialog.okButton()]
});
}
return context.listCheckpoints().then(checkpoints => {
if (checkpoints.length < 1) {
return;
Expand Down Expand Up @@ -531,6 +545,13 @@ function addCommands(
// Checks that shell.currentWidget is valid:
if (isEnabled()) {
let context = docManager.contextForWidget(shell.currentWidget!);
if (!context) {
return showDialog({
title: 'Cannot Save',
body: 'No context found for current widget!',
buttons: [Dialog.okButton()]
});
}
if (context.model.readOnly) {
return showDialog({
title: 'Cannot Save',
Expand Down Expand Up @@ -583,6 +604,13 @@ function addCommands(
// Checks that shell.currentWidget is valid:
if (isEnabled()) {
let context = docManager.contextForWidget(shell.currentWidget!);
if (!context) {
return showDialog({
title: 'Cannot Save',
body: 'No context found for current widget!',
buttons: [Dialog.okButton()]
});
}
return context.saveAs();
}
}
Expand All @@ -596,6 +624,13 @@ function addCommands(
// Checks that shell.currentWidget is valid:
if (isEnabled()) {
let context = docManager.contextForWidget(shell.currentWidget!);
if (!context) {
return showDialog({
title: 'Cannot Download',
body: 'No context found for current widget!',
buttons: [Dialog.okButton()]
});
}
return context.download();
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/docmanager/src/widgetmanager.ts
Expand Up @@ -252,7 +252,7 @@ export class DocumentWidgetManager implements IDisposable {
*
* @param widget - The target widget.
*/
protected setCaption(widget: Widget): Promise<void> {
protected async setCaption(widget: Widget): Promise<void> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should fix the return type from the naked return statements below from untitled to Promise<void>. I assume this is a fix, and not an API break...

Copy link
Member Author

@vidartf vidartf Dec 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i.e. I assume the return type should stay the currently typed Promise<void>, not the currently implemented Promise<void> | undefined.

let context = Private.contextProperty.get(widget);
if (!context) {
return;
Expand Down
Expand Up @@ -412,7 +412,7 @@ export class CodeMirrorSearchProvider

// if the last thing on the line was a match, make sure we still
// emit the changed signal so the display can pick up the updates
if (stream.eol) {
if (stream.eol()) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is a fix, and not a break...

this._changed.emit(undefined);
}
return 'searching';
Expand Down
2 changes: 1 addition & 1 deletion packages/logconsole-extension/src/index.tsx
Expand Up @@ -270,7 +270,7 @@ function activateLogConsole(
} else {
source = null;
}
if (logConsoleWidget) {
if (logConsolePanel) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is a fix, and not a break...

logConsolePanel.source = source;
}
status.model.source = source;
Expand Down
7 changes: 6 additions & 1 deletion packages/logconsole-extension/src/status.tsx
Expand Up @@ -32,10 +32,15 @@ function LogConsoleStatusComponent(
title = `${props.newMessages} new messages, `;
}
title += `${props.logEntries} log entries for ${props.source}`;
// inline conditional doesn't seem to work with strict TS currently...
let cond: JSX.Element = (false as unknown) as JSX.Element;
if (props.newMessages > 0) {
cond = <TextItem source={props.newMessages} />;
}
return (
<GroupItem spacing={0} onClick={props.handleClick} title={title}>
<DefaultIconReact name={'list'} top={'2px'} kind={'statusBar'} />
{props.newMessages > 0 && <TextItem source={props.newMessages} />}
{cond}
</GroupItem>
);
}
Expand Down
6 changes: 5 additions & 1 deletion packages/logconsole/src/widget.ts
Expand Up @@ -355,7 +355,11 @@ export class LogConsolePanel extends StackedPanel {
const viewId = `source:${sender.source}`;
const outputArea = this._outputAreas.get(viewId);
if (outputArea) {
outputArea.rendermime = change.newValue;
if (change.newValue) {
outputArea.rendermime = change.newValue;
} else {
outputArea.dispose();
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure why I made this change, but it think it made sense at the time. Please review carefully...

}
}, this);

Expand Down
2 changes: 1 addition & 1 deletion packages/notebook/src/actions.tsx
Expand Up @@ -1757,7 +1757,7 @@ namespace Private {

if (notebook.isSelectedOrActive(child) && deletable) {
toDelete.push(index);
notebook.model.deletedCells.push(child.model.id);
model.deletedCells.push(child.model.id);
}
});

Expand Down
2 changes: 1 addition & 1 deletion packages/notebook/src/model.ts
Expand Up @@ -182,7 +182,7 @@ export class NotebookModel extends DocumentModel implements INotebookModel {
*/
toJSON(): nbformat.INotebookContent {
let cells: nbformat.ICell[] = [];
for (let i = 0; i < this.cells.length; i++) {
for (let i = 0; i < (this.cells?.length || 0); i++) {
let cell = this.cells.get(i);
cells.push(cell.toJSON());
}
Expand Down
2 changes: 1 addition & 1 deletion packages/notebook/src/notebooktools.ts
Expand Up @@ -685,7 +685,7 @@ export namespace NotebookTools {
this._validCellTypes.length &&
this._validCellTypes.indexOf(cellType) === -1
) {
select.value = undefined;
select.value = '';
select.disabled = true;
return;
}
Expand Down
5 changes: 3 additions & 2 deletions packages/terminal-extension/src/index.ts
Expand Up @@ -336,6 +336,7 @@ export function addCommands(
Terminal = (await Private.ensureWidget()).Terminal;
} catch (err) {
Private.showErrorMessage(err);
return;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is a fix, and not a break...

}

const name = args['name'] as string;
Expand Down Expand Up @@ -401,7 +402,7 @@ export function addCommands(
label: 'Increase Terminal Font Size',
execute: async () => {
let { fontSize } = options;
if (fontSize < 72) {
if (fontSize && fontSize < 72) {
vidartf marked this conversation as resolved.
Show resolved Hide resolved
try {
await settingRegistry.set(plugin.id, 'fontSize', fontSize + 1);
} catch (err) {
Expand All @@ -415,7 +416,7 @@ export function addCommands(
label: 'Decrease Terminal Font Size',
execute: async () => {
let { fontSize } = options;
if (fontSize > 9) {
if (fontSize && fontSize > 9) {
try {
await settingRegistry.set(plugin.id, 'fontSize', fontSize - 1);
} catch (err) {
Expand Down
4 changes: 2 additions & 2 deletions tests/test-cells/src/widget.spec.ts
Expand Up @@ -357,10 +357,10 @@ describe('cells/widget', () => {
it('should not throw an error (full test in input area)', () => {
const widget = new Cell({ model, contentFactory }).initializeState();
expect(() => {
widget.setPrompt(void 0);
widget.setPrompt(void 0 as any);
vidartf marked this conversation as resolved.
Show resolved Hide resolved
}).not.toThrow();
expect(() => {
widget.setPrompt(null);
widget.setPrompt(null as any);
}).not.toThrow();
expect(() => {
widget.setPrompt('');
Expand Down
2 changes: 1 addition & 1 deletion tests/test-csvviewer/src/widget.spec.ts
Expand Up @@ -113,7 +113,7 @@ describe('csvviewer/widget', () => {
searchService.find(query);
expect(fakeRenderCell(0, 1)).to.equal('currentMatch');
expect(fakeRenderCell(1, 1)).to.equal('anotherMatch');
expect(fakeRenderCell(0, 0)).to.equal(undefined);
expect(fakeRenderCell(0, 0)).to.equal('');

// search again, the current match "moves" to be (1,1)
searchService.find(query);
Expand Down