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 dscanner.analysis.config; 7 8 import inifiled; 9 10 /// Returns: A default configuration. 11 StaticAnalysisConfig defaultStaticAnalysisConfig() 12 { 13 StaticAnalysisConfig config; 14 return config; 15 } 16 17 /// Describes how a check is operated. 18 enum Check: string 19 { 20 /// Check is disabled. 21 disabled = "disabled", 22 /// Check is enabled. 23 enabled = "enabled", 24 /// Check is enabled but not operated in the unittests. 25 skipTests = "skip-unittest" 26 } 27 28 /// Applies the --skipTests switch, allowing to call Dscanner without config 29 /// and less noise related to the unittests. 30 void enabled2SkipTests(ref StaticAnalysisConfig config) 31 { 32 foreach (mem; __traits(allMembers, StaticAnalysisConfig)) 33 { 34 static if (is(typeof(__traits(getMember, StaticAnalysisConfig, mem)))) 35 static if (is(typeof(__traits(getMember, config, mem)) == string)) 36 { 37 if (__traits(getMember, config, mem) == Check.enabled) 38 __traits(getMember, config, mem) = Check.skipTests; 39 } 40 } 41 } 42 43 /// Returns a config with all the checks disabled. 44 StaticAnalysisConfig disabledConfig() 45 { 46 StaticAnalysisConfig config; 47 foreach (mem; __traits(allMembers, StaticAnalysisConfig)) 48 { 49 static if (is(typeof(__traits(getMember, StaticAnalysisConfig, mem)))) 50 static if (is(typeof(__traits(getMember, config, mem)) == string)) 51 __traits(getMember, config, mem) = Check.disabled; 52 } 53 return config; 54 } 55 56 @INI("Configure which static analysis checks are enabled", "analysis.config.StaticAnalysisConfig") 57 struct StaticAnalysisConfig 58 { 59 @INI("Check variable, class, struct, interface, union, and function names against the Phobos style guide") 60 string style_check = Check.enabled; 61 62 @INI("Check for array literals that cause unnecessary allocation") 63 string enum_array_literal_check = Check.enabled; 64 65 @INI("Check for poor exception handling practices") 66 string exception_check = Check.enabled; 67 68 @INI("Check for use of the deprecated 'delete' keyword") 69 string delete_check = Check.enabled; 70 71 @INI("Check for use of the deprecated floating point operators") 72 string float_operator_check = Check.enabled; 73 74 @INI("Check number literals for readability") 75 string number_style_check = Check.enabled; 76 77 @INI("Checks that opEquals, opCmp, toHash, and toString are either const, immutable, or inout.") 78 string object_const_check = Check.enabled; 79 80 @INI("Checks for .. expressions where the left side is larger than the right.") 81 string backwards_range_check = Check.enabled; 82 83 @INI("Checks for if statements whose 'then' block is the same as the 'else' block") 84 string if_else_same_check = Check.enabled; 85 86 @INI("Checks for some problems with constructors") 87 string constructor_check = Check.enabled; 88 89 @INI("Checks for unused variables and function parameters") 90 string unused_variable_check = Check.enabled; 91 92 @INI("Checks for unused labels") 93 string unused_label_check = Check.enabled; 94 95 @INI("Checks for duplicate attributes") 96 string duplicate_attribute = Check.enabled; 97 98 @INI("Checks that opEquals and toHash are both defined or neither are defined") 99 string opequals_tohash_check = Check.enabled; 100 101 @INI("Checks for subtraction from .length properties") 102 string length_subtraction_check = Check.enabled; 103 104 @INI("Checks for methods or properties whose names conflict with built-in properties") 105 string builtin_property_names_check = Check.enabled; 106 107 @INI("Checks for confusing code in inline asm statements") 108 string asm_style_check = Check.enabled; 109 110 @INI("Checks for confusing logical operator precedence") 111 string logical_precedence_check = Check.enabled; 112 113 @INI("Checks for undocumented public declarations") 114 string undocumented_declaration_check = Check.enabled; 115 116 @INI("Checks for poor placement of function attributes") 117 string function_attribute_check = Check.enabled; 118 119 @INI("Checks for use of the comma operator") 120 string comma_expression_check = Check.enabled; 121 122 @INI("Checks for local imports that are too broad") 123 string local_import_check = Check.enabled; 124 125 @INI("Checks for variables that could be declared immutable") 126 string could_be_immutable_check = Check.enabled; 127 128 @INI("Checks for redundant expressions in if statements") 129 string redundant_if_check = Check.enabled; 130 131 @INI("Checks for redundant parenthesis") 132 string redundant_parens_check = Check.enabled; 133 134 @INI("Checks for mismatched argument and parameter names") 135 string mismatched_args_check = Check.enabled; 136 137 @INI("Checks for labels with the same name as variables") 138 string label_var_same_name_check = Check.enabled; 139 140 @INI("Checks for lines longer than 120 characters") 141 string long_line_check = Check.enabled; 142 143 @INI("Checks for assignment to auto-ref function parameters") 144 string auto_ref_assignment_check = Check.enabled; 145 146 @INI("Checks for incorrect infinite range definitions") 147 string incorrect_infinite_range_check = Check.enabled; 148 149 @INI("Checks for asserts that are always true") 150 string useless_assert_check = Check.enabled; 151 152 @INI("Check for uses of the old-style alias syntax") 153 string alias_syntax_check = Check.enabled; 154 155 @INI("Checks for else if that should be else static if") 156 string static_if_else_check = Check.enabled; 157 158 @INI("Check for unclear lambda syntax") 159 string lambda_return_check = Check.enabled; 160 161 @INI("Check for auto function without return statement") 162 string auto_function_check = Check.enabled; 163 164 @INI("Check for sortedness of imports") 165 string imports_sortedness = Check.disabled; 166 167 @INI("Check for explicitly annotated unittests") 168 string explicitly_annotated_unittests = Check.disabled; 169 170 @INI("Check for properly documented public functions (Returns, Params)") 171 string properly_documented_public_functions = Check.disabled; 172 173 @INI("Check for useless usage of the final attribute") 174 string final_attribute_check = Check.enabled; 175 176 @INI("Check for virtual calls in the class constructors") 177 string vcall_in_ctor = Check.enabled; 178 179 @INI("Check for useless user defined initializers") 180 string useless_initializer = Check.enabled; 181 182 @INI("Check allman brace style") 183 string allman_braces_check = Check.disabled; 184 185 @INI("Check for redundant attributes") 186 string redundant_attributes_check = Check.enabled; 187 188 @INI("Check public declarations without a documented unittest") 189 string has_public_example = Check.disabled; 190 191 @INI("Check for asserts without an explanatory message") 192 string assert_without_msg = Check.disabled; 193 194 @INI("Check indent of if constraints") 195 string if_constraints_indent = Check.disabled; 196 197 @INI("Check for @trusted applied to a bigger scope than a single function") 198 string trust_too_much = Check.enabled; 199 200 @INI("Check for redundant storage classes on variable declarations") 201 string redundant_storage_classes = Check.enabled; 202 203 @INI("Module-specific filters") 204 ModuleFilters filters; 205 } 206 207 private template ModuleFiltersMixin(A) 208 { 209 const string ModuleFiltersMixin = () { 210 string s; 211 foreach (mem; __traits(allMembers, StaticAnalysisConfig)) 212 static if (is(typeof(__traits(getMember, StaticAnalysisConfig, mem)) == string)) 213 s ~= `@INI("Exclude/Import modules") string[] ` ~ mem ~ ";\n"; 214 215 return s; 216 }(); 217 } 218 219 @INI("ModuleFilters for selectively enabling (+std) and disabling (-std.internal) individual checks", "analysis.config.ModuleFilters") 220 struct ModuleFilters 221 { 222 mixin(ModuleFiltersMixin!int); 223 }