prevent a case of false detection for auto functions
This commit is contained in:
parent
f283650c12
commit
55a6b2a758
|
@ -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.");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue