Fix #206
This commit is contained in:
parent
6258e9886e
commit
53a0958e6b
|
@ -67,6 +67,7 @@ the given source files.
|
||||||
* Subtraction from .length properties. (These may be unsigned and could lead to integer underflow)
|
* Subtraction from .length properties. (These may be unsigned and could lead to integer underflow)
|
||||||
* Class, struct, and union member variables whose names conflict with built-in type properties.
|
* Class, struct, and union member variables whose names conflict with built-in type properties.
|
||||||
* Confusing asm syntax.
|
* Confusing asm syntax.
|
||||||
|
* Placement of const, immutable, or inout before a function return type instead of after the parameters.
|
||||||
|
|
||||||
#### Wishlish
|
#### Wishlish
|
||||||
* Assigning to foreach variables that are not "ref".
|
* Assigning to foreach variables that are not "ref".
|
||||||
|
|
|
@ -71,4 +71,7 @@ struct StaticAnalysisConfig
|
||||||
|
|
||||||
@INI("Checks for undocumented public declarations")
|
@INI("Checks for undocumented public declarations")
|
||||||
bool undocumented_declaration_check;
|
bool undocumented_declaration_check;
|
||||||
|
|
||||||
|
@INI("Checks for poor placement of function attributes")
|
||||||
|
bool function_attribute_check;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
// Copyright Brian Schott (Hackerpilot) 2014.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
module analysis.function_attributes;
|
||||||
|
|
||||||
|
import std.d.ast;
|
||||||
|
import std.d.lexer;
|
||||||
|
import analysis.base;
|
||||||
|
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefer
|
||||||
|
* ---
|
||||||
|
* int getStuff() const {}
|
||||||
|
* ---
|
||||||
|
* to
|
||||||
|
* ---
|
||||||
|
* const int getStuff() {}
|
||||||
|
* ---
|
||||||
|
*/
|
||||||
|
class FunctionAttributeCheck : BaseAnalyzer
|
||||||
|
{
|
||||||
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
|
this(string fileName)
|
||||||
|
{
|
||||||
|
super(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
override void visit(const Declaration dec)
|
||||||
|
{
|
||||||
|
if (dec.functionDeclaration is null)
|
||||||
|
goto end;
|
||||||
|
if (dec.attributes.length == 0)
|
||||||
|
goto end;
|
||||||
|
foreach (attr; dec.attributes)
|
||||||
|
{
|
||||||
|
if (attr.storageClass is null)
|
||||||
|
continue;
|
||||||
|
if (attr.storageClass.token == tok!"const"
|
||||||
|
|| attr.storageClass.token == tok!"inout"
|
||||||
|
|| attr.storageClass.token == tok!"immutable")
|
||||||
|
{
|
||||||
|
import std.string : format;
|
||||||
|
immutable string attrString = str(attr.storageClass.token.type);
|
||||||
|
addErrorMessage(dec.functionDeclaration.name.line,
|
||||||
|
dec.functionDeclaration.name.column, KEY,
|
||||||
|
format("'%s' is not an attribute of the return type."
|
||||||
|
~ " Place it after the parameter list to clarify.", attrString));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
dec.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum KEY = "dscanner.confusing.function_attributes";
|
||||||
|
}
|
|
@ -36,6 +36,7 @@ import analysis.asm_style;
|
||||||
import analysis.logic_precedence;
|
import analysis.logic_precedence;
|
||||||
import analysis.stats_collector;
|
import analysis.stats_collector;
|
||||||
import analysis.undocumented;
|
import analysis.undocumented;
|
||||||
|
import analysis.function_attributes;
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
|
@ -181,6 +182,7 @@ MessageSet analyze(string fileName, const Module m,
|
||||||
if (analysisConfig.asm_style_check) checks ~= new AsmStyleCheck(fileName);
|
if (analysisConfig.asm_style_check) checks ~= new AsmStyleCheck(fileName);
|
||||||
if (analysisConfig.logical_precedence_check) checks ~= new LogicPrecedenceCheck(fileName);
|
if (analysisConfig.logical_precedence_check) checks ~= new LogicPrecedenceCheck(fileName);
|
||||||
if (analysisConfig.undocumented_declaration_check) checks ~= new UndocumentedDeclarationCheck(fileName);
|
if (analysisConfig.undocumented_declaration_check) checks ~= new UndocumentedDeclarationCheck(fileName);
|
||||||
|
if (analysisConfig.function_attribute_check) checks ~= new FunctionAttributeCheck(fileName);
|
||||||
|
|
||||||
foreach (check; checks)
|
foreach (check; checks)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue