-
Notifications
You must be signed in to change notification settings - Fork 118
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
Enable "strict" compiler option #178
Conversation
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.
Thanks for doing this cleanup! And sorry if some of these comments are dumb, I'm not deeply familiar with TS's type system. I do think if we're going to enable strict mode then I should understand it though...
@@ -163,16 +164,16 @@ class TreeAdapter implements vscode.TreeDataProvider<ASTNode> { | |||
return element.children || []; | |||
} | |||
|
|||
public getParent(node: ASTNode): ASTNode { | |||
public getParent(node: ASTNode): ASTNode|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.
There are a bunch of places in this class where you've changed null
to undefined
- is there some fundamental reason why null is incorrect? (It makes sense to be consistent within a module of course.
My understanding is this is mostly a stylistic choice, and my preference would be to use null for "deliberately" null values, but this isn't my primary language...
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.
Sorry if I came across as pompous saying that null
was "incorrect", that really wasn't the right word. There were inconsistent usages of null
vs undefined
which were causing type errors. I leaned towards undefined because generally it seems to be the preferred "bottom value" for typescript, or at least in terms of working with vscode's API's (Plus null
has some weird properties like having typeof 'object'
. But, it's definitely a preference kind-of-thing whether to use it or not). You're right though, null
is used deliberately/explicitly. But, I would make the argument that unless the logic makes a distinction between a variable being undefined
vs null
, then it's probably a better idea to use one or the other consistently, rather than specifying that something can be SomeType | 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.
No worries at all. I think if undefined
is privileged by the ?.
operators etc then ergonomics is a good reason to prefer it.
(And it seems so, playground says (null as any)?.foo
is undefined
)
And this seems to be MS's preference, and it's mostly their APIs we're dealing with.
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 agree. So just to confirm, are deciding to use undefined
for values stored by the extension and accepting null
for incoming values (when necessary)?
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.
That sounds good to me!
src/clangd-context.ts
Outdated
@@ -58,7 +58,7 @@ export class ClangdContext implements vscode.Disposable { | |||
await config.getSecureOrPrompt<string[]>('arguments', workspaceState), | |||
options: {cwd: vscode.workspace.rootPath || process.cwd()} | |||
}; | |||
const traceFile = config.get<string>('trace'); | |||
const traceFile = config.get<string>('trace', ''); |
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 think that echoing defaults already given in the package.json is unacceptable duplication (and causes practical problems e.g. someone changing the default in the wrong place).
Can we add a !
assertion in config.get() instead?
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.
That's fair. I believe the defaults can be retrieved through WorkspaceConfiguration.inspect()
, but that may be more trouble than it's worth. Realistically adding asserts here would only cause a problem if a default value was removed from package.json
, but I expect that's quite unlikely.
@@ -80,8 +80,8 @@ class MemoryUsageFeature implements vscodelc.StaticFeature { | |||
class TreeAdapter implements vscode.TreeDataProvider<InternalTree> { | |||
private root_?: InternalTree; | |||
|
|||
get root(): InternalTree|null { return this.root_; } | |||
set root(n: InternalTree|null) { | |||
get root(): InternalTree|undefined { return this.root_; } |
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.
again why these null->undefined changes?
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.
Addressed in a previous comment, but it's because private root_?: InternalTree
is already declared as being InternalTree | undefined
.
@@ -16,7 +16,7 @@ | |||
], | |||
"sourceMap": true, | |||
"rootDir": ".", | |||
"alwaysStrict": true, | |||
"strict": true, |
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.
It's surprising that "strict" is more strict than "alwaysStrict" :-)
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.
Yeah, it really seems like a "gcc -Wall" scenario haha.
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.
Addressed comments (further consensus is needed on the null
vs undefined
issue).
@@ -163,16 +164,16 @@ class TreeAdapter implements vscode.TreeDataProvider<ASTNode> { | |||
return element.children || []; | |||
} | |||
|
|||
public getParent(node: ASTNode): ASTNode { | |||
public getParent(node: ASTNode): ASTNode|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.
Sorry if I came across as pompous saying that null
was "incorrect", that really wasn't the right word. There were inconsistent usages of null
vs undefined
which were causing type errors. I leaned towards undefined because generally it seems to be the preferred "bottom value" for typescript, or at least in terms of working with vscode's API's (Plus null
has some weird properties like having typeof 'object'
. But, it's definitely a preference kind-of-thing whether to use it or not). You're right though, null
is used deliberately/explicitly. But, I would make the argument that unless the logic makes a distinction between a variable being undefined
vs null
, then it's probably a better idea to use one or the other consistently, rather than specifying that something can be SomeType | undefined | null
.
src/clangd-context.ts
Outdated
@@ -58,7 +58,7 @@ export class ClangdContext implements vscode.Disposable { | |||
await config.getSecureOrPrompt<string[]>('arguments', workspaceState), | |||
options: {cwd: vscode.workspace.rootPath || process.cwd()} | |||
}; | |||
const traceFile = config.get<string>('trace'); | |||
const traceFile = config.get<string>('trace', ''); |
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.
That's fair. I believe the defaults can be retrieved through WorkspaceConfiguration.inspect()
, but that may be more trouble than it's worth. Realistically adding asserts here would only cause a problem if a default value was removed from package.json
, but I expect that's quite unlikely.
@@ -80,8 +80,8 @@ class MemoryUsageFeature implements vscodelc.StaticFeature { | |||
class TreeAdapter implements vscode.TreeDataProvider<InternalTree> { | |||
private root_?: InternalTree; | |||
|
|||
get root(): InternalTree|null { return this.root_; } | |||
set root(n: InternalTree|null) { | |||
get root(): InternalTree|undefined { return this.root_; } |
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.
Addressed in a previous comment, but it's because private root_?: InternalTree
is already declared as being InternalTree | undefined
.
@@ -16,7 +16,7 @@ | |||
], | |||
"sourceMap": true, | |||
"rootDir": ".", | |||
"alwaysStrict": true, | |||
"strict": true, |
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.
Yeah, it really seems like a "gcc -Wall" scenario haha.
I was going crazy there for a minute wondering how the CI was failing on a non-existent file when the tests passed on my machine 😅. Anyways I merged and modified the new file for strict type checking. I fixed all the things that were mentioned. Additionally I changed all |
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.
Thanks a lot!
Happy to help 👍 |
Closes #61.
Changes have been made to adhere to strict type checking:
!
post-fix operator) have been added to please the compiler (these do not affect the compiled output). These assertions are not always strictly "safe", but are not any less safe than not having strict type checking at all. Plus, their presence in the code can be a signal that maybe the design should be changed to safely ensure that the types are not null/undefined.?.
) has been been added when properties can be null/undefined.null
have been replaced withundefined
.defaultValue
arguments toWorkspaceConfiguration.get()
so that it will not return undefined. The default values being passed are the default values defined in the package.json. Realistically, the function should not return undefined when default values are defined in the package.json, but this pleases the compiler.The changes I've made were aimed at not changing the behavior of the extension, and weren't necessarily aimed at fixing any potential bugs. Strict type checking will make it less likely to introduce new bugs in future changes.