1 // Copyright Brian Schott (Hackerpilot) 2014. 2 // Distributed under the Boost Software License, Version 1.0. 3 // (See accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 6 module analysis.local_imports; 7 8 import std.stdio; 9 import dparse.ast; 10 import dparse.lexer; 11 import analysis.base; 12 import analysis.helpers; 13 import dsymbol.scope_; 14 15 /** 16 * Checks for local imports that import all symbols. 17 * See_also: $(LINK https://issues.dlang.org/show_bug.cgi?id=10378) 18 */ 19 class LocalImportCheck : BaseAnalyzer 20 { 21 alias visit = BaseAnalyzer.visit; 22 23 /** 24 * Construct with the given file name. 25 */ 26 this(string fileName, const(Scope)* sc) 27 { 28 super(fileName, sc); 29 } 30 31 mixin visitThing!StructBody; 32 mixin visitThing!BlockStatement; 33 34 override void visit(const Declaration dec) 35 { 36 if (dec.importDeclaration is null) 37 { 38 dec.accept(this); 39 return; 40 } 41 foreach (attr; dec.attributes) 42 { 43 if (attr.attribute == tok!"static") 44 isStatic = true; 45 } 46 dec.accept(this); 47 isStatic = false; 48 } 49 50 override void visit(const ImportDeclaration id) 51 { 52 if ((!isStatic && interesting) && (id.importBindings is null || id.importBindings.importBinds.length == 0)) 53 { 54 addErrorMessage(id.singleImports[0].identifierChain.identifiers[0].line, 55 id.singleImports[0].identifierChain.identifiers[0].column, 56 "dscanner.suspicious.local_imports", "Local imports should specify" 57 ~ " the symbols being imported to avoid hiding local symbols."); 58 } 59 } 60 61 private: 62 63 mixin template visitThing(T) 64 { 65 override void visit(const T thing) 66 { 67 auto b = interesting; 68 interesting = true; 69 thing.accept(this); 70 interesting = b; 71 } 72 } 73 74 bool interesting; 75 bool isStatic; 76 } 77