mirror of
https://github.com/dlang-community/D-Scanner.git
synced 2025-04-26 13:20:07 +03:00
Delete IfStatementCheck (#106)
This commit is contained in:
parent
5f3e25f40f
commit
ffce05181e
3 changed files with 1 additions and 135 deletions
1
changelog/dscanner.if-statements.dd
Normal file
1
changelog/dscanner.if-statements.dd
Normal file
|
@ -0,0 +1 @@
|
|||
Remove IfStatementCheck, as it has been disabled in 2015 due to false positives and untouched ever since then.
|
|
@ -1,129 +0,0 @@
|
|||
// Copyright Brian Schott (Hackerpilot) 2015.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
module dscanner.analysis.if_statements;
|
||||
|
||||
import dparse.ast;
|
||||
import dparse.lexer;
|
||||
import dparse.formatter;
|
||||
import dscanner.analysis.base;
|
||||
import dsymbol.scope_ : Scope;
|
||||
import std.typecons : Rebindable, rebindable;
|
||||
|
||||
final class IfStatementCheck : BaseAnalyzer
|
||||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
mixin AnalyzerInfo!"redundant_if_check";
|
||||
|
||||
this(BaseAnalyzerArguments args)
|
||||
{
|
||||
super(args);
|
||||
}
|
||||
|
||||
override void visit(const IfStatement ifStatement)
|
||||
{
|
||||
import std.string : format;
|
||||
import std.algorithm : sort, countUntil;
|
||||
import std.array : appender;
|
||||
|
||||
++depth;
|
||||
|
||||
if (ifStatement.condition.expression.items.length == 1
|
||||
&& (cast(AndAndExpression) ifStatement.condition.expression.items[0]) is null)
|
||||
{
|
||||
redundancyCheck(ifStatement.condition.expression,
|
||||
ifStatement.condition.expression.line, ifStatement.condition.expression.column);
|
||||
}
|
||||
inIfExpresson = true;
|
||||
ifStatement.condition.expression.accept(this);
|
||||
inIfExpresson = false;
|
||||
ifStatement.thenStatement.accept(this);
|
||||
if (expressions.length)
|
||||
expressions = expressions[0 .. expressions.countUntil!(a => a.depth + 1 >= depth)];
|
||||
if (ifStatement.elseStatement)
|
||||
ifStatement.elseStatement.accept(this);
|
||||
--depth;
|
||||
}
|
||||
|
||||
override void visit(const AndAndExpression andAndExpression)
|
||||
{
|
||||
if (inIfExpresson)
|
||||
{
|
||||
redundancyCheck(andAndExpression, andAndExpression.line, andAndExpression.column);
|
||||
redundancyCheck(andAndExpression.left, andAndExpression.line, andAndExpression.column);
|
||||
redundancyCheck(andAndExpression.right, andAndExpression.line,
|
||||
andAndExpression.column);
|
||||
}
|
||||
andAndExpression.accept(this);
|
||||
}
|
||||
|
||||
override void visit(const OrOrExpression orOrExpression)
|
||||
{
|
||||
// intentionally does nothing
|
||||
}
|
||||
|
||||
private:
|
||||
invariant
|
||||
{
|
||||
assert(depth >= 0);
|
||||
}
|
||||
|
||||
void redundancyCheck(const ExpressionNode expression, size_t line, size_t column)
|
||||
{
|
||||
import std.string : format;
|
||||
import std.array : appender;
|
||||
import std.algorithm : sort;
|
||||
|
||||
if (expression is null)
|
||||
return;
|
||||
auto app = appender!string();
|
||||
dparse.formatter.format(app, expression);
|
||||
immutable size_t prevLocation = alreadyChecked(app.data, line, column);
|
||||
if (prevLocation != size_t.max)
|
||||
{
|
||||
addErrorMessage(expressions[prevLocation].astNode, KEY, "Expression %s is true: already checked on line %d.".format(
|
||||
expressions[prevLocation].formatted, expressions[prevLocation].line));
|
||||
}
|
||||
else
|
||||
{
|
||||
expressions ~= ExpressionInfo(app.data, line, column, depth, (cast(const BaseNode) expression).rebindable);
|
||||
sort(expressions);
|
||||
}
|
||||
}
|
||||
|
||||
size_t alreadyChecked(string expressionText, size_t line, size_t column)
|
||||
{
|
||||
foreach (i, ref info; expressions)
|
||||
{
|
||||
if (info.line == line && info.column == column)
|
||||
continue;
|
||||
if (info.formatted == expressionText)
|
||||
return i;
|
||||
}
|
||||
return size_t.max;
|
||||
}
|
||||
|
||||
bool inIfExpresson;
|
||||
int depth;
|
||||
ExpressionInfo[] expressions;
|
||||
enum string KEY = "dscanner.if_statement";
|
||||
}
|
||||
|
||||
private struct ExpressionInfo
|
||||
{
|
||||
int opCmp(ref const ExpressionInfo other) const nothrow
|
||||
{
|
||||
if (line < other.line || (line == other.line && column < other.column))
|
||||
return 1;
|
||||
if (line == other.line && column == other.column)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
string formatted;
|
||||
size_t line;
|
||||
size_t column;
|
||||
int depth;
|
||||
Rebindable!(const BaseNode) astNode;
|
||||
}
|
|
@ -51,7 +51,6 @@ import dscanner.analysis.comma_expression;
|
|||
import dscanner.analysis.function_attributes;
|
||||
import dscanner.analysis.local_imports;
|
||||
import dscanner.analysis.unmodified;
|
||||
import dscanner.analysis.if_statements;
|
||||
import dscanner.analysis.redundant_parens;
|
||||
import dscanner.analysis.mismatched_args;
|
||||
import dscanner.analysis.label_var_same_name_check;
|
||||
|
@ -908,11 +907,6 @@ private BaseAnalyzer[] getAnalyzersForModuleAndConfig(string fileName,
|
|||
checks ~= new BodyOnDisabledFuncsCheck(args.setSkipTests(
|
||||
analysisConfig.body_on_disabled_func_check == Check.skipTests && !ut));
|
||||
|
||||
version (none)
|
||||
if (moduleName.shouldRun!IfStatementCheck(analysisConfig))
|
||||
checks ~= new IfStatementCheck(args.setSkipTests(
|
||||
analysisConfig.redundant_if_check == Check.skipTests && !ut));
|
||||
|
||||
return checks;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue