Added more attributes to the duplicate checker.

This commit is contained in:
Matthew Brennan Jones 2014-05-24 18:24:37 -07:00
parent be02c872b5
commit fad096cdff
2 changed files with 38 additions and 24 deletions

View File

@ -12,11 +12,10 @@ import std.d.lexer;
import analysis.base; import analysis.base;
import analysis.helpers; import analysis.helpers;
// FIXME: Make it work with @safe, @trusted, @system
// FIXME: Make it work with pure, nothrow // FIXME: Make it work with pure, nothrow
/** /**
* Checks for duplicate attributes such as @property * Checks for duplicate attributes such as @property, @safe, @trusted, @system
*/ */
class DuplicateAttributeCheck : BaseAnalyzer class DuplicateAttributeCheck : BaseAnalyzer
{ {
@ -36,6 +35,9 @@ class DuplicateAttributeCheck : BaseAnalyzer
void checkAttributes(const Declaration node) void checkAttributes(const Declaration node)
{ {
bool hasProperty = false; bool hasProperty = false;
bool hasSafe = false;
bool hasTrusted = false;
bool hasSystem = false;
// Check the attributes // Check the attributes
foreach (attribute; node.attributes) foreach (attribute; node.attributes)
@ -47,9 +49,12 @@ class DuplicateAttributeCheck : BaseAnalyzer
|| attribute.storageClass.atAttribute.identifier is Token.init) || attribute.storageClass.atAttribute.identifier is Token.init)
continue; continue;
// Is a property // Check for the attributes
auto iden = attribute.storageClass.atAttribute.identifier; auto iden = attribute.storageClass.atAttribute.identifier;
checkProperty(iden, hasProperty); checkDuplicateAttribute(iden, "property", hasProperty);
checkDuplicateAttribute(iden, "safe", hasSafe);
checkDuplicateAttribute(iden, "trusted", hasTrusted);
checkDuplicateAttribute(iden, "system", hasSystem);
} }
// Just return if missing function nodes // Just return if missing function nodes
@ -66,56 +71,64 @@ class DuplicateAttributeCheck : BaseAnalyzer
|| memberFunctionAttribute.atAttribute.identifier is Token.init) || memberFunctionAttribute.atAttribute.identifier is Token.init)
continue; continue;
// Is a property // Check for the attributes
auto iden = memberFunctionAttribute.atAttribute.identifier; auto iden = memberFunctionAttribute.atAttribute.identifier;
checkProperty(iden, hasProperty); checkDuplicateAttribute(iden, "property", hasProperty);
checkDuplicateAttribute(iden, "safe", hasSafe);
checkDuplicateAttribute(iden, "trusted", hasTrusted);
checkDuplicateAttribute(iden, "system", hasSystem);
} }
} }
void checkProperty(const Token iden, ref bool hasProperty) void checkDuplicateAttribute(const Token token, const string attributeName, ref bool hasAttribute)
{ {
// Just return if not a property // Just return if not an attribute
if (!isProperty(iden)) if (token.type != tok!"identifier"
|| token.text != attributeName)
return; return;
// Already has a property // Already has that attribute
if (hasProperty) if (hasAttribute)
{ {
string message = "The attribute '%s' is duplicated.".format(iden.text); string message = "The attribute '%s' is duplicated.".format(token.text);
addErrorMessage(iden.line, iden.column, message); addErrorMessage(token.line, token.column, message);
} }
// Mark it as a property // Mark it as having that attribute
hasProperty = true; hasAttribute = true;
} }
} }
bool isProperty(const Token token) pure
{
return token.type == tok!"identifier" && token.text == "property";
}
unittest unittest
{ {
assertAnalyzerWarnings(q{ assertAnalyzerWarnings(q{
class CAllocator class ExampleAttributes
{ {
@property bool xxx() // ok @property @safe bool xxx() // ok
{ {
return false; return false;
} }
// Duplicate before
@property @property bool aaa() // [warn]: The attribute 'property' is duplicated. @property @property bool aaa() // [warn]: The attribute 'property' is duplicated.
{ {
return false; return false;
} }
bool bbb() @property @property // [warn]: The attribute 'property' is duplicated. // Duplicate after
bool bbb() @safe @safe // [warn]: The attribute 'safe' is duplicated.
{ {
return false; return false;
} }
@property bool ccc() @property // [warn]: The attribute 'property' is duplicated. // Duplicate before and after
@system bool ccc() @system // [warn]: The attribute 'system' is duplicated.
{
return false;
}
// Duplicate before and after
@trusted bool ddd() @trusted // [warn]: The attribute 'trusted' is duplicated.
{ {
return false; return false;
} }

View File

@ -8,6 +8,7 @@ module analysis.helpers;
import std.string; import std.string;
import std.traits; import std.traits;
import std.d.ast; import std.d.ast;
import analysis.run;
S between(S)(S value, S before, S after) S between(S)(S value, S before, S after)