Merge pull request #340 from BBasile/skip-tests
Added an option that alows to skip the unittests analysis
This commit is contained in:
commit
d5929a4226
18
README.md
18
README.md
|
@ -43,6 +43,12 @@ analysis and it does not compile the code.
|
||||||
The "--styleCheck" or "-S" option runs some basic static analysis checks against
|
The "--styleCheck" or "-S" option runs some basic static analysis checks against
|
||||||
the given source files.
|
the given source files.
|
||||||
|
|
||||||
|
#### Skip style checks in the tests
|
||||||
|
Static checks in the unit tests can produce irrelevant warnings. For example,
|
||||||
|
it's legit to declare a variable that's not used if the goal is to verify that
|
||||||
|
a templatized function can be instantiated by inference of the type of this variable.
|
||||||
|
To avoid these cases, it's possible to pass the "--skipTests" option.
|
||||||
|
|
||||||
#### Configuration
|
#### Configuration
|
||||||
By default all checks are enabled. Individual checks can be enabled or disabled
|
By default all checks are enabled. Individual checks can be enabled or disabled
|
||||||
by using a configuration file. Running ```dscanner --defaultConfig``` will
|
by using a configuration file. Running ```dscanner --defaultConfig``` will
|
||||||
|
@ -50,6 +56,16 @@ generate a default configuration file and print the file's location. The
|
||||||
"--config" option will allow you to specify the path to a configuration file if
|
"--config" option will allow you to specify the path to a configuration file if
|
||||||
you do not want to use the one created by the "--defaultConfig" option.
|
you do not want to use the one created by the "--defaultConfig" option.
|
||||||
|
|
||||||
|
For each check, three values are possible:
|
||||||
|
* `"disabled"`: the check is not performed.
|
||||||
|
* `"enabled"`: the check is performed.
|
||||||
|
* `"skip-unittest"`: the check is performed but not in the unit tests.
|
||||||
|
|
||||||
|
Any other value deactivates a check.
|
||||||
|
|
||||||
|
Note that the "--skipTests" option is the equivalent of changing each
|
||||||
|
`"enabled"` check by a `"skip-unittest"` check.
|
||||||
|
|
||||||
#### Implemented checks
|
#### Implemented checks
|
||||||
* Old alias syntax (i.e "alias a b;" should be replaced with "alias b = a;").
|
* Old alias syntax (i.e "alias a b;" should be replaced with "alias b = a;").
|
||||||
* Implicit concatenation of string literals.
|
* Implicit concatenation of string literals.
|
||||||
|
@ -85,7 +101,7 @@ you do not want to use the one created by the "--defaultConfig" option.
|
||||||
* Unused labels.
|
* Unused labels.
|
||||||
* Lines longer than 120 characters.
|
* Lines longer than 120 characters.
|
||||||
* Incorrect infinite range definitions.
|
* Incorrect infinite range definitions.
|
||||||
* Some assertions that check conditions that will always be true.
|
* Some assertions that check conditions that will always be true. This check can't be skipped in the tests.
|
||||||
|
|
||||||
#### Wishlist
|
#### Wishlist
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,9 @@ class AliasSyntaxCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName)
|
this(string fileName, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, null);
|
super(fileName, null, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const AliasDeclaration ad)
|
override void visit(const AliasDeclaration ad)
|
||||||
|
@ -40,11 +40,11 @@ private:
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.helpers : assertAnalyzerWarnings;
|
import analysis.helpers : assertAnalyzerWarnings;
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
import std.stdio : stderr;
|
import std.stdio : stderr;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.alias_syntax_check = true;
|
sac.alias_syntax_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
alias int abcde; // [warn]: Prefer the new "'alias' identifier '=' type ';'" syntax to the old "'alias' type identifier ';'" syntax.
|
alias int abcde; // [warn]: Prefer the new "'alias' identifier '=' type ';'" syntax to the old "'alias' type identifier ';'" syntax.
|
||||||
alias abcde = int;
|
alias abcde = int;
|
||||||
|
|
|
@ -20,9 +20,9 @@ class AsmStyleCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const AsmBrExp brExp)
|
override void visit(const AsmBrExp brExp)
|
||||||
|
@ -39,10 +39,10 @@ class AsmStyleCheck : BaseAnalyzer
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.asm_style_check = true;
|
sac.asm_style_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
void testAsm()
|
void testAsm()
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,9 +15,9 @@ import analysis.base;
|
||||||
class AutoRefAssignmentCheck : BaseAnalyzer
|
class AutoRefAssignmentCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
this(string fileName)
|
this(string fileName, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, null);
|
super(fileName, null, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const Module m)
|
override void visit(const Module m)
|
||||||
|
@ -113,11 +113,11 @@ unittest
|
||||||
{
|
{
|
||||||
import std.stdio : stderr;
|
import std.stdio : stderr;
|
||||||
import std.format : format;
|
import std.format : format;
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
import analysis.helpers : assertAnalyzerWarnings;
|
import analysis.helpers : assertAnalyzerWarnings;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.auto_ref_assignment_check = true;
|
sac.auto_ref_assignment_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
int doStuff(T)(auto ref int a)
|
int doStuff(T)(auto ref int a)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,10 +27,11 @@ alias MessageSet = RedBlackTree!(Message, comparitor, true);
|
||||||
abstract class BaseAnalyzer : ASTVisitor
|
abstract class BaseAnalyzer : ASTVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
this(string fileName, const Scope* sc)
|
this(string fileName, const Scope* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
this.sc = sc;
|
this.sc = sc;
|
||||||
this.fileName = fileName;
|
this.fileName = fileName;
|
||||||
|
this.skipTests = skipTests;
|
||||||
_messages = new MessageSet;
|
_messages = new MessageSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,9 +40,24 @@ public:
|
||||||
return _messages[].array;
|
return _messages[].array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alias visit = ASTVisitor.visit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits a unittest.
|
||||||
|
*
|
||||||
|
* When overriden, the protected bool "skipTests" should be handled
|
||||||
|
* so that the content of the test is not analyzed.
|
||||||
|
*/
|
||||||
|
override void visit(const Unittest unittest_)
|
||||||
|
{
|
||||||
|
if (!skipTests)
|
||||||
|
unittest_.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool inAggregate = false;
|
bool inAggregate = false;
|
||||||
|
bool skipTests;
|
||||||
|
|
||||||
template visitTemplate(T)
|
template visitTemplate(T)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,9 +30,9 @@ class BuiltinPropertyNameCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const FunctionDeclaration fd)
|
override void visit(const FunctionDeclaration fd)
|
||||||
|
@ -101,10 +101,10 @@ private:
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.builtin_property_names_check = true;
|
sac.builtin_property_names_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
class SomeClass
|
class SomeClass
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,9 +17,9 @@ class CommaExpressionCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const Expression ex)
|
override void visit(const Expression ex)
|
||||||
|
|
|
@ -10,113 +10,138 @@ import inifiled;
|
||||||
StaticAnalysisConfig defaultStaticAnalysisConfig()
|
StaticAnalysisConfig defaultStaticAnalysisConfig()
|
||||||
{
|
{
|
||||||
StaticAnalysisConfig config;
|
StaticAnalysisConfig config;
|
||||||
foreach (mem; __traits(allMembers, StaticAnalysisConfig))
|
config.fillConfig!(Check.enabled);
|
||||||
mixin("config." ~ mem ~ " = true;");
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Check: string
|
||||||
|
{
|
||||||
|
disabled = "disabled",
|
||||||
|
enabled = "enabled",
|
||||||
|
skipTests = "skip-unittest"
|
||||||
|
}
|
||||||
|
|
||||||
|
void fillConfig(string check)(ref StaticAnalysisConfig config)
|
||||||
|
{
|
||||||
|
foreach (mem; __traits(allMembers, StaticAnalysisConfig))
|
||||||
|
{
|
||||||
|
static if (is(typeof(__traits(getMember, StaticAnalysisConfig, mem))))
|
||||||
|
static if (is(typeof(__traits(getMember, config, mem)) == string))
|
||||||
|
__traits(getMember, config, mem) = check;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
StaticAnalysisConfig c;
|
||||||
|
c.fillConfig!(Check.enabled);
|
||||||
|
assert(c.enum_array_literal_check == Check.enabled);
|
||||||
|
fillConfig!(Check.skipTests)(c);
|
||||||
|
assert(c.alias_syntax_check == Check.skipTests);
|
||||||
|
}
|
||||||
|
|
||||||
@INI("Configure which static analysis checks are enabled")
|
@INI("Configure which static analysis checks are enabled")
|
||||||
struct StaticAnalysisConfig
|
struct StaticAnalysisConfig
|
||||||
{
|
{
|
||||||
@INI("Check variable, class, struct, interface, union, and function names against the Phobos style guide")
|
@INI("Check variable, class, struct, interface, union, and function names against the Phobos style guide")
|
||||||
bool style_check;
|
string style_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Check for array literals that cause unnecessary allocation")
|
@INI("Check for array literals that cause unnecessary allocation")
|
||||||
bool enum_array_literal_check;
|
string enum_array_literal_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Check for poor exception handling practices")
|
@INI("Check for poor exception handling practices")
|
||||||
bool exception_check;
|
string exception_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Check for use of the deprecated 'delete' keyword")
|
@INI("Check for use of the deprecated 'delete' keyword")
|
||||||
bool delete_check;
|
string delete_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Check for use of the deprecated floating point operators")
|
@INI("Check for use of the deprecated floating point operators")
|
||||||
bool float_operator_check;
|
string float_operator_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Check number literals for readability")
|
@INI("Check number literals for readability")
|
||||||
bool number_style_check;
|
string number_style_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks that opEquals, opCmp, toHash, and toString are either const, immutable, or inout.")
|
@INI("Checks that opEquals, opCmp, toHash, and toString are either const, immutable, or inout.")
|
||||||
bool object_const_check;
|
string object_const_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for .. expressions where the left side is larger than the right.")
|
@INI("Checks for .. expressions where the left side is larger than the right.")
|
||||||
bool backwards_range_check;
|
string backwards_range_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for if statements whose 'then' block is the same as the 'else' block")
|
@INI("Checks for if statements whose 'then' block is the same as the 'else' block")
|
||||||
bool if_else_same_check;
|
string if_else_same_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for some problems with constructors")
|
@INI("Checks for some problems with constructors")
|
||||||
bool constructor_check;
|
string constructor_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for unused variables and function parameters")
|
@INI("Checks for unused variables and function parameters")
|
||||||
bool unused_variable_check;
|
string unused_variable_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for unused labels")
|
@INI("Checks for unused labels")
|
||||||
bool unused_label_check;
|
string unused_label_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for duplicate attributes")
|
@INI("Checks for duplicate attributes")
|
||||||
bool duplicate_attribute;
|
string duplicate_attribute = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks that opEquals and toHash are both defined or neither are defined")
|
@INI("Checks that opEquals and toHash are both defined or neither are defined")
|
||||||
bool opequals_tohash_check;
|
string opequals_tohash_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for subtraction from .length properties")
|
@INI("Checks for subtraction from .length properties")
|
||||||
bool length_subtraction_check;
|
string length_subtraction_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for methods or properties whose names conflict with built-in properties")
|
@INI("Checks for methods or properties whose names conflict with built-in properties")
|
||||||
bool builtin_property_names_check;
|
string builtin_property_names_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for confusing code in inline asm statements")
|
@INI("Checks for confusing code in inline asm statements")
|
||||||
bool asm_style_check;
|
string asm_style_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for confusing logical operator precedence")
|
@INI("Checks for confusing logical operator precedence")
|
||||||
bool logical_precedence_check;
|
string logical_precedence_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for undocumented public declarations")
|
@INI("Checks for undocumented public declarations")
|
||||||
bool undocumented_declaration_check;
|
string undocumented_declaration_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for poor placement of function attributes")
|
@INI("Checks for poor placement of function attributes")
|
||||||
bool function_attribute_check;
|
string function_attribute_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for use of the comma operator")
|
@INI("Checks for use of the comma operator")
|
||||||
bool comma_expression_check;
|
string comma_expression_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for local imports that are too broad")
|
@INI("Checks for local imports that are too broad")
|
||||||
bool local_import_check;
|
string local_import_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for variables that could be declared immutable")
|
@INI("Checks for variables that could be declared immutable")
|
||||||
bool could_be_immutable_check = false; // disabled by default for now
|
string could_be_immutable_check = Check.disabled; // disabled by default for now
|
||||||
|
|
||||||
@INI("Checks for redundant expressions in if statements")
|
@INI("Checks for redundant expressions in if statements")
|
||||||
bool redundant_if_check;
|
string redundant_if_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for redundant parenthesis")
|
@INI("Checks for redundant parenthesis")
|
||||||
bool redundant_parens_check;
|
string redundant_parens_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for mismatched argument and parameter names")
|
@INI("Checks for mismatched argument and parameter names")
|
||||||
bool mismatched_args_check;
|
string mismatched_args_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for labels with the same name as variables")
|
@INI("Checks for labels with the same name as variables")
|
||||||
bool label_var_same_name_check;
|
string label_var_same_name_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for lines longer than 120 characters")
|
@INI("Checks for lines longer than 120 characters")
|
||||||
bool long_line_check;
|
string long_line_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for assignment to auto-ref function parameters")
|
@INI("Checks for assignment to auto-ref function parameters")
|
||||||
bool auto_ref_assignment_check;
|
string auto_ref_assignment_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for incorrect infinite range definitions")
|
@INI("Checks for incorrect infinite range definitions")
|
||||||
bool incorrect_infinite_range_check;
|
string incorrect_infinite_range_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for asserts that are always true")
|
@INI("Checks for asserts that are always true")
|
||||||
bool useless_assert_check;
|
string useless_assert_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Check for uses of the old-style alias syntax")
|
@INI("Check for uses of the old-style alias syntax")
|
||||||
bool alias_syntax_check;
|
string alias_syntax_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Checks for else if that should be else static if")
|
@INI("Checks for else if that should be else static if")
|
||||||
bool static_if_else_check;
|
string static_if_else_check = Check.disabled;
|
||||||
|
|
||||||
@INI("Check for unclear lambda syntax")
|
@INI("Check for unclear lambda syntax")
|
||||||
bool lambda_return_check;
|
string lambda_return_check = Check.disabled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@ class ConstructorCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const ClassDeclaration classDeclaration)
|
override void visit(const ClassDeclaration classDeclaration)
|
||||||
|
@ -90,10 +90,10 @@ private:
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.constructor_check = true;
|
sac.constructor_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
class Cat // [warn]: This class has a zero-argument constructor as well as a constructor with one default argument. This can be confusing.
|
class Cat // [warn]: This class has a zero-argument constructor as well as a constructor with one default argument. This can be confusing.
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,9 +18,9 @@ class DeleteCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const DeleteExpression d)
|
override void visit(const DeleteExpression d)
|
||||||
|
@ -33,11 +33,11 @@ class DeleteCheck : BaseAnalyzer
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
import analysis.helpers : assertAnalyzerWarnings;
|
import analysis.helpers : assertAnalyzerWarnings;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.delete_check = true;
|
sac.delete_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
void testDelete()
|
void testDelete()
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,9 +21,9 @@ class DuplicateAttributeCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const Declaration node)
|
override void visit(const Declaration node)
|
||||||
|
@ -153,10 +153,10 @@ class DuplicateAttributeCheck : BaseAnalyzer
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.duplicate_attribute = true;
|
sac.duplicate_attribute = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
class ExampleAttributes
|
class ExampleAttributes
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,9 +19,9 @@ class EnumArrayLiteralCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool looking = false;
|
bool looking = false;
|
||||||
|
|
|
@ -21,9 +21,9 @@ class FloatOperatorCheck : BaseAnalyzer
|
||||||
|
|
||||||
enum string KEY = "dscanner.deprecated.floating_point_operators";
|
enum string KEY = "dscanner.deprecated.floating_point_operators";
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const RelExpression r)
|
override void visit(const RelExpression r)
|
||||||
|
@ -42,10 +42,10 @@ class FloatOperatorCheck : BaseAnalyzer
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.float_operator_check = true;
|
sac.float_operator_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
void testFish()
|
void testFish()
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,9 +25,9 @@ class FunctionAttributeCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const InterfaceDeclaration dec)
|
override void visit(const InterfaceDeclaration dec)
|
||||||
|
|
|
@ -13,9 +13,9 @@ import dsymbol.scope_ : Scope;
|
||||||
class IfStatementCheck : BaseAnalyzer
|
class IfStatementCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const IfStatement ifStatement)
|
override void visit(const IfStatement ifStatement)
|
||||||
|
|
|
@ -24,9 +24,9 @@ class IfElseSameCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const IfStatement ifStatement)
|
override void visit(const IfStatement ifStatement)
|
||||||
|
@ -77,10 +77,10 @@ class IfElseSameCheck : BaseAnalyzer
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.if_else_same_check = true;
|
sac.if_else_same_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
void testSizeT()
|
void testSizeT()
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,9 +18,9 @@ class IncorrectInfiniteRangeCheck : BaseAnalyzer
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
///
|
///
|
||||||
this(string fileName)
|
this(string fileName, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, null);
|
super(fileName, null, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const StructBody structBody)
|
override void visit(const StructBody structBody)
|
||||||
|
@ -88,11 +88,11 @@ private:
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import std.stdio : stderr;
|
import std.stdio : stderr;
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
import std.format : format;
|
import std.format : format;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.incorrect_infinite_range_check = true;
|
sac.incorrect_infinite_range_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{struct InfiniteRange
|
assertAnalyzerWarnings(q{struct InfiniteRange
|
||||||
{
|
{
|
||||||
bool empty() // [warn]: %1$s
|
bool empty() // [warn]: %1$s
|
||||||
|
|
|
@ -15,9 +15,9 @@ import analysis.helpers;
|
||||||
*/
|
*/
|
||||||
class LabelVarNameCheck : BaseAnalyzer
|
class LabelVarNameCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin ScopedVisit!Module;
|
mixin ScopedVisit!Module;
|
||||||
|
@ -118,11 +118,11 @@ private:
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
import std.stdio : stderr;
|
import std.stdio : stderr;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.label_var_same_name_check = true;
|
sac.label_var_same_name_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,10 +13,10 @@ class LambdaReturnCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName)
|
this(string fileName, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, null);
|
super(fileName, null, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const FunctionLiteralExpression fLit)
|
override void visit(const FunctionLiteralExpression fLit)
|
||||||
{
|
{
|
||||||
|
@ -47,11 +47,11 @@ private:
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.helpers : assertAnalyzerWarnings;
|
import analysis.helpers : assertAnalyzerWarnings;
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
import std.stdio : stderr;
|
import std.stdio : stderr;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.lambda_return_check = true;
|
sac.lambda_return_check = Check.enabled;
|
||||||
|
|
||||||
auto code = `
|
auto code = `
|
||||||
void main()
|
void main()
|
||||||
|
|
|
@ -20,9 +20,9 @@ class LengthSubtractionCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const AddExpression addExpression)
|
override void visit(const AddExpression addExpression)
|
||||||
|
@ -58,10 +58,10 @@ class LengthSubtractionCheck : BaseAnalyzer
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.length_subtraction_check = true;
|
sac.length_subtraction_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
void testSizeT()
|
void testSizeT()
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,9 +15,9 @@ import analysis.base : BaseAnalyzer;
|
||||||
class LineLengthCheck : BaseAnalyzer
|
class LineLengthCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
this(string fileName, const(Token)[] tokens)
|
this(string fileName, const(Token)[] tokens, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, null);
|
super(fileName, null, skipTests);
|
||||||
this.tokens = tokens;
|
this.tokens = tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,9 @@ class LocalImportCheck : BaseAnalyzer
|
||||||
/**
|
/**
|
||||||
* Construct with the given file name.
|
* Construct with the given file name.
|
||||||
*/
|
*/
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin visitThing!StructBody;
|
mixin visitThing!StructBody;
|
||||||
|
@ -84,10 +84,10 @@ private:
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.local_import_check = true;
|
sac.local_import_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
void testLocalImport()
|
void testLocalImport()
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,9 +25,9 @@ class LogicPrecedenceCheck : BaseAnalyzer
|
||||||
|
|
||||||
enum string KEY = "dscanner.confusing.logical_precedence";
|
enum string KEY = "dscanner.confusing.logical_precedence";
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const OrOrExpression orOr)
|
override void visit(const OrOrExpression orOr)
|
||||||
|
@ -48,10 +48,10 @@ class LogicPrecedenceCheck : BaseAnalyzer
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.logical_precedence_check = true;
|
sac.logical_precedence_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
void testFish()
|
void testFish()
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,9 +11,9 @@ import dsymbol.builtin.names;
|
||||||
final class MismatchedArgumentCheck : BaseAnalyzer
|
final class MismatchedArgumentCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
this(string fileName, const Scope* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const FunctionCallExpression fce)
|
override void visit(const FunctionCallExpression fce)
|
||||||
|
|
|
@ -24,9 +24,9 @@ public:
|
||||||
/**
|
/**
|
||||||
* Constructs the style checker with the given file name.
|
* Constructs the style checker with the given file name.
|
||||||
*/
|
*/
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const Token t)
|
override void visit(const Token t)
|
||||||
|
@ -49,10 +49,10 @@ private:
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.number_style_check = true;
|
sac.number_style_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
void testNumbers()
|
void testNumbers()
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,9 +21,9 @@ class ObjectConstCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin visitTemplate!ClassDeclaration;
|
mixin visitTemplate!ClassDeclaration;
|
||||||
|
@ -71,10 +71,10 @@ class ObjectConstCheck : BaseAnalyzer
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.object_const_check = true;
|
sac.object_const_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
void testConsts()
|
void testConsts()
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,9 +20,9 @@ class OpEqualsWithoutToHashCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const ClassDeclaration node)
|
override void visit(const ClassDeclaration node)
|
||||||
|
@ -89,10 +89,10 @@ class OpEqualsWithoutToHashCheck : BaseAnalyzer
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.opequals_tohash_check = true;
|
sac.opequals_tohash_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
// Success because it has opEquals and toHash
|
// Success because it has opEquals and toHash
|
||||||
class Chimp
|
class Chimp
|
||||||
|
|
|
@ -30,9 +30,9 @@ class PokemonExceptionCheck : BaseAnalyzer
|
||||||
|
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const LastCatch lc)
|
override void visit(const LastCatch lc)
|
||||||
|
@ -85,10 +85,10 @@ class PokemonExceptionCheck : BaseAnalyzer
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.exception_check = true;
|
sac.exception_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
void testCatch()
|
void testCatch()
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,9 +27,9 @@ class BackwardsRangeCheck : BaseAnalyzer
|
||||||
* Params:
|
* Params:
|
||||||
* fileName = the name of the file being analyzed
|
* fileName = the name of the file being analyzed
|
||||||
*/
|
*/
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const Scope* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const ForeachStatement foreachStatement)
|
override void visit(const ForeachStatement foreachStatement)
|
||||||
|
@ -157,10 +157,10 @@ private:
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.backwards_range_check = true;
|
sac.backwards_range_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
void testRange()
|
void testRange()
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,9 +18,9 @@ class RedundantParenCheck : BaseAnalyzer
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
///
|
///
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const IfStatement statement)
|
override void visit(const IfStatement statement)
|
||||||
|
|
|
@ -205,8 +205,10 @@ MessageSet analyze(string fileName, const Module m, const StaticAnalysisConfig a
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
auto symbolAllocator = scoped!ASTAllocator();
|
auto symbolAllocator = scoped!ASTAllocator();
|
||||||
|
version (unittest) enum ut = true; else enum ut = false;
|
||||||
|
|
||||||
auto first = scoped!FirstPass(m, internString(fileName), symbolAllocator,
|
auto first = scoped!FirstPass(m, internString(fileName), symbolAllocator,
|
||||||
symbolAllocator, true, &moduleCache, null);
|
symbolAllocator, true, &moduleCache, null);
|
||||||
first.run();
|
first.run();
|
||||||
|
|
||||||
secondPass(first.rootSymbol, first.moduleScope, moduleCache);
|
secondPass(first.rootSymbol, first.moduleScope, moduleCache);
|
||||||
|
@ -216,75 +218,142 @@ MessageSet analyze(string fileName, const Module m, const StaticAnalysisConfig a
|
||||||
scope(exit) typeid(Scope).destroy(first.moduleScope);
|
scope(exit) typeid(Scope).destroy(first.moduleScope);
|
||||||
BaseAnalyzer[] checks;
|
BaseAnalyzer[] checks;
|
||||||
|
|
||||||
if (analysisConfig.asm_style_check)
|
if (analysisConfig.asm_style_check != Check.disabled)
|
||||||
checks ~= new AsmStyleCheck(fileName, moduleScope);
|
checks ~= new AsmStyleCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.backwards_range_check)
|
analysisConfig.asm_style_check == Check.skipTests && !ut);
|
||||||
checks ~= new BackwardsRangeCheck(fileName, moduleScope);
|
|
||||||
if (analysisConfig.builtin_property_names_check)
|
if (analysisConfig.backwards_range_check != Check.disabled)
|
||||||
checks ~= new BuiltinPropertyNameCheck(fileName, moduleScope);
|
checks ~= new BackwardsRangeCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.comma_expression_check)
|
analysisConfig.backwards_range_check == Check.skipTests && !ut);
|
||||||
checks ~= new CommaExpressionCheck(fileName, moduleScope);
|
|
||||||
if (analysisConfig.constructor_check)
|
if (analysisConfig.builtin_property_names_check != Check.disabled)
|
||||||
checks ~= new ConstructorCheck(fileName, moduleScope);
|
checks ~= new BuiltinPropertyNameCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.could_be_immutable_check)
|
analysisConfig.builtin_property_names_check == Check.skipTests && !ut);
|
||||||
checks ~= new UnmodifiedFinder(fileName, moduleScope);
|
|
||||||
if (analysisConfig.delete_check)
|
if (analysisConfig.comma_expression_check != Check.disabled)
|
||||||
checks ~= new DeleteCheck(fileName, moduleScope);
|
checks ~= new CommaExpressionCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.duplicate_attribute)
|
analysisConfig.comma_expression_check == Check.skipTests && !ut);
|
||||||
checks ~= new DuplicateAttributeCheck(fileName, moduleScope);
|
|
||||||
if (analysisConfig.enum_array_literal_check)
|
if (analysisConfig.constructor_check != Check.disabled)
|
||||||
checks ~= new EnumArrayLiteralCheck(fileName, moduleScope);
|
checks ~= new ConstructorCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.exception_check)
|
analysisConfig.constructor_check == Check.skipTests && !ut);
|
||||||
checks ~= new PokemonExceptionCheck(fileName, moduleScope);
|
|
||||||
if (analysisConfig.float_operator_check)
|
if (analysisConfig.could_be_immutable_check != Check.disabled)
|
||||||
checks ~= new FloatOperatorCheck(fileName, moduleScope);
|
checks ~= new UnmodifiedFinder(fileName, moduleScope,
|
||||||
if (analysisConfig.function_attribute_check)
|
analysisConfig.could_be_immutable_check == Check.skipTests && !ut);
|
||||||
checks ~= new FunctionAttributeCheck(fileName, moduleScope);
|
|
||||||
if (analysisConfig.if_else_same_check)
|
if (analysisConfig.delete_check != Check.disabled)
|
||||||
checks ~= new IfElseSameCheck(fileName, moduleScope);
|
checks ~= new DeleteCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.label_var_same_name_check)
|
analysisConfig.delete_check == Check.skipTests && !ut);
|
||||||
checks ~= new LabelVarNameCheck(fileName, moduleScope);
|
|
||||||
if (analysisConfig.length_subtraction_check)
|
if (analysisConfig.duplicate_attribute != Check.disabled)
|
||||||
checks ~= new LengthSubtractionCheck(fileName, moduleScope);
|
checks ~= new DuplicateAttributeCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.local_import_check)
|
analysisConfig.duplicate_attribute == Check.skipTests && !ut);
|
||||||
checks ~= new LocalImportCheck(fileName, moduleScope);
|
|
||||||
if (analysisConfig.logical_precedence_check)
|
if (analysisConfig.enum_array_literal_check != Check.disabled)
|
||||||
checks ~= new LogicPrecedenceCheck(fileName, moduleScope);
|
checks ~= new EnumArrayLiteralCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.mismatched_args_check)
|
analysisConfig.enum_array_literal_check == Check.skipTests && !ut);
|
||||||
checks ~= new MismatchedArgumentCheck(fileName, moduleScope);
|
|
||||||
if (analysisConfig.number_style_check)
|
if (analysisConfig.exception_check != Check.disabled)
|
||||||
checks ~= new NumberStyleCheck(fileName, moduleScope);
|
checks ~= new PokemonExceptionCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.object_const_check)
|
analysisConfig.exception_check == Check.skipTests && !ut);
|
||||||
checks ~= new ObjectConstCheck(fileName, moduleScope);
|
|
||||||
if (analysisConfig.opequals_tohash_check)
|
if (analysisConfig.float_operator_check != Check.disabled)
|
||||||
checks ~= new OpEqualsWithoutToHashCheck(fileName, moduleScope);
|
checks ~= new FloatOperatorCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.redundant_parens_check)
|
analysisConfig.float_operator_check == Check.skipTests && !ut);
|
||||||
checks ~= new RedundantParenCheck(fileName, moduleScope);
|
|
||||||
if (analysisConfig.style_check)
|
if (analysisConfig.function_attribute_check != Check.disabled)
|
||||||
checks ~= new StyleChecker(fileName, moduleScope);
|
checks ~= new FunctionAttributeCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.undocumented_declaration_check)
|
analysisConfig.function_attribute_check == Check.skipTests && !ut);
|
||||||
checks ~= new UndocumentedDeclarationCheck(fileName, moduleScope);
|
|
||||||
if (analysisConfig.unused_label_check)
|
if (analysisConfig.if_else_same_check != Check.disabled)
|
||||||
checks ~= new UnusedLabelCheck(fileName, moduleScope);
|
checks ~= new IfElseSameCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.unused_variable_check)
|
analysisConfig.if_else_same_check == Check.skipTests&& !ut);
|
||||||
checks ~= new UnusedVariableCheck(fileName, moduleScope);
|
|
||||||
if (analysisConfig.long_line_check)
|
if (analysisConfig.label_var_same_name_check != Check.disabled)
|
||||||
checks ~= new LineLengthCheck(fileName, tokens);
|
checks ~= new LabelVarNameCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.auto_ref_assignment_check)
|
analysisConfig.label_var_same_name_check == Check.skipTests && !ut);
|
||||||
checks ~= new AutoRefAssignmentCheck(fileName);
|
|
||||||
if (analysisConfig.incorrect_infinite_range_check)
|
if (analysisConfig.length_subtraction_check != Check.disabled)
|
||||||
checks ~= new IncorrectInfiniteRangeCheck(fileName);
|
checks ~= new LengthSubtractionCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.useless_assert_check)
|
analysisConfig.length_subtraction_check == Check.skipTests && !ut);
|
||||||
checks ~= new UselessAssertCheck(fileName);
|
|
||||||
if (analysisConfig.alias_syntax_check)
|
if (analysisConfig.local_import_check != Check.disabled)
|
||||||
checks ~= new AliasSyntaxCheck(fileName);
|
checks ~= new LocalImportCheck(fileName, moduleScope,
|
||||||
if (analysisConfig.static_if_else_check)
|
analysisConfig.local_import_check == Check.skipTests && !ut);
|
||||||
checks ~= new StaticIfElse(fileName);
|
|
||||||
if (analysisConfig.lambda_return_check)
|
if (analysisConfig.logical_precedence_check != Check.disabled)
|
||||||
checks ~= new LambdaReturnCheck(fileName);
|
checks ~= new LogicPrecedenceCheck(fileName, moduleScope,
|
||||||
|
analysisConfig.logical_precedence_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.mismatched_args_check != Check.disabled)
|
||||||
|
checks ~= new MismatchedArgumentCheck(fileName, moduleScope,
|
||||||
|
analysisConfig.mismatched_args_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.number_style_check != Check.disabled)
|
||||||
|
checks ~= new NumberStyleCheck(fileName, moduleScope,
|
||||||
|
analysisConfig.number_style_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.object_const_check != Check.disabled)
|
||||||
|
checks ~= new ObjectConstCheck(fileName, moduleScope,
|
||||||
|
analysisConfig.object_const_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.opequals_tohash_check != Check.disabled)
|
||||||
|
checks ~= new OpEqualsWithoutToHashCheck(fileName, moduleScope,
|
||||||
|
analysisConfig.opequals_tohash_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.redundant_parens_check != Check.disabled)
|
||||||
|
checks ~= new RedundantParenCheck(fileName, moduleScope,
|
||||||
|
analysisConfig.redundant_parens_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.style_check != Check.disabled)
|
||||||
|
checks ~= new StyleChecker(fileName, moduleScope,
|
||||||
|
analysisConfig.style_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.undocumented_declaration_check != Check.disabled)
|
||||||
|
checks ~= new UndocumentedDeclarationCheck(fileName, moduleScope,
|
||||||
|
analysisConfig.undocumented_declaration_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.unused_label_check != Check.disabled)
|
||||||
|
checks ~= new UnusedLabelCheck(fileName, moduleScope,
|
||||||
|
analysisConfig.unused_label_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.unused_variable_check != Check.disabled)
|
||||||
|
checks ~= new UnusedVariableCheck(fileName, moduleScope,
|
||||||
|
analysisConfig.unused_variable_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.long_line_check != Check.disabled)
|
||||||
|
checks ~= new LineLengthCheck(fileName, tokens,
|
||||||
|
analysisConfig.long_line_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.auto_ref_assignment_check != Check.disabled)
|
||||||
|
checks ~= new AutoRefAssignmentCheck(fileName,
|
||||||
|
analysisConfig.auto_ref_assignment_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.incorrect_infinite_range_check != Check.disabled)
|
||||||
|
checks ~= new IncorrectInfiniteRangeCheck(fileName,
|
||||||
|
analysisConfig.incorrect_infinite_range_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.useless_assert_check != Check.disabled)
|
||||||
|
checks ~= new UselessAssertCheck(fileName,
|
||||||
|
analysisConfig.useless_assert_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.alias_syntax_check != Check.disabled)
|
||||||
|
checks ~= new AliasSyntaxCheck(fileName,
|
||||||
|
analysisConfig.alias_syntax_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.static_if_else_check != Check.disabled)
|
||||||
|
checks ~= new StaticIfElse(fileName,
|
||||||
|
analysisConfig.static_if_else_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
|
if (analysisConfig.lambda_return_check != Check.disabled)
|
||||||
|
checks ~= new LambdaReturnCheck(fileName,
|
||||||
|
analysisConfig.lambda_return_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
version (none)
|
version (none)
|
||||||
if (analysisConfig.redundant_if_check)
|
if (analysisConfig.redundant_if_check != Check.disabled)
|
||||||
checks ~= new IfStatementCheck(fileName, moduleScope);
|
checks ~= new IfStatementCheck(fileName, moduleScope,
|
||||||
|
analysisConfig.redundant_if_check == Check.skipTests && !ut);
|
||||||
|
|
||||||
foreach (check; checks)
|
foreach (check; checks)
|
||||||
{
|
{
|
||||||
|
@ -297,3 +366,4 @@ MessageSet analyze(string fileName, const Module m, const StaticAnalysisConfig a
|
||||||
set.insert(message);
|
set.insert(message);
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,9 @@ class StaticIfElse : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string filename)
|
this(string fileName, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(filename, null);
|
super(fileName, null, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const ConditionalStatement cc)
|
override void visit(const ConditionalStatement cc)
|
||||||
|
@ -66,11 +66,11 @@ class StaticIfElse : BaseAnalyzer
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.helpers : assertAnalyzerWarnings;
|
import analysis.helpers : assertAnalyzerWarnings;
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
import std.stdio : stderr;
|
import std.stdio : stderr;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.static_if_else_check = true;
|
sac.static_if_else_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
void foo() {
|
void foo() {
|
||||||
static if (false)
|
static if (false)
|
||||||
|
|
|
@ -25,9 +25,9 @@ class StyleChecker : BaseAnalyzer
|
||||||
enum string moduleNameRegex = `^[\p{Ll}_\d]+$`;
|
enum string moduleNameRegex = `^[\p{Ll}_\d]+$`;
|
||||||
enum string KEY = "dscanner.style.phobos_naming_convention";
|
enum string KEY = "dscanner.style.phobos_naming_convention";
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const ModuleDeclaration dec)
|
override void visit(const ModuleDeclaration dec)
|
||||||
|
@ -93,10 +93,10 @@ class StyleChecker : BaseAnalyzer
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.style_check = true;
|
sac.style_check = Check.enabled;
|
||||||
|
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
module AMODULE; // [warn]: Module/package name 'AMODULE' does not match style guidelines.
|
module AMODULE; // [warn]: Module/package name 'AMODULE' does not match style guidelines.
|
||||||
|
|
|
@ -21,9 +21,9 @@ class UndocumentedDeclarationCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const Module mod)
|
override void visit(const Module mod)
|
||||||
|
|
|
@ -18,9 +18,9 @@ class UnmodifiedFinder : BaseAnalyzer
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
///
|
///
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const Module mod)
|
override void visit(const Module mod)
|
||||||
|
|
|
@ -22,9 +22,9 @@ class UnusedVariableCheck : BaseAnalyzer
|
||||||
* Params:
|
* Params:
|
||||||
* fileName = the name of the file being analyzed
|
* fileName = the name of the file being analyzed
|
||||||
*/
|
*/
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
re = regex("[\\p{Alphabetic}_][\\w_]*");
|
re = regex("[\\p{Alphabetic}_][\\w_]*");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,11 +410,11 @@ private:
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import std.stdio : stderr;
|
import std.stdio : stderr;
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
import analysis.helpers : assertAnalyzerWarnings;
|
import analysis.helpers : assertAnalyzerWarnings;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.unused_variable_check = true;
|
sac.unused_variable_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
|
|
||||||
// Issue 274
|
// Issue 274
|
||||||
|
|
|
@ -14,9 +14,9 @@ class UnusedLabelCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
this(string fileName, const(Scope)* sc)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc);
|
super(fileName, sc, skipTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const Module mod)
|
override void visit(const Module mod)
|
||||||
|
@ -137,11 +137,11 @@ private:
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
import std.stdio : stderr;
|
import std.stdio : stderr;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.unused_label_check = true;
|
sac.unused_label_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
int testUnusedLabel()
|
int testUnusedLabel()
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,11 +19,12 @@ class UselessAssertCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
///
|
///
|
||||||
this(string fileName)
|
this(string fileName, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, null);
|
// assertions likely to be in unittest so never skip
|
||||||
}
|
super(fileName, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
override void visit(const AssertExpression ae)
|
override void visit(const AssertExpression ae)
|
||||||
{
|
{
|
||||||
|
@ -96,11 +97,11 @@ private:
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import std.stdio : stderr;
|
import std.stdio : stderr;
|
||||||
import analysis.config : StaticAnalysisConfig;
|
import analysis.config : StaticAnalysisConfig, Check;
|
||||||
import std.format : format;
|
import std.format : format;
|
||||||
|
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.useless_assert_check = true;
|
sac.useless_assert_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
|
|
16
src/main.d
16
src/main.d
|
@ -59,6 +59,7 @@ else
|
||||||
bool styleCheck;
|
bool styleCheck;
|
||||||
bool defaultConfig;
|
bool defaultConfig;
|
||||||
bool report;
|
bool report;
|
||||||
|
bool skipTests;
|
||||||
string symbolName;
|
string symbolName;
|
||||||
string configLocation;
|
string configLocation;
|
||||||
string[] importPaths;
|
string[] importPaths;
|
||||||
|
@ -89,7 +90,8 @@ else
|
||||||
"I", &importPaths,
|
"I", &importPaths,
|
||||||
"version", &printVersion,
|
"version", &printVersion,
|
||||||
"muffinButton", &muffin,
|
"muffinButton", &muffin,
|
||||||
"explore", &explore);
|
"explore", &explore,
|
||||||
|
"skipTests", &skipTests);
|
||||||
//dfmt on
|
//dfmt on
|
||||||
}
|
}
|
||||||
catch (ConvException e)
|
catch (ConvException e)
|
||||||
|
@ -218,6 +220,8 @@ else
|
||||||
string s = configLocation is null ? getConfigurationLocation() : configLocation;
|
string s = configLocation is null ? getConfigurationLocation() : configLocation;
|
||||||
if (s.exists())
|
if (s.exists())
|
||||||
readINIFile(config, s);
|
readINIFile(config, s);
|
||||||
|
if (skipTests)
|
||||||
|
config.fillConfig!(Check.skipTests);
|
||||||
if (report)
|
if (report)
|
||||||
generateReport(expandArgs(args), config, cache, moduleCache);
|
generateReport(expandArgs(args), config, cache, moduleCache);
|
||||||
else
|
else
|
||||||
|
@ -368,7 +372,7 @@ Options:
|
||||||
If no files are specified, input is read from stdin. %1$s will exit with
|
If no files are specified, input is read from stdin. %1$s will exit with
|
||||||
a status code of zero if no errors are found, 1 otherwise.
|
a status code of zero if no errors are found, 1 otherwise.
|
||||||
|
|
||||||
--styleCheck <file | directory>..., <file | directory>...
|
--styleCheck|S <file | directory>..., <file | directory>...
|
||||||
Lexes and parses sourceFiles, printing the line and column number of any
|
Lexes and parses sourceFiles, printing the line and column number of any
|
||||||
static analysis check failures stdout. %1$s will exit with a status code
|
static analysis check failures stdout. %1$s will exit with a status code
|
||||||
of zero if no warnings or errors are found, 1 otherwise.
|
of zero if no warnings or errors are found, 1 otherwise.
|
||||||
|
@ -406,8 +410,12 @@ Options:
|
||||||
$HOME/.config/dscanner/dscanner.ini
|
$HOME/.config/dscanner/dscanner.ini
|
||||||
|
|
||||||
--defaultConfig
|
--defaultConfig
|
||||||
Generates a default configuration file for the static analysis checks`,
|
Generates a default configuration file for the static analysis checks,
|
||||||
programName);
|
|
||||||
|
--skipTests
|
||||||
|
Does not analyze in the unittests. Only works if --styleCheck.`,
|
||||||
|
|
||||||
|
programName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doNothing(string, size_t, size_t, string, bool)
|
private void doNothing(string, size_t, size_t, string, bool)
|
||||||
|
|
Loading…
Reference in New Issue