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

When every import is unused, error on the entire import declaration #22386

Merged
4 commits merged into from
Mar 7, 2018

Conversation

ghost
Copy link

@ghost ghost commented Mar 7, 2018

@ghost ghost requested review from amcasey and sheetalkamat March 7, 2018 20:58
@ghost ghost force-pushed the unusedImports_entireImportDeclaration branch from 2e25654 to 142d881 Compare March 7, 2018 21:00
@ghost ghost force-pushed the unusedImports_entireImportDeclaration branch from 142d881 to bda9140 Compare March 7, 2018 21:12
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));
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. 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.

  2. 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 or all imports in import declaration are unused

Copy link
Member

@amcasey amcasey left a 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!

for (const declaration of local.declarations) {
if (isAmbientModule(declaration)) continue;
if (isImportedDeclaration(declaration)) {
unusedImports.push(declaration);
Copy link
Member

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.

Copy link
Author

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));
Copy link
Member

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?

Copy link
Author

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'",
Copy link
Member

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'"?

@amcasey
Copy link
Member

amcasey commented Mar 7, 2018

@andy-ms looks like you might need to regenerate baselines - there's a conflict with your expanded range change.

Copy link
Member

@amcasey amcasey left a 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.

}
}
});

unusedImports.forEach(unuseds => {
const importClause = importClauseFromImported(first(unuseds)); // others will have the same clause
Copy link
Member

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?

Copy link
Author

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.

Copy link
Author

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...

Copy link
Member

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.

@ghost ghost merged commit 1f7a509 into master Mar 7, 2018
@ghost ghost deleted the unusedImports_entireImportDeclaration branch March 7, 2018 22:42
@microsoft microsoft locked and limited conversation to collaborators Jul 25, 2018
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants