Merge pull request #388 from wilzbach/local-imports-sortedness
Imports sortedness check: handle local imports in their separate scope
This commit is contained in:
commit
6ce77ecaed
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
module analysis.imports_sortedness;
|
module analysis.imports_sortedness;
|
||||||
|
|
||||||
|
import analysis.base : BaseAnalyzer;
|
||||||
import dparse.lexer;
|
import dparse.lexer;
|
||||||
import dparse.ast;
|
import dparse.ast;
|
||||||
import analysis.base : BaseAnalyzer;
|
|
||||||
|
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
|
|
||||||
|
@ -26,10 +26,32 @@ class ImportSortednessCheck : BaseAnalyzer
|
||||||
|
|
||||||
override void visit(const Module mod)
|
override void visit(const Module mod)
|
||||||
{
|
{
|
||||||
globalImports = [];
|
level = 0;
|
||||||
|
imports[level] = [];
|
||||||
mod.accept(this);
|
mod.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override void visit(const Statement decl)
|
||||||
|
{
|
||||||
|
imports[++level] = [];
|
||||||
|
decl.accept(this);
|
||||||
|
level--;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void visit(const BlockStatement decl)
|
||||||
|
{
|
||||||
|
imports[++level] = [];
|
||||||
|
decl.accept(this);
|
||||||
|
level--;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void visit(const StructBody decl)
|
||||||
|
{
|
||||||
|
imports[++level] = [];
|
||||||
|
decl.accept(this);
|
||||||
|
level--;
|
||||||
|
}
|
||||||
|
|
||||||
override void visit(const ImportDeclaration id)
|
override void visit(const ImportDeclaration id)
|
||||||
{
|
{
|
||||||
import std.algorithm.iteration : map;
|
import std.algorithm.iteration : map;
|
||||||
|
@ -59,20 +81,21 @@ class ImportSortednessCheck : BaseAnalyzer
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
string[] globalImports;
|
int level = 0;
|
||||||
|
string[][int] imports;
|
||||||
|
|
||||||
void addImport(string importModuleName, const SingleImport singleImport)
|
void addImport(string importModuleName, const SingleImport singleImport)
|
||||||
{
|
{
|
||||||
import std.uni : sicmp;
|
import std.uni : sicmp;
|
||||||
|
|
||||||
if (globalImports.length > 0 && globalImports[$ -1].sicmp(importModuleName) > 0)
|
if (imports[level].length > 0 && imports[level][$ -1].sicmp(importModuleName) > 0)
|
||||||
{
|
{
|
||||||
addErrorMessage(singleImport.identifierChain.identifiers[0].line,
|
addErrorMessage(singleImport.identifierChain.identifiers[0].line,
|
||||||
singleImport.identifierChain.identifiers[0].column, KEY, MESSAGE);
|
singleImport.identifierChain.identifiers[0].column, KEY, MESSAGE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
globalImports ~= importModuleName;
|
imports[level] ~= importModuleName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,5 +210,136 @@ unittest
|
||||||
ImportSortednessCheck.MESSAGE,
|
ImportSortednessCheck.MESSAGE,
|
||||||
), sac);
|
), sac);
|
||||||
|
|
||||||
|
// local imports in functions
|
||||||
|
assertAnalyzerWarnings(q{
|
||||||
|
import t2;
|
||||||
|
import t1; // [warn]: %s
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
import f2;
|
||||||
|
import f1; // [warn]: %s
|
||||||
|
import f3;
|
||||||
|
}
|
||||||
|
void bar()
|
||||||
|
{
|
||||||
|
import f1;
|
||||||
|
import f2;
|
||||||
|
}
|
||||||
|
}c.format(
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
), sac);
|
||||||
|
|
||||||
|
// local imports in scopes
|
||||||
|
assertAnalyzerWarnings(q{
|
||||||
|
import t2;
|
||||||
|
import t1; // [warn]: %s
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
import f2;
|
||||||
|
import f1; // [warn]: %s
|
||||||
|
import f3;
|
||||||
|
{
|
||||||
|
import f2;
|
||||||
|
import f1; // [warn]: %s
|
||||||
|
import f3;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
import f1;
|
||||||
|
import f2;
|
||||||
|
import f3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}c.format(
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
), sac);
|
||||||
|
|
||||||
|
// local imports in functions
|
||||||
|
assertAnalyzerWarnings(q{
|
||||||
|
import t2;
|
||||||
|
import t1; // [warn]: %s
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
import f2;
|
||||||
|
import f1; // [warn]: %s
|
||||||
|
import f3;
|
||||||
|
while (true) {
|
||||||
|
import f2;
|
||||||
|
import f1; // [warn]: %s
|
||||||
|
import f3;
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
import f1;
|
||||||
|
import f2;
|
||||||
|
import f3;
|
||||||
|
}
|
||||||
|
foreach (el; arr) {
|
||||||
|
import f2;
|
||||||
|
import f1; // [warn]: %s
|
||||||
|
import f3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}c.format(
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
), sac);
|
||||||
|
|
||||||
|
// nested scopes
|
||||||
|
assertAnalyzerWarnings(q{
|
||||||
|
import t2;
|
||||||
|
import t1; // [warn]: %s
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
import f2;
|
||||||
|
import f1; // [warn]: %s
|
||||||
|
import f3;
|
||||||
|
{
|
||||||
|
import f2;
|
||||||
|
import f1; // [warn]: %s
|
||||||
|
import f3;
|
||||||
|
{
|
||||||
|
import f2;
|
||||||
|
import f1; // [warn]: %s
|
||||||
|
import f3;
|
||||||
|
{
|
||||||
|
import f2;
|
||||||
|
import f1; // [warn]: %s
|
||||||
|
import f3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}c.format(
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
), sac);
|
||||||
|
|
||||||
|
// local imports in functions
|
||||||
|
assertAnalyzerWarnings(q{
|
||||||
|
import t2;
|
||||||
|
import t1; // [warn]: %s
|
||||||
|
struct foo()
|
||||||
|
{
|
||||||
|
import f2;
|
||||||
|
import f1; // [warn]: %s
|
||||||
|
import f3;
|
||||||
|
}
|
||||||
|
class bar()
|
||||||
|
{
|
||||||
|
import f1;
|
||||||
|
import f2;
|
||||||
|
}
|
||||||
|
}c.format(
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
ImportSortednessCheck.MESSAGE,
|
||||||
|
), sac);
|
||||||
|
|
||||||
stderr.writeln("Unittest for ImportSortednessCheck passed.");
|
stderr.writeln("Unittest for ImportSortednessCheck passed.");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue