Added more attributes to the duplicate checker.
This commit is contained in:
parent
be02c872b5
commit
fad096cdff
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue