replace libdparse in redundant parens check (#61)

This commit is contained in:
lucica28 2023-05-22 10:44:52 +03:00 committed by Vladiwostok
parent cb432bc651
commit 235e9d0884
2 changed files with 51 additions and 43 deletions

View file

@ -5,60 +5,66 @@
module dscanner.analysis.redundant_parens; module dscanner.analysis.redundant_parens;
import dparse.ast;
import dparse.lexer;
import dscanner.analysis.base; import dscanner.analysis.base;
import dsymbol.scope_ : Scope;
// TODO: check and fix
/** /**
* Checks for redundant parenthesis * Checks for redundant parenthesis
*/ */
final class RedundantParenCheck : BaseAnalyzer extern(C++) class RedundantParenCheck(AST) : BaseAnalyzerDmd
{ {
alias visit = BaseAnalyzer.visit; alias visit = BaseAnalyzerDmd.visit;
mixin AnalyzerInfo!"redundant_parens_check"; mixin AnalyzerInfo!"redundant_parens_check";
/// ///
this(BaseAnalyzerArguments args) extern(D) this(string fileName, bool skipTests = false)
{ {
super(args); super(fileName, skipTests);
} }
override void visit(const IfStatement statement) override void visit(AST.IfStatement s)
{ {
UnaryExpression unary; if (s.condition.parens)
if (statement.condition.expression is null || statement.condition.expression.items.length != 1) addErrorMessage(cast(ulong) s.loc.linnum, cast(ulong) s.loc.charnum,
goto end; KEY, MESSAGE);
unary = cast(UnaryExpression) statement.condition.expression.items[0];
if (unary is null)
goto end;
if (unary.primaryExpression is null)
goto end;
if (unary.primaryExpression.expression is null)
goto end;
addErrorMessage(unary.primaryExpression, KEY, "Redundant parenthesis.");
end:
statement.accept(this);
}
override void visit(const PrimaryExpression primaryExpression)
{
UnaryExpression unary;
if (primaryExpression.expression is null)
goto end;
unary = cast(UnaryExpression) primaryExpression.expression.items[0];
if (unary is null)
goto end;
if (unary.primaryExpression is null)
goto end;
if (unary.primaryExpression.expression is null)
goto end;
addErrorMessage(primaryExpression, KEY, "Redundant parenthesis.");
end:
primaryExpression.accept(this);
} }
private: private:
enum string KEY = "dscanner.suspicious.redundant_parens"; enum string KEY = "dscanner.suspicious.redundant_parens";
enum string MESSAGE = "Redundant parenthesis.";
}
unittest
{
import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig;
import std.stdio : stderr;
import dscanner.analysis.helpers : assertAnalyzerWarnings = assertAnalyzerWarningsDMD;
StaticAnalysisConfig sac = disabledConfig();
sac.redundant_parens_check = Check.enabled;
assertAnalyzerWarnings(q{
void testRedundantParens()
{
int a = 0;
bool b = true;
if ((a + 2 == 3)) // [warn]: Redundant parenthesis.
{
}
if ((b)) // [warn]: Redundant parenthesis.
{
}
if (b) { }
if (a * 2 == 0) { }
}
}c, sac);
stderr.writeln("Unittest for RedundantParenthesis passed.");
} }

View file

@ -881,10 +881,6 @@ private BaseAnalyzer[] getAnalyzersForModuleAndConfig(string fileName,
checks ~= new NumberStyleCheck(args.setSkipTests( checks ~= new NumberStyleCheck(args.setSkipTests(
analysisConfig.number_style_check == Check.skipTests && !ut)); analysisConfig.number_style_check == Check.skipTests && !ut));
if (moduleName.shouldRun!RedundantParenCheck(analysisConfig))
checks ~= new RedundantParenCheck(args.setSkipTests(
analysisConfig.redundant_parens_check == Check.skipTests && !ut));
if (moduleName.shouldRun!StyleChecker(analysisConfig)) if (moduleName.shouldRun!StyleChecker(analysisConfig))
checks ~= new StyleChecker(args.setSkipTests( checks ~= new StyleChecker(args.setSkipTests(
analysisConfig.style_check == Check.skipTests && !ut)); analysisConfig.style_check == Check.skipTests && !ut));
@ -1343,6 +1339,12 @@ MessageSet analyzeDmd(string fileName, ASTCodegen.Module m, const char[] moduleN
config.properly_documented_public_functions == Check.skipTests && !ut config.properly_documented_public_functions == Check.skipTests && !ut
); );
if (moduleName.shouldRunDmd!(RedundantParenCheck!ASTCodegen)(config))
visitors ~= new RedundantParenCheck!ASTCodegen(
fileName,
config.redundant_parens_check == Check.skipTests && !ut
);
foreach (visitor; visitors) foreach (visitor; visitors)
{ {
m.accept(visitor); m.accept(visitor);