prevent a case of false detection for auto functions

This commit is contained in:
Basile Burg 2016-12-11 00:42:47 +01:00
parent f283650c12
commit 55a6b2a758
No known key found for this signature in database
GPG Key ID: 1868039F415CB8CF
1 changed files with 62 additions and 4 deletions

View File

@ -30,6 +30,7 @@ private:
bool[] _returns;
size_t _mixinDepth;
string[] _literalWithReturn;
public:
@ -93,11 +94,63 @@ public:
override void visit(const(PrimaryExpression) exp)
{
exp.accept(this);
import std.algorithm.searching : find;
import std.range : empty;
if (_returns.length && _mixinDepth && !exp.primary.text.find("return").empty)
_returns[$-1] = true;
import std.algorithm.searching : canFind;
if (_returns.length && _mixinDepth)
{
if (findReturnInLiteral(exp.primary.text))
_returns[$-1] = true;
else if (exp.identifierOrTemplateInstance &&
_literalWithReturn.canFind(exp.identifierOrTemplateInstance.identifier.text))
_returns[$-1] = true;
}
}
bool findReturnInLiteral(const(string) value)
{
import std.algorithm.searching : find;
import std.range : empty;
return value == "return" || !value.find("return ").empty;
}
bool stringliteralHasReturn(const(NonVoidInitializer) nvi)
{
bool result;
if (!nvi.assignExpression || (cast(UnaryExpression) nvi.assignExpression) is null)
return result;
const(UnaryExpression) u = cast(UnaryExpression) nvi.assignExpression;
if (u.primaryExpression &&
u.primaryExpression.primary.type.isStringLiteral &&
findReturnInLiteral(u.primaryExpression.primary.text))
result = true;
return result;
}
override void visit(const(AutoDeclaration) decl)
{
decl.accept(this);
foreach(const(AutoDeclarationPart) p; decl.parts)
if (p.initializer &&
p.initializer.nonVoidInitializer &&
stringliteralHasReturn(p.initializer.nonVoidInitializer))
_literalWithReturn ~= p.identifier.text.idup;
}
override void visit(const(VariableDeclaration) decl)
{
decl.accept(this);
foreach(const(Declarator) d; decl.declarators)
if (d.initializer &&
d.initializer.nonVoidInitializer &&
stringliteralHasReturn(d.initializer.nonVoidInitializer))
_literalWithReturn ~= d.name.text.idup;
}
}
unittest
@ -163,5 +216,10 @@ unittest
AutoFunctionChecker.MESSAGE,
), sac);
assertAnalyzerWarnings(q{
enum _genSave = "return true;";
auto doStuff(){ mixin(_genSave);}
}, sac);
stderr.writeln("Unittest for AutoFunctionChecker passed.");
}