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;
|
||||
|
||||
import analysis.base : BaseAnalyzer;
|
||||
import dparse.lexer;
|
||||
import dparse.ast;
|
||||
import analysis.base : BaseAnalyzer;
|
||||
|
||||
import std.stdio;
|
||||
|
||||
|
@ -26,10 +26,32 @@ class ImportSortednessCheck : BaseAnalyzer
|
|||
|
||||
override void visit(const Module mod)
|
||||
{
|
||||
globalImports = [];
|
||||
level = 0;
|
||||
imports[level] = [];
|
||||
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)
|
||||
{
|
||||
import std.algorithm.iteration : map;
|
||||
|
@ -59,20 +81,21 @@ class ImportSortednessCheck : BaseAnalyzer
|
|||
|
||||
private:
|
||||
|
||||
string[] globalImports;
|
||||
int level = 0;
|
||||
string[][int] imports;
|
||||
|
||||
void addImport(string importModuleName, const SingleImport singleImport)
|
||||
{
|
||||
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,
|
||||
singleImport.identifierChain.identifiers[0].column, KEY, MESSAGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
globalImports ~= importModuleName;
|
||||
imports[level] ~= importModuleName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -187,5 +210,136 @@ unittest
|
|||
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;
|
||||
}
|
||||
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.");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue