replace libdparse in builtin properties visitor (#52)

This commit is contained in:
lucica28 2022-12-02 13:08:02 +02:00 committed by Vladiwostok
parent da10937067
commit d07ac30c6f
2 changed files with 48 additions and 56 deletions

View file

@ -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.");
} }

View file

@ -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);