@slippy-lint/slippy
Version:
A simple but powerful linter for Solidity
52 lines (45 loc) • 1.47 kB
text/typescript
import {
Diagnostic,
RuleContext,
RuleDefinitionWithoutConfig,
RuleWithoutConfig,
} from "./types.js";
import { NonterminalKind, TerminalKind } from "@nomicfoundation/slang/cst";
export const ImportsOnTop: RuleDefinitionWithoutConfig = {
name: "imports-on-top",
recommended: true,
create: function () {
return new ImportsOnTopRule(this.name);
},
};
class ImportsOnTopRule implements RuleWithoutConfig {
constructor(public name: string) {}
public run({ file }: RuleContext): Diagnostic[] {
const diagnostics: Diagnostic[] = [];
const cursor = file.createTreeCursor();
let hasSeenNonImport = false;
while (
cursor.goToNextNonterminalWithKind(NonterminalKind.SourceUnitMember)
) {
if (!cursor.goToFirstChild()) {
continue;
}
if (cursor.node.kind === NonterminalKind.ImportDirective) {
if (hasSeenNonImport) {
cursor.goToNextTerminalWithKind(TerminalKind.ImportKeyword);
// If we have seen a non-import directive before this import,
diagnostics.push({
rule: this.name,
message: "Imports should be at the top of the file.",
sourceId: file.id,
line: cursor.textRange.start.line,
column: cursor.textRange.start.column,
});
}
} else if (cursor.node.kind !== NonterminalKind.PragmaDirective) {
hasSeenNonImport = true;
}
}
return diagnostics;
}
}