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