Solidity code linter providing security and style guide validations for smart contract development
—
Reporter system for collecting, managing, and accessing linting results with severity levels and structured output. The Reporter class is the central mechanism for gathering and organizing linting issues found during code analysis.
Main class for collecting and managing linting results during code analysis.
/**
* Creates a new Reporter instance for collecting linting results
* @param {Array} tokens - Array of parsed tokens from source code
* @param {Object} config - Configuration object with rules
*/
class Reporter {
constructor(tokens, config);
}Usage Examples:
const Reporter = require('solhint/lib/reporter');
// Create reporter instance
const tokens = []; // From parser
const config = { rules: { 'func-visibility': 'error' } };
const reporter = new Reporter(tokens, config);
// Reporter is typically created internally by processing functions
const { processStr } = require('solhint');
const report = processStr('contract Test {}'); // Returns Reporter instanceAdds a linting report/issue with specific location and severity information.
/**
* Adds a linting report/issue
* @param {number} line - Line number where issue occurs
* @param {number} column - Column number where issue occurs
* @param {number} severity - Severity level (Reporter.SEVERITY.ERROR or Reporter.SEVERITY.WARN)
* @param {string} message - Description of the issue
* @param {string} ruleId - Identifier of the rule that triggered this report
* @param {Function} fix - Optional fix function for auto-fixing (optional)
*/
addReport(line, column, severity, message, ruleId, fix);Usage Examples:
// Add error report
reporter.addReport(
10,
5,
Reporter.SEVERITY.ERROR,
'Function visibility must be declared',
'func-visibility'
);
// Add warning with fix function
reporter.addReport(
15,
8,
Reporter.SEVERITY.WARN,
'Variable name should be in mixedCase',
'var-name-mixedcase',
(fixer) => fixer.replaceText(node, 'correctedName')
);Adds a message using AST location object for automatic line/column extraction.
/**
* Adds a message using AST location object
* @param {Object} loc - AST location object with start/end properties
* @param {number} defaultSeverity - Default severity level if not configured
* @param {string} message - Description of the issue
* @param {string} ruleId - Identifier of the rule
* @param {Function} fix - Optional fix function (optional)
*/
addMessage(loc, defaultSeverity, message, ruleId, fix);Adds a message with explicit line and column numbers, applying rule configuration and comment directive checks.
/**
* Adds a message with explicit line and column numbers
* @param {number} line - Line number where issue occurs
* @param {number} column - Column number where issue occurs
* @param {number} defaultSeverity - Default severity level if not configured
* @param {string} message - Description of the issue
* @param {string} ruleId - Identifier of the rule
* @param {Function} fix - Optional fix function (optional)
*/
addMessageExplicitLine(line, column, defaultSeverity, message, ruleId, fix);Usage Examples:
// Using AST node location
const astNode = {
loc: {
start: { line: 12, column: 4 },
end: { line: 12, column: 20 }
}
};
reporter.addMessage(
astNode.loc,
Reporter.SEVERITY.ERROR,
'Avoid using low level calls',
'avoid-low-level-calls'
);Convenience method for adding error-level reports using AST context.
/**
* Adds an error-level report
* @param {Object} ctx - AST context object with location information
* @param {string} ruleId - Rule identifier
* @param {string} message - Error message
* @param {Function} fix - Optional fix function (optional)
*/
error(ctx, ruleId, message, fix);Convenience method for adding warning-level reports using AST context.
/**
* Adds a warning-level report
* @param {Object} ctx - AST context object with location information
* @param {string} ruleId - Rule identifier
* @param {string} message - Warning message
* @param {Function} fix - Optional fix function (optional)
*/
warn(ctx, ruleId, message, fix);Convenience method for adding error-level reports at specific line and column.
/**
* Adds an error-level report at specific location
* @param {number} line - Line number where error occurs
* @param {number} column - Column number where error occurs
* @param {string} ruleId - Rule identifier
* @param {string} message - Error message
*/
errorAt(line, column, ruleId, message);Usage Examples:
// In a rule implementation
class MyRule {
visitFunctionDefinition(node) {
if (node.visibility === null) {
this.reporter.error(
node,
'func-visibility',
'Function visibility must be declared'
);
}
if (node.name.startsWith('_') && node.visibility === 'public') {
this.reporter.warn(
node,
'private-vars-leading-underscore',
'Public functions should not start with underscore'
);
}
}
}Returns the count of error-level reports.
/**
* Returns count of error-level reports
* @returns {number} Number of errors
*/
get errorCount();Returns the count of warning-level reports.
/**
* Returns count of warning-level reports
* @returns {number} Number of warnings
*/
get warningCount();Returns sorted array of all reports by line number.
/**
* Returns sorted array of all reports
* @returns {Array<Object>} Array of report objects sorted by line number
*/
get messages();Returns the file path being reported on.
/**
* Returns the file path being reported on
* @returns {string} File path
*/
get filePath();Usage Examples:
const { processFile } = require('solhint');
const report = processFile('./contracts/Token.sol');
// Check results
console.log(`File: ${report.filePath}`);
console.log(`Errors: ${report.errorCount}`);
console.log(`Warnings: ${report.warningCount}`);
// Process all messages
report.messages.forEach(msg => {
const severity = msg.severity === Reporter.SEVERITY.ERROR ? 'ERROR' : 'WARN';
console.log(`${severity} at line ${msg.line}: ${msg.message} (${msg.ruleId})`);
});
// Check if file has any issues
if (report.errorCount > 0) {
console.log('File has errors that must be fixed');
process.exit(1);
}
if (report.warningCount > 0) {
console.log('File has warnings that should be addressed');
}Each report in the messages array has the following structure:
interface LintingReport {
line: number; // Line number (1-based)
column: number; // Column number (1-based, adjusted by +1)
severity: number; // SEVERITY.ERROR (2) or SEVERITY.WARN (3)
message: string; // Human-readable description
ruleId: string; // Rule identifier (e.g., 'func-visibility')
fix?: Function; // Optional fix function for auto-fixing
}const SEVERITY = {
ERROR: 2, // Critical issues that should block deployment
WARN: 3 // Style issues and recommendations
};Usage Examples:
// Check severity levels
report.messages.forEach(msg => {
if (msg.severity === Reporter.SEVERITY.ERROR) {
console.error(`CRITICAL: ${msg.message}`);
} else if (msg.severity === Reporter.SEVERITY.WARN) {
console.warn(`WARNING: ${msg.message}`);
}
});The Reporter respects rule configuration for severity levels:
['error', ...options] where first element is severity// solhint-disable-next-line rule-nameConfiguration Examples:
const config = {
rules: {
'func-visibility': 'error', // Always error
'max-line-length': ['warn', 120], // Warning with option
'no-console': 'off' // Disabled
}
};Reports can include fix functions for automatic code correction:
// Fix function example
const fix = (fixer) => {
return fixer.replaceText(node, 'public');
};
reporter.addReport(line, col, severity, message, ruleId, fix);Fix functions work with the RuleFixer system to modify source code safely.
Install with Tessl CLI
npx tessl i tessl/npm-solhint