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