mirror of
https://github.com/dlang-community/D-Scanner.git
synced 2025-04-28 14:20:03 +03:00
replace libdparse in builtin properties visitor (#52)
This commit is contained in:
parent
da10937067
commit
d07ac30c6f
2 changed files with 48 additions and 56 deletions
|
@ -5,14 +5,7 @@
|
||||||
|
|
||||||
module dscanner.analysis.builtin_property_names;
|
module dscanner.analysis.builtin_property_names;
|
||||||
|
|
||||||
import std.stdio;
|
|
||||||
import std.regex;
|
|
||||||
import dparse.ast;
|
|
||||||
import dparse.lexer;
|
|
||||||
import dscanner.analysis.base;
|
import dscanner.analysis.base;
|
||||||
import dscanner.analysis.helpers;
|
|
||||||
import dsymbol.scope_;
|
|
||||||
import std.algorithm : map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The following code should be killed with fire:
|
* The following code should be killed with fire:
|
||||||
|
@ -27,63 +20,64 @@ import std.algorithm : map;
|
||||||
* }
|
* }
|
||||||
* ---
|
* ---
|
||||||
*/
|
*/
|
||||||
final class BuiltinPropertyNameCheck : BaseAnalyzer
|
|
||||||
{
|
|
||||||
alias visit = BaseAnalyzer.visit;
|
|
||||||
|
|
||||||
|
extern(C++) class BuiltinPropertyNameCheck(AST) : BaseAnalyzerDmd
|
||||||
|
{
|
||||||
|
alias visit = BaseAnalyzerDmd.visit;
|
||||||
mixin AnalyzerInfo!"builtin_property_names_check";
|
mixin AnalyzerInfo!"builtin_property_names_check";
|
||||||
|
|
||||||
this(BaseAnalyzerArguments args)
|
extern(D) this(string fileName)
|
||||||
{
|
{
|
||||||
super(args);
|
super(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const FunctionDeclaration fd)
|
mixin AggregateVisit!(AST.StructDeclaration);
|
||||||
|
mixin AggregateVisit!(AST.ClassDeclaration);
|
||||||
|
mixin AggregateVisit!(AST.InterfaceDeclaration);
|
||||||
|
mixin AggregateVisit!(AST.UnionDeclaration);
|
||||||
|
|
||||||
|
override void visit(AST.VarDeclaration vd)
|
||||||
{
|
{
|
||||||
if (depth > 0 && isBuiltinProperty(fd.name.text))
|
if (inAggregate && isBuiltinProperty(vd.ident.toString()))
|
||||||
{
|
addErrorMessage(cast(ulong) vd.loc.linnum, cast(ulong) vd.loc.charnum,
|
||||||
addErrorMessage(fd.name, KEY, generateErrorMessage(fd.name.text));
|
KEY, generateErrorMessage(vd.ident.toString()));
|
||||||
}
|
|
||||||
fd.accept(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const FunctionBody functionBody)
|
override void visit(AST.FuncDeclaration fd)
|
||||||
{
|
{
|
||||||
immutable int d = depth;
|
if (inAggregate && isBuiltinProperty(fd.ident.toString()))
|
||||||
scope (exit)
|
addErrorMessage(cast(ulong) fd.loc.linnum, cast(ulong) fd.loc.charnum,
|
||||||
depth = d;
|
KEY, generateErrorMessage(fd.ident.toString()));
|
||||||
depth = 0;
|
|
||||||
functionBody.accept(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const AutoDeclaration ad)
|
override void visit(AST.AliasDeclaration ad)
|
||||||
{
|
{
|
||||||
if (depth > 0)
|
if (inAggregate && isBuiltinProperty(ad.ident.toString()))
|
||||||
foreach (i; ad.parts.map!(a => a.identifier))
|
addErrorMessage(cast(ulong) ad.loc.linnum, cast(ulong) ad.loc.charnum,
|
||||||
{
|
KEY, generateErrorMessage(ad.ident.toString()));
|
||||||
if (isBuiltinProperty(i.text))
|
|
||||||
addErrorMessage(i, KEY, generateErrorMessage(i.text));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const Declarator d)
|
override void visit(AST.TemplateDeclaration td)
|
||||||
{
|
{
|
||||||
if (depth > 0 && isBuiltinProperty(d.name.text))
|
if (inAggregate && isBuiltinProperty(td.ident.toString()))
|
||||||
addErrorMessage(d.name, KEY, generateErrorMessage(d.name.text));
|
addErrorMessage(cast(ulong) td.loc.linnum, cast(ulong) td.loc.charnum,
|
||||||
}
|
KEY, generateErrorMessage(td.ident.toString()));
|
||||||
|
|
||||||
override void visit(const StructBody sb)
|
|
||||||
{
|
|
||||||
depth++;
|
|
||||||
sb.accept(this);
|
|
||||||
depth--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum string KEY = "dscanner.confusing.builtin_property_names";
|
enum string KEY = "dscanner.confusing.builtin_property_names";
|
||||||
|
|
||||||
string generateErrorMessage(string name)
|
template AggregateVisit(NodeType)
|
||||||
|
{
|
||||||
|
override void visit(NodeType n)
|
||||||
|
{
|
||||||
|
inAggregate++;
|
||||||
|
super.visit(n);
|
||||||
|
inAggregate--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern(D) string generateErrorMessage(const(char)[] name)
|
||||||
{
|
{
|
||||||
import std.string : format;
|
import std.string : format;
|
||||||
|
|
||||||
|
@ -91,7 +85,7 @@ private:
|
||||||
~ " confuse code that depends on the '.%s' property of a type.", name, name);
|
~ " confuse code that depends on the '.%s' property of a type.", name, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isBuiltinProperty(string name)
|
extern(D) bool isBuiltinProperty(const(char)[] name)
|
||||||
{
|
{
|
||||||
import std.algorithm : canFind;
|
import std.algorithm : canFind;
|
||||||
|
|
||||||
|
@ -99,26 +93,25 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
enum string[] BuiltinProperties = ["init", "sizeof", "mangleof", "alignof", "stringof"];
|
enum string[] BuiltinProperties = ["init", "sizeof", "mangleof", "alignof", "stringof"];
|
||||||
int depth;
|
int inAggregate;
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig;
|
import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig;
|
||||||
|
import dscanner.analysis.helpers : assertAnalyzerWarnings = assertAnalyzerWarningsDMD;
|
||||||
|
import std.stdio : stderr;
|
||||||
|
|
||||||
StaticAnalysisConfig sac = disabledConfig();
|
StaticAnalysisConfig sac = disabledConfig();
|
||||||
sac.builtin_property_names_check = Check.enabled;
|
sac.builtin_property_names_check = Check.enabled;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
class SomeClass
|
class SomeClass
|
||||||
{
|
{
|
||||||
void init(); /+
|
void init(); // [warn]: Avoid naming members 'init'. This can confuse code that depends on the '.init' property of a type.
|
||||||
^^^^ [warn]: Avoid naming members 'init'. This can confuse code that depends on the '.init' property of a type. +/
|
int init; // [warn]: Avoid naming members 'init'. This can confuse code that depends on the '.init' property of a type.
|
||||||
int init; /+
|
auto init = 10; // [warn]: Avoid naming members 'init'. This can confuse code that depends on the '.init' property of a type.
|
||||||
^^^^ [warn]: Avoid naming members 'init'. This can confuse code that depends on the '.init' property of a type. +/
|
|
||||||
auto init = 10; /+
|
|
||||||
^^^^ [warn]: Avoid naming members 'init'. This can confuse code that depends on the '.init' property of a type. +/
|
|
||||||
}
|
}
|
||||||
}c, sac);
|
}c, sac);
|
||||||
|
|
||||||
stderr.writeln("Unittest for NumberStyleCheck passed.");
|
stderr.writeln("Unittest for BuiltinPropertyNamesCheck passed.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -840,10 +840,6 @@ private BaseAnalyzer[] getAnalyzersForModuleAndConfig(string fileName,
|
||||||
checks ~= new BackwardsRangeCheck(args.setSkipTests(
|
checks ~= new BackwardsRangeCheck(args.setSkipTests(
|
||||||
analysisConfig.backwards_range_check == Check.skipTests && !ut));
|
analysisConfig.backwards_range_check == Check.skipTests && !ut));
|
||||||
|
|
||||||
if (moduleName.shouldRun!BuiltinPropertyNameCheck(analysisConfig))
|
|
||||||
checks ~= new BuiltinPropertyNameCheck(args.setSkipTests(
|
|
||||||
analysisConfig.builtin_property_names_check == Check.skipTests && !ut));
|
|
||||||
|
|
||||||
if (moduleName.shouldRun!CommaExpressionCheck(analysisConfig))
|
if (moduleName.shouldRun!CommaExpressionCheck(analysisConfig))
|
||||||
checks ~= new CommaExpressionCheck(args.setSkipTests(
|
checks ~= new CommaExpressionCheck(args.setSkipTests(
|
||||||
analysisConfig.comma_expression_check == Check.skipTests && !ut));
|
analysisConfig.comma_expression_check == Check.skipTests && !ut));
|
||||||
|
@ -1335,6 +1331,9 @@ MessageSet analyzeDmd(string fileName, ASTBase.Module m, const char[] moduleName
|
||||||
config.logical_precedence_check == Check.skipTests && !ut
|
config.logical_precedence_check == Check.skipTests && !ut
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (moduleName.shouldRunDmd!(BuiltinPropertyNameCheck!ASTBase)(config))
|
||||||
|
visitors ~= new BuiltinPropertyNameCheck!ASTBase(fileName);
|
||||||
|
|
||||||
foreach (visitor; visitors)
|
foreach (visitor; visitors)
|
||||||
{
|
{
|
||||||
m.accept(visitor);
|
m.accept(visitor);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue