This commit is contained in:
parent
ce6056d4bc
commit
7b91483943
|
@ -21,6 +21,7 @@ class ObjectConstCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
|
///
|
||||||
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
this(string fileName, const(Scope)* sc, bool skipTests = false)
|
||||||
{
|
{
|
||||||
super(fileName, sc, skipTests);
|
super(fileName, sc, skipTests);
|
||||||
|
@ -31,24 +32,40 @@ class ObjectConstCheck : BaseAnalyzer
|
||||||
mixin visitTemplate!UnionDeclaration;
|
mixin visitTemplate!UnionDeclaration;
|
||||||
mixin visitTemplate!StructDeclaration;
|
mixin visitTemplate!StructDeclaration;
|
||||||
|
|
||||||
|
override void visit(const AttributeDeclaration d)
|
||||||
|
{
|
||||||
|
if (d.attribute.attribute == tok!"const" && inAggregate)
|
||||||
|
{
|
||||||
|
constColon = true;
|
||||||
|
}
|
||||||
|
d.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
override void visit(const Declaration d)
|
override void visit(const Declaration d)
|
||||||
{
|
{
|
||||||
if (inAggregate && d.functionDeclaration !is null
|
import std.algorithm : any;
|
||||||
&& isInteresting(d.functionDeclaration.name.text) && (!hasConst(d.attributes)
|
bool setConstBlock;
|
||||||
&& !hasConst(d.functionDeclaration.memberFunctionAttributes)))
|
if (inAggregate && d.attributes && d.attributes.any!(a => a.attribute == tok!"const"))
|
||||||
|
{
|
||||||
|
setConstBlock = true;
|
||||||
|
constBlock = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inAggregate && d.functionDeclaration !is null && !constColon && !constBlock
|
||||||
|
&& isInteresting(d.functionDeclaration.name.text)
|
||||||
|
&& !hasConst(d.functionDeclaration.memberFunctionAttributes))
|
||||||
{
|
{
|
||||||
addErrorMessage(d.functionDeclaration.name.line,
|
addErrorMessage(d.functionDeclaration.name.line,
|
||||||
d.functionDeclaration.name.column, "dscanner.suspicious.object_const",
|
d.functionDeclaration.name.column, "dscanner.suspicious.object_const",
|
||||||
"Methods 'opCmp', 'toHash', 'opEquals', 'opCast', and/or 'toString' are non-const.");
|
"Methods 'opCmp', 'toHash', 'opEquals', 'opCast', and/or 'toString' are non-const.");
|
||||||
}
|
}
|
||||||
|
|
||||||
d.accept(this);
|
d.accept(this);
|
||||||
}
|
|
||||||
|
|
||||||
private static bool hasConst(const Attribute[] attributes)
|
if (!inAggregate)
|
||||||
{
|
constColon = false;
|
||||||
import std.algorithm : any;
|
if (setConstBlock)
|
||||||
|
constBlock = false;
|
||||||
return attributes.any!(a => a.attribute == tok!"const");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool hasConst(const MemberFunctionAttribute[] attributes)
|
private static bool hasConst(const MemberFunctionAttribute[] attributes)
|
||||||
|
@ -65,7 +82,8 @@ class ObjectConstCheck : BaseAnalyzer
|
||||||
|| name == "toString" || name == "opCast";
|
|| name == "toString" || name == "opCast";
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool looking;
|
private bool constBlock;
|
||||||
|
private bool constColon;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +120,16 @@ unittest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Bat
|
||||||
|
{
|
||||||
|
const: override string toString() { return "foo"; } // ok
|
||||||
|
}
|
||||||
|
|
||||||
|
class Fox
|
||||||
|
{
|
||||||
|
const{ override string toString() { return "foo"; }} // ok
|
||||||
|
}
|
||||||
|
|
||||||
// Will warn, because none are const
|
// Will warn, because none are const
|
||||||
class Dog
|
class Dog
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue