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