Skip to content

Commit

Permalink
feat: ignoring some node types (#2)
Browse files Browse the repository at this point in the history
* feat: ignoring some node types

* test: added processor tests
  • Loading branch information
0xGorilla authored Jan 9, 2024
1 parent 4973559 commit 966c676
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 25 deletions.
12 changes: 12 additions & 0 deletions sample-data/LibrarySample.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity =0.8.19;

library StringUtils {
function nothing(string memory input) public pure returns (string memory) {
return input;
}
}

contract BasicSample {
using StringUtils for string;
}
34 changes: 9 additions & 25 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
import { compileSol } from 'solc-typed-ast';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import { SolcContractNode } from './types/solc-typed-ast.t';
import { parseNodeNatspec } from './parser';
import { validate } from './validator';
import { getRemappings, getSolidityFiles } from './utils';
import { processSources } from './processor';

(async () => {
const { base, contracts } = getArguments();
Expand All @@ -21,29 +19,15 @@ import { getRemappings, getSolidityFiles } from './utils';
remapping: remappings,
includePath: [base],
});

for (const [fileName, source] of Object.entries(compiledFiles.data.sources)) {
if (fileName.startsWith('node_modules') || fileName.startsWith('lib')) continue;

const fileContracts = (source as any).ast.nodes.filter((node: any) => node.nodeType === 'ContractDefinition');
fileContracts.forEach((contract: any) => {
const nodes = contract.nodes as SolcContractNode[];

nodes.forEach(node => {
const nodeNatspec = parseNodeNatspec(node);
const warnings = validate(node, nodeNatspec);

// print warnings
if (warnings.length) {
console.warn(`Natspec warnings in ${fileName}:${contract.name}:${node.name}`);
warnings.forEach(warning => {
console.warn(' ' + warning);
});
}
});
});
const warnings = await processSources(compiledFiles.data.sources);

}
warnings.forEach(({ location, messages }) => {
console.warn(location);
messages.forEach(message => {
console.warn(' ' + message);
});
});
})().catch(console.error);

function getArguments() {
Expand All @@ -61,4 +45,4 @@ function getArguments() {
},
})
.parseSync();
}
}
41 changes: 41 additions & 0 deletions src/processor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { parseNodeNatspec } from "./parser";
import { SolcContractNode } from "./types/solc-typed-ast.t";
import { validate } from "./validator";

interface IWarning {
location: string;
messages: string[];
}

// TODO: better check all the options here
const ignoredNodeTypes = ['UsingForDirective'];

export async function processSources(sources: any): Promise<IWarning[]> {
let warnings: IWarning[] = [];

for (const [fileName, source] of Object.entries(sources)) {
if (fileName.startsWith('node_modules') || fileName.startsWith('lib')) continue;

const fileContracts = (source as any).ast.nodes.filter((node: any) => node.nodeType === 'ContractDefinition');
fileContracts.forEach((contract: any) => {
const nodes = contract.nodes as SolcContractNode[];

nodes
.filter(node => !ignoredNodeTypes.includes(node.nodeType))
.forEach(node => {
const nodeNatspec = parseNodeNatspec(node);
const validationMessages = validate(node, nodeNatspec);
const nodeName = node.name || node.kind;

if (validationMessages.length) {
warnings.push({
location: `${fileName}:${contract.name}:${nodeName}`,
messages: validationMessages,
});
}
});
});
}

return warnings;
}
19 changes: 19 additions & 0 deletions test/processor.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { processSources } from '../src/processor';
import { parseSolidityFile } from './test-utils';

describe('processSources', () => {

describe('LibrarySample.sol', () => {

it('should return warnings only for the library method empty natspec', async () => {
const sources = (await parseSolidityFile('sample-data/LibrarySample.sol')).data.sources;
const warnings = await processSources(sources);
expect(warnings).toEqual([
{
location: 'sample-data/LibrarySample.sol:StringUtils:nothing',
messages: ['Natspec is missing']
},
]);
});
});
});

0 comments on commit 966c676

Please sign in to comment.