1 //          Copyright Brian Schott (Hackerpilot) 2014-2015.
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 module dscanner.analysis.unused_variable;
6 
7 import dparse.ast;
8 import dscanner.analysis.base;
9 import dscanner.analysis.unused;
10 import dsymbol.scope_ : Scope;
11 import std.algorithm.iteration : map;
12 
13 /**
14  * Checks for unused variables.
15  */
16 final class UnusedVariableCheck : UnusedStorageCheck
17 {
18 	alias visit = UnusedStorageCheck.visit;
19 
20 	mixin AnalyzerInfo!"unused_variable_check";
21 
22 	/**
23 	 * Params:
24 	 *     fileName = the name of the file being analyzed
25 	 */
26 	this(string fileName, const(Scope)* sc, bool skipTests = false)
27 	{
28 		super(fileName, sc, skipTests, "Variable", "unused_variable");
29 	}
30 
31 	override void visit(const VariableDeclaration variableDeclaration)
32 	{
33 		foreach (d; variableDeclaration.declarators)
34 			this.variableDeclared(d.name.text, d.name.line, d.name.column, false);
35 		variableDeclaration.accept(this);
36 	}
37 
38 	override void visit(const AutoDeclaration autoDeclaration)
39 	{
40 		foreach (t; autoDeclaration.parts.map!(a => a.identifier))
41 			this.variableDeclared(t.text, t.line, t.column, false);
42 		autoDeclaration.accept(this);
43 	}
44 }
45 
46 @system unittest
47 {
48 	import std.stdio : stderr;
49 	import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig;
50 	import dscanner.analysis.helpers : assertAnalyzerWarnings;
51 
52 	StaticAnalysisConfig sac = disabledConfig();
53 	sac.unused_variable_check = Check.enabled;
54 	assertAnalyzerWarnings(q{
55 
56 	// Issue 274
57 	unittest
58 	{
59 		size_t byteIndex = 0;
60 		*(cast(FieldType*)(retVal.ptr + byteIndex)) = item;
61 	}
62 
63 	unittest
64 	{
65 		int a; // [warn]: Variable a is never used.
66 	}
67 
68 	// Issue 380
69 	int templatedEnum()
70 	{
71 		enum a(T) = T.init;
72 		return a!int;
73 	}
74 
75 	// Issue 380
76 	int otherTemplatedEnum()
77 	{
78 		auto a(T) = T.init; // [warn]: Variable a is never used.
79 		return 0;
80 	}
81 
82 	// Issue 364
83 	void test364_1()
84 	{
85 		enum s = 8;
86 		immutable t = 2;
87 		int[s][t] a;
88 		a[0][0] = 1;
89 	}
90 
91 	void test364_2()
92 	{
93 		enum s = 8;
94 		alias a = e!s;
95 		a = 1;
96 	}
97 
98 	void oops ()
99 	{
100 		class Identity { int val; }
101 		Identity v;
102 		v.val = 0;
103 	}
104 
105 	void main()
106 	{
107 		const int testValue;
108 		testValue.writeln;
109 	}
110 
111 	// Issue 788
112 	void traits()
113 	{
114 		enum fieldName = "abc";
115 		__traits(hasMember, S, fieldName);
116 
117 		__traits(compiles, { int i = 2; });
118 	}
119 
120 	}}, sac);
121 	stderr.writeln("Unittest for UnusedVariableCheck passed.");
122 }