1 // Copyright Chris Wright (dhasenan) 2016. 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 dscanner.analysis.static_if_else; 7 8 import dparse.ast; 9 import dparse.lexer; 10 import dscanner.analysis.base; 11 import dscanner.utils : safeAccess; 12 13 /** 14 * Checks for potentially mistaken static if / else if. 15 * 16 * It's potentially valid to write: 17 * --- 18 * static if (foo) { 19 * } else if (bar) { 20 * } 21 * --- 22 * 23 * However, it's more likely that this is a mistake. 24 */ 25 class StaticIfElse : BaseAnalyzer 26 { 27 alias visit = BaseAnalyzer.visit; 28 29 this(string fileName, bool skipTests = false) 30 { 31 super(fileName, null, skipTests); 32 } 33 34 override void visit(const ConditionalStatement cc) 35 { 36 cc.accept(this); 37 if (cc.falseStatement is null) 38 { 39 return; 40 } 41 const(IfStatement) ifStmt = getIfStatement(cc); 42 if (!ifStmt) 43 { 44 return; 45 } 46 addErrorMessage(ifStmt.line, ifStmt.column, KEY, "Mismatched static if. Use 'else static if' here."); 47 } 48 49 const(IfStatement) getIfStatement(const ConditionalStatement cc) 50 { 51 return safeAccess(cc).falseStatement.statement.statementNoCaseNoDefault.ifStatement; 52 } 53 54 enum KEY = "dscanner.suspicious.static_if_else"; 55 } 56 57 unittest 58 { 59 import dscanner.analysis.helpers : assertAnalyzerWarnings; 60 import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig; 61 import std.stdio : stderr; 62 63 StaticAnalysisConfig sac = disabledConfig(); 64 sac.static_if_else_check = Check.enabled; 65 assertAnalyzerWarnings(q{ 66 void foo() { 67 static if (false) 68 auto a = 0; 69 else if (true) // [warn]: Mismatched static if. Use 'else static if' here. 70 auto b = 1; 71 } 72 }c, sac); 73 // Explicit braces, so no warning. 74 assertAnalyzerWarnings(q{ 75 void foo() { 76 static if (false) 77 auto a = 0; 78 else { 79 if (true) 80 auto b = 1; 81 } 82 } 83 }c, sac); 84 85 stderr.writeln("Unittest for StaticIfElse passed."); 86 }