diff --git a/README.md b/README.md index 8c63c04..060be12 100644 --- a/README.md +++ b/README.md @@ -30,13 +30,13 @@ source file. std.stdio ### Syntax Check -The "--syntaxCheck" option prints a listing of any errors or warnings found +The "--syntaxCheck" or "-s" option prints a listing of any errors or warnings found while lexing or parsing the given source file. It does not do any semantic analysis and it does not compile the code. ### Style Check -The "--styleCheck" option runs some basic static analysis checks against the -given source files. +The "--styleCheck" or "-S" option runs some basic static analysis checks against +the given source files. #### Implemented checks * Old alias syntax (i.e "alias a b;" should be replaced with "alias b = a;"). @@ -55,6 +55,7 @@ given source files. * Struct constructors that have a single parameter that has a default argument. * Assign expressions where the left side of the '=' operator is the same as the right * 'if' statements where the 'else' block is the same as the 'if' block. +* ||, &&, and == expressions where the left and right sides of the operator are identical * Unused variables. * Unused parameters (check is skipped if function is marked "override") * Duplicate attributes diff --git a/analysis/ifelsesame.d b/analysis/ifelsesame.d index 0550345..8f8dd4d 100644 --- a/analysis/ifelsesame.d +++ b/analysis/ifelsesame.d @@ -14,7 +14,12 @@ import analysis.helpers; /** - * Checks for if statements whose "then" block is the same as the "else" block + * Checks for duplicated code in conditional and logical expressions. + * $(UL + * $(LI If statements whose "then" block is the same as the "else" block) + * $(LI || and && expressions where the left and right are the same) + * $(LI == expressions where the left and right are the same) + * ) */ class IfElseSameCheck : BaseAnalyzer { @@ -44,6 +49,28 @@ class IfElseSameCheck : BaseAnalyzer } assignExpression.accept(this); } + + override void visit(const AndAndExpression andAndExpression) + { + if (andAndExpression.left !is null && andAndExpression.right !is null + && andAndExpression.left == andAndExpression.right) + { + addErrorMessage(andAndExpression.line, andAndExpression.column, + "Left side of logical and is identical to right side."); + } + andAndExpression.accept(this); + } + + override void visit(const OrOrExpression orOrExpression) + { + if (orOrExpression.left !is null && orOrExpression.right !is null + && orOrExpression.left == orOrExpression.right) + { + addErrorMessage(orOrExpression.line, orOrExpression.column, + "Left side of logical or is identical to right side."); + } + orOrExpression.accept(this); + } } unittest diff --git a/libdparse b/libdparse index 9187ad6..acb6b43 160000 --- a/libdparse +++ b/libdparse @@ -1 +1 @@ -Subproject commit 9187ad6c775e91c78fd2e9313d2d66d1922445eb +Subproject commit acb6b43655b1144fbcaf08ec0442a81143cdb569 diff --git a/main.d b/main.d index 294ef98..7531d38 100644 --- a/main.d +++ b/main.d @@ -59,11 +59,11 @@ int run(string[] args) try { - getopt(args, "sloc|l", &sloc, "highlight", &highlight, - "ctags|c", &ctags, "recursive|r|R", &recursive, "help|h", &help, - "tokenCount|t", &tokenCount, "syntaxCheck|s", &syntaxCheck, + getopt(args, std.getopt.config.caseSensitive, "sloc|l", &sloc, + "highlight", &highlight, "ctags|c", &ctags, "recursive|r|R", &recursive, + "help|h", &help, "tokenCount|t", &tokenCount, "syntaxCheck|s", &syntaxCheck, "ast|xml", &ast, "imports|i", &imports, "outline|o", &outline, - "tokenDump", &tokenDump, "styleCheck", &styleCheck, + "tokenDump", &tokenDump, "styleCheck|S", &styleCheck, "defaultConfig", &defaultConfig, "muffinButton", &muffin); } catch (ConvException e) @@ -319,7 +319,7 @@ options: syntax errors to stdout. One error or warning is printed per line. If no files are specified, input is read from stdin. - --styleCheck [sourceFiles] + --styleCheck | -S [sourceFiles] Lexes and parses sourceFiles, printing the line and column number of any static analysis check failures stdout.