Fix #341
This commit is contained in:
parent
e7a1b1fd2f
commit
15c780fac4
2
dub.json
2
dub.json
|
@ -7,7 +7,7 @@
|
||||||
"targetType": "executable",
|
"targetType": "executable",
|
||||||
"versions": ["built_with_dub"],
|
"versions": ["built_with_dub"],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"libdparse": "~>0.7.0-alpha9",
|
"libdparse": "~>0.7.0-alpha10",
|
||||||
"dsymbol": "~>0.2.0-alpha6",
|
"dsymbol": "~>0.2.0-alpha6",
|
||||||
"inifiled": ">=0.0.6",
|
"inifiled": ">=0.0.6",
|
||||||
},
|
},
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 80f054e7d137de3b7907ee4a6406ffad5af9a6ea
|
Subproject commit c1dd27ea248111bd1dc9f8fb8a24f54592907110
|
|
@ -116,4 +116,7 @@ struct StaticAnalysisConfig
|
||||||
|
|
||||||
@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;
|
bool static_if_else_check;
|
||||||
|
|
||||||
|
@INI("Check for unclear lambda syntax")
|
||||||
|
bool lambda_return_check;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright Brian Schott (Hackerpilot) 2016.
|
||||||
|
// 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 analysis.lambda_return_check;
|
||||||
|
|
||||||
|
import dparse.ast;
|
||||||
|
import dparse.lexer;
|
||||||
|
import analysis.base;
|
||||||
|
|
||||||
|
class LambdaReturnCheck : BaseAnalyzer
|
||||||
|
{
|
||||||
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
|
this(string fileName)
|
||||||
|
{
|
||||||
|
super(fileName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
override void visit(const FunctionLiteralExpression fLit)
|
||||||
|
{
|
||||||
|
if (fLit.assignExpression is null)
|
||||||
|
return;
|
||||||
|
const UnaryExpression unary = cast(const UnaryExpression) fLit.assignExpression;
|
||||||
|
if (unary is null)
|
||||||
|
return;
|
||||||
|
if (unary.primaryExpression is null)
|
||||||
|
return;
|
||||||
|
if (unary.primaryExpression.functionLiteralExpression is null)
|
||||||
|
return;
|
||||||
|
if (unary.primaryExpression.functionLiteralExpression.parameters !is null)
|
||||||
|
return;
|
||||||
|
if (unary.primaryExpression.functionLiteralExpression.identifier != tok!"")
|
||||||
|
return;
|
||||||
|
if (unary.primaryExpression.functionLiteralExpression.functionBody is null)
|
||||||
|
return;
|
||||||
|
if (unary.primaryExpression.functionLiteralExpression.functionBody.blockStatement is null)
|
||||||
|
return;
|
||||||
|
addErrorMessage(fLit.line, fLit.column, KEY, "This lambda returns a lambda. Add parenthesis to clarify.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum KEY = "dscanner.confusing.lambda_returns_lambda";
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
import analysis.helpers : assertAnalyzerWarnings;
|
||||||
|
import analysis.config : StaticAnalysisConfig;
|
||||||
|
import std.stdio : stderr;
|
||||||
|
|
||||||
|
StaticAnalysisConfig sac;
|
||||||
|
sac.lambda_return_check = true;
|
||||||
|
|
||||||
|
auto code = `
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int[] b;
|
||||||
|
auto a = b.map!(a => { return a * a + 2; }).array(); // [warn]: This lambda returns a lambda. Add parenthesis to clarify.
|
||||||
|
pragma(msg, typeof(a => { return a; })); // [warn]: This lambda returns a lambda. Add parenthesis to clarify.
|
||||||
|
pragma(msg, typeof((a) => { return a; })); // [warn]: This lambda returns a lambda. Add parenthesis to clarify.
|
||||||
|
pragma(msg, typeof({ return a; }));
|
||||||
|
pragma(msg, typeof(a => () { return a; }));
|
||||||
|
}`c;
|
||||||
|
assertAnalyzerWarnings(code, sac);
|
||||||
|
stderr.writeln("Unittest for LambdaReturnCheck passed.");
|
||||||
|
}
|
|
@ -58,6 +58,7 @@ import analysis.incorrect_infinite_range;
|
||||||
import analysis.useless_assert;
|
import analysis.useless_assert;
|
||||||
import analysis.alias_syntax_check;
|
import analysis.alias_syntax_check;
|
||||||
import analysis.static_if_else;
|
import analysis.static_if_else;
|
||||||
|
import analysis.lambda_return_check;
|
||||||
|
|
||||||
import dsymbol.string_interning : internString;
|
import dsymbol.string_interning : internString;
|
||||||
import dsymbol.scope_;
|
import dsymbol.scope_;
|
||||||
|
@ -276,6 +277,8 @@ MessageSet analyze(string fileName, const Module m, const StaticAnalysisConfig a
|
||||||
checks ~= new AliasSyntaxCheck(fileName);
|
checks ~= new AliasSyntaxCheck(fileName);
|
||||||
if (analysisConfig.static_if_else_check)
|
if (analysisConfig.static_if_else_check)
|
||||||
checks ~= new StaticIfElse(fileName);
|
checks ~= new StaticIfElse(fileName);
|
||||||
|
if (analysisConfig.lambda_return_check)
|
||||||
|
checks ~= new LambdaReturnCheck(fileName);
|
||||||
version (none)
|
version (none)
|
||||||
if (analysisConfig.redundant_if_check)
|
if (analysisConfig.redundant_if_check)
|
||||||
checks ~= new IfStatementCheck(fileName, moduleScope);
|
checks ~= new IfStatementCheck(fileName, moduleScope);
|
||||||
|
|
Loading…
Reference in New Issue