From 7b91483943e74ab0a31d53e3a699598e8aa6423a Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Fri, 28 Jul 2017 00:30:03 +0200 Subject: [PATCH] fix #312 - spurious warnings about non-const toString inside const block (#505) --- src/analysis/objectconst.d | 48 ++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/src/analysis/objectconst.d b/src/analysis/objectconst.d index d2b0a98..64f4184 100644 --- a/src/analysis/objectconst.d +++ b/src/analysis/objectconst.d @@ -21,6 +21,7 @@ class ObjectConstCheck : BaseAnalyzer { alias visit = BaseAnalyzer.visit; + /// this(string fileName, const(Scope)* sc, bool skipTests = false) { super(fileName, sc, skipTests); @@ -31,24 +32,40 @@ class ObjectConstCheck : BaseAnalyzer mixin visitTemplate!UnionDeclaration; 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) { - if (inAggregate && d.functionDeclaration !is null - && isInteresting(d.functionDeclaration.name.text) && (!hasConst(d.attributes) - && !hasConst(d.functionDeclaration.memberFunctionAttributes))) + import std.algorithm : any; + bool setConstBlock; + 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, d.functionDeclaration.name.column, "dscanner.suspicious.object_const", "Methods 'opCmp', 'toHash', 'opEquals', 'opCast', and/or 'toString' are non-const."); } + d.accept(this); - } - private static bool hasConst(const Attribute[] attributes) - { - import std.algorithm : any; - - return attributes.any!(a => a.attribute == tok!"const"); + if (!inAggregate) + constColon = false; + if (setConstBlock) + constBlock = false; } private static bool hasConst(const MemberFunctionAttribute[] attributes) @@ -65,7 +82,8 @@ class ObjectConstCheck : BaseAnalyzer || 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 class Dog {