From 746cc7a7ca254d3faa7c4514b105af3bcfcacd4c Mon Sep 17 00:00:00 2001 From: capu Date: Tue, 28 Feb 2023 16:24:04 -0300 Subject: [PATCH] process variable definitions as import usages --- lib/rules/best-practises/no-unused-import.js | 15 +++++++++-- test/rules/best-practises/no-unused-import.js | 27 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/lib/rules/best-practises/no-unused-import.js b/lib/rules/best-practises/no-unused-import.js index 50e29b84..991c6bc1 100644 --- a/lib/rules/best-practises/no-unused-import.js +++ b/lib/rules/best-practises/no-unused-import.js @@ -29,11 +29,22 @@ class NoUnusedImportsChecker extends BaseChecker { }) } + VariableDeclaration(node) { + if (node.typeName.type === 'UserDefinedTypeName') { + const importedName = node.typeName.namePath.split('.')[0] + if (this.importedNames[importedName]) { + this.importedNames[importedName].used = true + } else { + throw new Error('imported name isnt registered') + } + } + } + ContractDefinition(node) { node.baseContracts.forEach((inheritanceSpecifier) => { if (inheritanceSpecifier.baseName.type === 'UserDefinedTypeName') { if (!this.importedNames[inheritanceSpecifier.baseName.namePath]) { - throw new Error('contract name isnt registered') + throw new Error('imported name isnt registered') } this.importedNames[inheritanceSpecifier.baseName.namePath].used = true } else { @@ -47,7 +58,7 @@ class NoUnusedImportsChecker extends BaseChecker { if (this.importedNames[name]) { this.importedNames[name].used = true } else { - throw new Error('library name isnt registered') + throw new Error('imported name isnt registered') } } diff --git a/test/rules/best-practises/no-unused-import.js b/test/rules/best-practises/no-unused-import.js index f0ce7c45..77c9ef92 100644 --- a/test/rules/best-practises/no-unused-import.js +++ b/test/rules/best-practises/no-unused-import.js @@ -39,6 +39,33 @@ describe('Linter - no-unused-import', () => { assertNoErrors(report) }) + it('should not raise when contract name is used in a state variable declaration', () => { + const code = `import {A} from './A.sol'; contract B { A public statevar; }` + + const report = linter.processStr(code, { + rules: { 'no-unused-import': 'error' }, + }) + assertNoErrors(report) + }) + + it('should not raise when an imported subtype is used in a state variable declaration', () => { + const code = `import {A} from './A.sol'; contract B { A.thing public statevar; }` + + const report = linter.processStr(code, { + rules: { 'no-unused-import': 'error' }, + }) + assertNoErrors(report) + }) + + it('should not raise when one of the imported contracts types is used in a function parameter declaration', () => { + const code = `import {A} from './A.sol'; contract B { function (A.thing statevar) public {} }` + + const report = linter.processStr(code, { + rules: { 'no-unused-import': 'error' }, + }) + assertNoErrors(report) + }) + it('should raise when some of the imported names are not used', () => { const code = `import {A, B} from './A.sol'; contract C is A {}`