-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
When every import is unused, error on the entire import declaration #22386
Conversation
2e25654
to
142d881
Compare
142d881
to
bda9140
Compare
src/compiler/checker.ts
Outdated
const importClause = decl.kind === SyntaxKind.ImportClause ? decl : decl.kind === SyntaxKind.NamespaceImport ? decl.parent : decl.parent.parent; | ||
if (!forEachImportedDeclaration(importClause, d => d !== decl && !contains(unusedImports, d))) { | ||
forEachImportedDeclaration(importClause, d => unorderedRemoveItem(unusedImports, d)); | ||
error(importClause.parent, Diagnostics.No_import_of_0_is_used, showModuleSpecifier(importClause.parent)); |
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.
-
if there is only one import e.g. default or one named import, the other error is superior. i would suggests such extending the span and using the error message with he name of the import.
-
I think the new error message is inaccurate. we just know that the import declaration is not needed, but there may be other import declarations for the same module that are still in use. so possibly remove the name of the module from the error message and say
Import declaration unused
orall imports in import declaration are unused
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!
src/compiler/checker.ts
Outdated
for (const declaration of local.declarations) { | ||
if (isAmbientModule(declaration)) continue; | ||
if (isImportedDeclaration(declaration)) { | ||
unusedImports.push(declaration); |
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.
Personally, I find the forEach code below a little hard to follow. Another way to express this might be to build a multi-map from import clauses to the unused declarations they contain. Then, for each import clause in the map, you could either report a single diagnostic or a list of diagnostics according to whether or not the import clause contained a declaration not in the corresponding unused list. I don't feel strong about this.
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, helped me remove the count
variable.
@@ -38,14 +47,24 @@ namespace ts.codefix { | |||
} | |||
break; | |||
case fixIdDelete: | |||
tryDeleteDeclaration(changes, sourceFile, token); | |||
if (diag.code === Diagnostics.No_import_of_0_is_used.code) { | |||
changes.deleteNode(sourceFile, getImportDeclarationAtErrorLocation(token)); |
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.
Which adjacent trivia does this delete?
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.
Looks like it removes leading but not trailing trivia by default.
////import a, { b } from "mod"; | ||
|
||
verify.codeFix({ | ||
description: "Remove declaration for: 'mod'", |
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 wording is confusing. What about something like "Remove import from 'mod'"?
@andy-ms looks like you might need to regenerate baselines - there's a conflict with your expanded range change. |
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! I find it a lot clearer with the map.
src/compiler/checker.ts
Outdated
} | ||
} | ||
}); | ||
|
||
unusedImports.forEach(unuseds => { | ||
const importClause = importClauseFromImported(first(unuseds)); // others will have the same clause |
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.
Why recompute this? Isn't it the map key?
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.
Unfortunately we don't support non-string keys for maps for compatibility with ES5. See shimMap
.
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.
We could always make the map value be a pair though...
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 must have been thinking of another context. This makes sense, given that limitation.
Part of #22361 (comment)