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 }