Skip to content
This repository has been archived by the owner on Oct 10, 2018. It is now read-only.

Commit

Permalink
feat(organize): add configuration to disable removal of unsed imports (
Browse files Browse the repository at this point in the history
…#315)


Relates #311
  • Loading branch information
danieloprado authored and buehler committed Oct 5, 2017
1 parent 4748204 commit 17ae191
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 17 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ The following settings do have the prefix `resolver`. So an example setting coul
| multiLineWrapThreshold | The threshold, when imports are converted into multiline imports |
| multiLineTrailingComma | When multiline imports are created, `true` inserts a trailing comma to the last line |
| disableImportSorting | Disable sorting during organize imports action |
| disableImportRemovalOnOrganize | Disable removal unsed imports during organize imports action |
| importGroups | The groups that are used for sorting the imports (description below) |
| ignoreImportsForOrganize | Imports that are never removed during organize import (e.g. react) |
| resolverMode | Which files should be considered to index for TypeScript Hero |
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@
"default": false,
"description": "Defines if sorting is disable during organize imports."
},
"typescriptHero.resolver.disableImportRemovalOnOrganize": {
"type": "boolean",
"default": false,
"description": "Defines, if removal unsed imports is obligatory during organize imports"
},
"typescriptHero.resolver.organizeOnSave": {
"type": "boolean",
"default": true,
Expand Down
8 changes: 8 additions & 0 deletions src/common/config/ResolverConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ export interface ResolverConfig {
*/
disableImportSorting: boolean;

/**
* Disables removal of the unsed imports on organize.
*
* @type {boolean}
* @memberof ResolverConfig
*/
disableImportRemovalOnOrganize: boolean;

/**
* List of import libraries ("from" part) which are ignored during the organize import function.
*
Expand Down
12 changes: 12 additions & 0 deletions src/extension/VscodeExtensionConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,18 @@ class VscodeResolverConfig implements ResolverConfig {
return value !== undefined ? value : false;
}

/**
* Defines, if removal unsed is obligatory during organize imports
*
* @readonly
* @type {boolean}
* @memberof ResolverConfig
*/
public get disableImportRemovalOnOrganize(): boolean {
const value = this.workspaceSection.get<boolean>('resolver.disableImportRemovalOnOrganize');
return value !== undefined ? value : false;
}

/**
* Returns the tab size that is configured in vscode.
*
Expand Down
38 changes: 21 additions & 17 deletions src/extension/managers/ImportManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,27 +213,31 @@ export class ImportManager implements ObjectManager {
this.organize = true;
let keep: Import[] = [];

for (const actImport of this.imports) {
if (ImportManager.config.resolver.ignoreImportsForOrganize.indexOf(actImport.libraryName) >= 0) {
keep.push(actImport);
continue;
}
if (actImport instanceof NamespaceImport ||
actImport instanceof ExternalModuleImport) {
if (this._parsedDocument.nonLocalUsages.indexOf(actImport.alias) > -1) {
if (ImportManager.config.resolver.disableImportRemovalOnOrganize) {
keep = this.imports;
} else {
for (const actImport of this.imports) {
if (ImportManager.config.resolver.ignoreImportsForOrganize.indexOf(actImport.libraryName) >= 0) {
keep.push(actImport);
continue;
}
} else if (actImport instanceof NamedImport) {
actImport.specifiers = actImport.specifiers
.filter(o => this._parsedDocument.nonLocalUsages.indexOf(o.alias || o.specifier) > -1)
.sort(specifierSort);
const defaultSpec = actImport.defaultAlias;
if (actImport.specifiers.length ||
(!!defaultSpec && this._parsedDocument.nonLocalUsages.indexOf(defaultSpec) >= 0)) {
if (actImport instanceof NamespaceImport ||
actImport instanceof ExternalModuleImport) {
if (this._parsedDocument.nonLocalUsages.indexOf(actImport.alias) > -1) {
keep.push(actImport);
}
} else if (actImport instanceof NamedImport) {
actImport.specifiers = actImport.specifiers
.filter(o => this._parsedDocument.nonLocalUsages.indexOf(o.alias || o.specifier) > -1)
.sort(specifierSort);
const defaultSpec = actImport.defaultAlias;
if (actImport.specifiers.length ||
(!!defaultSpec && this._parsedDocument.nonLocalUsages.indexOf(defaultSpec) >= 0)) {
keep.push(actImport);
}
} else if (actImport instanceof StringImport) {
keep.push(actImport);
}
} else if (actImport instanceof StringImport) {
keep.push(actImport);
}
}

Expand Down
30 changes: 30 additions & 0 deletions test/extension/extensions/OrganizeImportsOnSaveExtension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,34 @@ describe('OrganizeImportsOnSaveExtension', () => {
);
});

it('should not remove an unused import on save when disableImportRemovalOnOrganize is true', async () => {
const config = vscode.workspace.getConfiguration('typescriptHero');
await config.update('resolver.disableImportRemovalOnOrganize', true);

const ctrl = await ImportManager.create(document);
const declaration = index.declarationInfos.find(o => o.declaration.name === 'Class1');
const declaration2 = index.declarationInfos.find(o => o.declaration.name === 'Class2');
ctrl.addDeclarationImport(declaration!).addDeclarationImport(declaration2!);
await ctrl.commit();

document.lineAt(0).text.should.equals(
`import { Class1, Class2 } from '../../../server/indices/MyClass';`,
);

await vscode.window.activeTextEditor!.edit((builder) => {
builder.insert(
new vscode.Position(1, 0),
'let a = new Class2()',
);
});

await document.save();

document.lineAt(0).text.should.equals(
`import { Class1, Class2 } from '../../../server/indices/MyClass';`,
);

await config.update('resolver.disableImportRemovalOnOrganize', false);
});

});

0 comments on commit 17ae191

Please sign in to comment.