diff --git a/sample-data/BasicSample.sol b/sample-data/BasicSample.sol index 239fbac..5554dba 100644 --- a/sample-data/BasicSample.sol +++ b/sample-data/BasicSample.sol @@ -1,7 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity =0.8.19; -contract BasicSample { +abstract contract AbstractBasic { + function overriddenFunction() internal pure virtual returns (uint256 _returned); +} + +contract BasicSample is AbstractBasic { /** * @notice Some notice of the struct */ @@ -72,6 +76,15 @@ contract BasicSample { return (true, 111); } + /** + * @notice This function should have an inheritdoc tag + */ + function overriddenFunction() internal pure override returns (uint256 _returned) { + return 1; + } + + function virtualFunction() public pure virtual returns (uint256 _returned) {} + /** * @notice Modifier notice */ diff --git a/src/validator.ts b/src/validator.ts index c70bdf8..2f323bb 100644 --- a/src/validator.ts +++ b/src/validator.ts @@ -99,8 +99,8 @@ export class Validator { _requiresInheritdoc ||= node instanceof FunctionDefinition && (node.visibility === 'external' || node.visibility === 'public') && !node.isConstructor; - // Internal virtual function - _requiresInheritdoc ||= node instanceof FunctionDefinition && node.visibility === 'internal' && node.virtual; + // Overridden internal functions + _requiresInheritdoc ||= node instanceof FunctionDefinition && node.visibility === 'internal' && !!node.vOverrideSpecifier; // Public variable _requiresInheritdoc ||= node instanceof VariableDeclaration && node.visibility === 'public'; diff --git a/test/validator.test.ts b/test/validator.test.ts index 9090063..1d19196 100644 --- a/test/validator.test.ts +++ b/test/validator.test.ts @@ -2,12 +2,13 @@ import { ContractDefinition } from 'solc-typed-ast'; import { Validator } from '../src/validator'; import { getFileCompiledSource } from './utils'; import { Config, NodeToProcess } from '../src/types'; +import { before } from 'node:test'; describe('Validator', () => { let contract: ContractDefinition; let node: NodeToProcess; - const config: Config = { + let config: Config = { root: '.', include: './sample-data', exclude: [], @@ -15,12 +16,11 @@ describe('Validator', () => { constructorNatspec: false, }; - const validator: Validator = new Validator(config); + let validator: Validator = new Validator(config); beforeAll(async () => { const compileResult = await getFileCompiledSource('sample-data/BasicSample.sol'); - contract = compileResult.vContracts[0]; - node = contract.vFunctions.find(({ name }) => name === 'externalSimple')!; + contract = compileResult.vContracts.find(({ name }) => name === 'BasicSample')!; }); let natspec = { @@ -57,11 +57,14 @@ describe('Validator', () => { }; it('should validate proper natspec', () => { + node = contract.vFunctions.find(({ name }) => name === 'externalSimple')!; + const result = validator.validate(node, natspec); expect(result).toEqual([]); }); it('should reveal missing natspec for parameters', () => { + node = contract.vFunctions.find(({ name }) => name === 'externalSimple')!; const paramName = '_magicNumber'; let natspec = { tags: [ @@ -239,4 +242,40 @@ describe('Validator', () => { expect(result).toContainEqual(`@param ${paramName1} is missing`); expect(result).toContainEqual(`@param ${paramName2} is missing`); }); + + describe('with enforced inheritdoc', () => { + beforeAll(async () => { + config = { + root: '.', + include: './sample-data', + exclude: [], + enforceInheritdoc: true, + constructorNatspec: false, + }; + + validator = new Validator(config); + }); + + it('should reveal missing inheritdoc for an overridden function', () => { + node = contract.vFunctions.find(({ name }) => name === 'overriddenFunction')!; + natspec = { + tags: [], + params: [], + returns: [], + }; + const result = validator.validate(node, natspec); + expect(result).toContainEqual(`@inheritdoc is missing`); + }); + + it('should reveal missing inheritdoc for a virtual function', () => { + node = contract.vFunctions.find(({ name }) => name === 'virtualFunction')!; + natspec = { + tags: [], + params: [], + returns: [], + }; + const result = validator.validate(node, natspec); + expect(result).toContainEqual(`@inheritdoc is missing`); + }); + }); }); diff --git a/tsconfig.json b/tsconfig.json index bbc5894..d4288ef 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,6 @@ "esModuleInterop": true, "module": "commonjs", "noImplicitReturns": true, - "noUnusedLocals": true, "sourceMap": true, "resolveJsonModule": true, "target": "es2020"