-
Notifications
You must be signed in to change notification settings - Fork 78
Enable strictNullChecks in tsconfig.json #179
Conversation
lib/adapters/apply-edit-adapter.ts
Outdated
private static validateEdit( | ||
buffer: TextBuffer, | ||
edit: atomIde.TextEdit, | ||
prevEdit: atomIde.TextEdit | undefined | null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could revert the addition of undefined
here.
@@ -267,11 +267,11 @@ export default class AutocompleteAdapter { | |||
// * `editor` An Atom {TextEditor} used to obtain the necessary text replacement. | |||
// * `suggestion` An {atom$AutocompleteSuggestion} to set the replacementPrefix and text properties of. | |||
public static applyTextEditToSuggestion( | |||
textEdit: TextEdit | null, | |||
textEdit: TextEdit | undefined, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This TextEdit comes from CompletionItem.textEdit
which is typed as TextEdit | undefined
, makes more sense to use undefined
here
@@ -296,7 +296,7 @@ export default class AutocompleteAdapter { | |||
// | |||
// Returns a {String} containing the AutoComplete+ suggestion type equivalent | |||
// to the given completion kind. | |||
public static completionKindToSuggestionType(kind: number | null): string { | |||
public static completionKindToSuggestionType(kind: number | undefined): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CompletionItem.kind
uses number | undefined
(or more accurately, a bunch of specific numbers unioned with undefined
@@ -88,5 +88,8 @@ export default class DatatipAdapter { | |||
value: markedString.value, | |||
}; | |||
} | |||
|
|||
// Catch-all case | |||
return { type: 'markdown', value: markedString.toString() }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypeScript compiler wouldn't let this method live without a catch-all case. Is there a better result value?
@@ -27,7 +27,7 @@ export default class CodeActionAdapter { | |||
public static async getCodeActions( | |||
connection: LanguageClientConnection, | |||
serverCapabilities: ServerCapabilities, | |||
linterAdapter: LinterPushV2Adapter | null, | |||
linterAdapter: LinterPushV2Adapter | undefined , |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ActiveServer.linterPushV2
is typed as LinterPushV2Adapter | undefined
, that gets passed into this method for this parameter
@@ -64,7 +64,7 @@ export default class DocumentSyncAdapter { | |||
// indicating whether this adapter should care about the contents of the editor. | |||
constructor( | |||
connection: LanguageClientConnection, | |||
documentSyncKind: TextDocumentSyncOptions | number | null, | |||
documentSyncKind: TextDocumentSyncOptions | number | undefined, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ServerCapabilities.textDocumentSync
uses undefined
instead of null
} | ||
} | ||
return null; | ||
} | ||
} | ||
|
||
function getCodeKey(range: atom.Range, text: string): string { | ||
return [].concat(...range.serialize(), text).join(','); | ||
return ([] as any[]).concat(...range.serialize(), text).join(','); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A little hack to make the type system happy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should just ${range.serialize()},${text}
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll give it a shot!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
range.serialize()
won't work because it returns an array of arrays, that's why the [].concat()
with the spread operator is used. It builds a flat array of items that can be joined. I'll leave it as it is for now
@@ -113,13 +113,13 @@ export default class LinterPushV2Adapter { | |||
if (path != null) { | |||
const diagnosticCodes = this._diagnosticCodes.get(path); | |||
if (diagnosticCodes != null) { | |||
return diagnosticCodes.get(getCodeKey(range, text)); | |||
return diagnosticCodes.get(getCodeKey(range, text)) || null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maps return undefined
when a key has no value, so I'm coercing it to null
to conform to the existing signature
for (const candidate of candidates) { | ||
if ( | ||
candidate !== child && | ||
candidate.startPosition.isLessThanOrEqual(child.startPosition) && | ||
(candidate.endPosition == null || candidate.endPosition.isGreaterThanOrEqual(child.endPosition)) | ||
(candidate.endPosition === undefined || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
endPosition
is an optional property which is undefined
instead of null
@@ -31,8 +31,8 @@ export default class SignatureHelpAdapter { | |||
const {signatureHelpProvider} = this._capabilities; | |||
assert(signatureHelpProvider != null); | |||
|
|||
let triggerCharacters = null; | |||
if (Array.isArray(signatureHelpProvider.triggerCharacters)) { | |||
let triggerCharacters: Set<string> | undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet assigned, must use undefined
in type
@@ -39,21 +39,6 @@ import SignatureHelpAdapter from './adapters/signature-help-adapter'; | |||
|
|||
export type ConnectionType = 'stdio' | 'socket' | 'ipc'; | |||
|
|||
// Public: Defines the minimum surface area for an object that resembles a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Decided to move this to ServerManager's file because ServerManager was still using ChildProcess to refer to the language server process.
@@ -159,7 +159,7 @@ export default class Convert { | |||
case 'deleted': | |||
return [{uri: Convert.pathToUri(fileEvent.path), type: ls.FileChangeType.Deleted}]; | |||
case 'renamed': { | |||
const results = []; | |||
const results: Array<{ uri: string, type: ls.FileChangeType }> = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypeScript uses a type of never[]
when you define a plain array with no typing. You have to make the type specific so that the type system doesn't give a bunch of weird errors.
@@ -31,7 +31,7 @@ export default (async function downloadFile( | |||
throw Error('No response body'); | |||
} | |||
|
|||
const finalLength = length || parseInt(response.headers.get('Content-Length' || '0'), 10); | |||
const finalLength = length || parseInt(response.headers.get('Content-Length') || '0', 10); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug in the previous code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha, looks like it. Nice catch.
@@ -72,7 +72,7 @@ async function streamWithProgress( | |||
writer.write(Buffer.from(chunk)); | |||
if (progressCallback != null) { | |||
bytesDone += chunk.byteLength; | |||
const percent: number = length === 0 ? null : Math.floor(bytesDone / length * 100); | |||
const percent: number | undefined = length === 0 ? undefined : Math.floor(bytesDone / length * 100); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
percent
gets passed into ByteProgressCallback's optional percent
parameter, undefined
matches it
@@ -20,7 +20,7 @@ describe('AutoCompleteAdapter', () => { | |||
capabilities: {completionProvider: { }}, | |||
connection: new ls.LanguageClientConnection(createSpyConnection()), | |||
disposable: new CompositeDisposable(), | |||
process: undefined, | |||
process: undefined as any, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type system hack to not have to mock a whole process
@@ -50,8 +50,10 @@ describe('CodeHighlightAdapter', () => { | |||
expect(highlightStub.called).to.be.true; | |||
|
|||
invariant(result != null); | |||
expect(result.length).to.equal(1); | |||
expect(result[0].isEqual(new Range([0, 1], [0, 2]))).to.be.true; | |||
if (result) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests required a bunch of null/undefined checks so that the compiler would be happy
@@ -178,7 +178,7 @@ export interface CodeActionProvider { | |||
editor: TextEditor, | |||
range: Range, | |||
diagnostics: Diagnostic[], | |||
): Promise<CodeAction[]>; | |||
): Promise<CodeAction[] | null>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation of getCodeActions
in AutoLanguageClient
can return null, so had to add it here
efd506a
to
a449d20
Compare
a449d20
to
f42e380
Compare
@daviwil thanks for keeping me in the loop. I should clarify that I'm neither Typescript, nor Flow expert 😅I'm writing a Scala.js type-facade for this library (here). So I just want to understand what's changing here, why and how it influences my work. I'm going to go through all your comments, but before that have a general question: wouldn't it make more sense to use consistently only one kind of "default"/absent value ( |
@laughedelic It seems that there's a lot of debate over Let me know if you have any other questions! |
@daviwil thanks for the answer and the link! That thread is huge, but has a lot of interesting opinions. I got your point, it will be useful for me when working with the library. The inconvenience of using |
Please let me know if there are any places where these changes are incorrect!
/cc @laughedelic