replace libdparse in trust_too_much visitor (#70)

This commit is contained in:
lucica28 2023-05-29 13:47:43 +03:00 committed by Albert24GG
parent b45b268c0c
commit e73a8a8860
2 changed files with 33 additions and 73 deletions

View File

@ -917,10 +917,6 @@ private BaseAnalyzer[] getAnalyzersForModuleAndConfig(string fileName,
checks ~= new IfConstraintsIndentCheck(args.setSkipTests( checks ~= new IfConstraintsIndentCheck(args.setSkipTests(
analysisConfig.if_constraints_indent == Check.skipTests && !ut)); analysisConfig.if_constraints_indent == Check.skipTests && !ut));
if (moduleName.shouldRun!TrustTooMuchCheck(analysisConfig))
checks ~= new TrustTooMuchCheck(args.setSkipTests(
analysisConfig.trust_too_much == Check.skipTests && !ut));
if (moduleName.shouldRun!RedundantStorageClassCheck(analysisConfig)) if (moduleName.shouldRun!RedundantStorageClassCheck(analysisConfig))
checks ~= new RedundantStorageClassCheck(args.setSkipTests( checks ~= new RedundantStorageClassCheck(args.setSkipTests(
analysisConfig.redundant_storage_classes == Check.skipTests && !ut)); analysisConfig.redundant_storage_classes == Check.skipTests && !ut));
@ -1285,6 +1281,12 @@ MessageSet analyzeDmd(string fileName, ASTCodegen.Module m, const char[] moduleN
fileName, fileName,
config.opequals_tohash_check == Check.skipTests && !ut config.opequals_tohash_check == Check.skipTests && !ut
); );
if (moduleName.shouldRunDmd!(TrustTooMuchCheck!ASTCodegen)(config))
visitors ~= new TrustTooMuchCheck!ASTCodegen(
fileName,
config.trust_too_much == Check.skipTests && !ut
);
if (moduleName.shouldRunDmd!(AutoRefAssignmentCheck!ASTCodegen)(config)) if (moduleName.shouldRunDmd!(AutoRefAssignmentCheck!ASTCodegen)(config))
visitors ~= new AutoRefAssignmentCheck!ASTCodegen(fileName); visitors ~= new AutoRefAssignmentCheck!ASTCodegen(fileName);

View File

@ -5,103 +5,65 @@
module dscanner.analysis.trust_too_much; module dscanner.analysis.trust_too_much;
import std.stdio;
import dparse.ast;
import dparse.lexer;
import dscanner.analysis.base; import dscanner.analysis.base;
import dsymbol.scope_; import dmd.astenums : STC;
/** /**
* Checks that `@trusted` is only applied to a a single function * Checks that `@trusted` is only applied to a a single function
*/ */
final class TrustTooMuchCheck : BaseAnalyzer extern(C++) class TrustTooMuchCheck(AST) : BaseAnalyzerDmd
{ {
mixin AnalyzerInfo!"trust_too_much";
alias visit = BaseAnalyzerDmd.visit;
private: private:
extern(D) static immutable MESSAGE = "Trusting a whole scope is a bad idea, " ~
static immutable MESSAGE = "Trusting a whole scope is a bad idea, " ~
"`@trusted` should only be attached to the functions individually"; "`@trusted` should only be attached to the functions individually";
static immutable string KEY = "dscanner.trust_too_much"; extern(D) static immutable string KEY = "dscanner.trust_too_much";
bool checkAtAttribute = true;
public: public:
alias visit = BaseAnalyzer.visit;
mixin AnalyzerInfo!"trust_too_much";
/// ///
this(BaseAnalyzerArguments args) extern(D) this(string fileName, bool skipTests = false)
{ {
super(args); super(fileName, skipTests);
} }
override void visit(const AtAttribute d) override void visit(AST.StorageClassDeclaration scd)
{ {
if (checkAtAttribute && d.identifier.text == "trusted") if (scd.stc & STC.trusted)
addErrorMessage(d, KEY, MESSAGE); addErrorMessage(cast(ulong) scd.loc.linnum, cast(ulong) scd.loc.charnum,
d.accept(this); KEY, MESSAGE);
}
super.visit(scd);
// always applied to function body, so OK
override void visit(const MemberFunctionAttribute d)
{
const oldCheckAtAttribute = checkAtAttribute;
checkAtAttribute = false;
d.accept(this);
checkAtAttribute = oldCheckAtAttribute;
}
// handles `@trusted{}` and old style, leading, atAttribute for single funcs
override void visit(const Declaration d)
{
const oldCheckAtAttribute = checkAtAttribute;
checkAtAttribute = d.functionDeclaration is null && d.unittest_ is null &&
d.constructor is null && d.destructor is null &&
d.staticConstructor is null && d.staticDestructor is null &&
d.sharedStaticConstructor is null && d.sharedStaticDestructor is null;
d.accept(this);
checkAtAttribute = oldCheckAtAttribute;
}
// issue #588
override void visit(const AliasDeclaration d)
{
const oldCheckAtAttribute = checkAtAttribute;
checkAtAttribute = false;
d.accept(this);
checkAtAttribute = oldCheckAtAttribute;
} }
} }
unittest unittest
{ {
import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig; import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig;
import dscanner.analysis.helpers : assertAnalyzerWarnings; import dscanner.analysis.helpers : assertAnalyzerWarnings = assertAnalyzerWarningsDMD;
import std.format : format; import std.format : format;
import std.stdio : stderr;
StaticAnalysisConfig sac = disabledConfig(); StaticAnalysisConfig sac = disabledConfig();
sac.trust_too_much = Check.enabled; sac.trust_too_much = Check.enabled;
const msg = TrustTooMuchCheck.MESSAGE; const msg = "Trusting a whole scope is a bad idea, " ~
"`@trusted` should only be attached to the functions individually";
//--- fail cases ---// //--- fail cases ---//
assertAnalyzerWarnings(q{ assertAnalyzerWarnings(q{
@trusted: /+ @trusted: // [warn]: %s
^^^^^^^^ [warn]: %s +/
void test(); void test();
}c.format(msg), sac); }c.format(msg), sac);
assertAnalyzerWarnings(q{ assertAnalyzerWarnings(q{
@trusted @nogc: /+ @trusted @nogc: // [warn]: %s
^^^^^^^^ [warn]: %s +/
void test(); void test();
}c.format(msg), sac); }c.format(msg), sac);
assertAnalyzerWarnings(q{ assertAnalyzerWarnings(q{
@trusted { /+ @trusted { // [warn]: %s
^^^^^^^^ [warn]: %s +/
void test(); void test();
void test(); void test();
} }
@ -109,31 +71,27 @@ unittest
assertAnalyzerWarnings(q{ assertAnalyzerWarnings(q{
@safe { @safe {
@trusted @nogc { /+ @trusted @nogc { // [warn]: %s
^^^^^^^^ [warn]: %s +/
void test(); void test();
void test(); void test();
}} }}
}c.format(msg), sac); }c.format(msg), sac);
assertAnalyzerWarnings(q{ assertAnalyzerWarnings(q{
@nogc @trusted { /+ @nogc @trusted { // [warn]: %s
^^^^^^^^ [warn]: %s +/
void test(); void test();
void test(); void test();
} }
}c.format(msg), sac); }c.format(msg), sac);
assertAnalyzerWarnings(q{ assertAnalyzerWarnings(q{
@trusted template foo(){ /+ @trusted template foo(){ // [warn]: %s
^^^^^^^^ [warn]: %s +/
} }
}c.format(msg), sac); }c.format(msg), sac);
assertAnalyzerWarnings(q{ assertAnalyzerWarnings(q{
struct foo{ struct foo{
@trusted: /+ @trusted: // [warn]: %s
^^^^^^^^ [warn]: %s +/
} }
}c.format(msg), sac); }c.format(msg), sac);
//--- pass cases ---// //--- pass cases ---//
@ -161,4 +119,4 @@ unittest
}c , sac); }c , sac);
stderr.writeln("Unittest for TrustTooMuchCheck passed."); stderr.writeln("Unittest for TrustTooMuchCheck passed.");
} }