mirror of
https://github.com/dlang-community/D-Scanner.git
synced 2025-04-28 14:20:03 +03:00
replace libdparse in explicitly annotated unittests check (#44)
This commit is contained in:
parent
50e992c219
commit
65720ab41f
2 changed files with 60 additions and 92 deletions
|
@ -4,124 +4,93 @@
|
||||||
|
|
||||||
module dscanner.analysis.explicitly_annotated_unittests;
|
module dscanner.analysis.explicitly_annotated_unittests;
|
||||||
|
|
||||||
import dparse.lexer;
|
|
||||||
import dparse.ast;
|
|
||||||
import dscanner.analysis.base;
|
import dscanner.analysis.base;
|
||||||
|
import dscanner.analysis.helpers;
|
||||||
import std.stdio;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requires unittests to be explicitly annotated with either @safe or @system
|
* Requires unittests to be explicitly annotated with either @safe or @system
|
||||||
*/
|
*/
|
||||||
final class ExplicitlyAnnotatedUnittestCheck : BaseAnalyzer
|
extern(C++) class ExplicitlyAnnotatedUnittestCheck(AST) : BaseAnalyzerDmd
|
||||||
{
|
{
|
||||||
|
mixin AnalyzerInfo!"explicitly_annotated_unittests";
|
||||||
|
alias visit = BaseAnalyzerDmd.visit;
|
||||||
|
|
||||||
|
extern(D) this(string fileName)
|
||||||
|
{
|
||||||
|
super(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
override void visit(AST.UnitTestDeclaration d)
|
||||||
|
{
|
||||||
|
import dmd.astenums : STC;
|
||||||
|
|
||||||
|
if (!(d.storage_class & STC.safe || d.storage_class & STC.system))
|
||||||
|
addErrorMessage(cast(ulong) d.loc.linnum, cast(ulong) d.loc.charnum,
|
||||||
|
KEY, MESSAGE);
|
||||||
|
|
||||||
|
super.visit(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
enum string KEY = "dscanner.style.explicitly_annotated_unittest";
|
enum string KEY = "dscanner.style.explicitly_annotated_unittest";
|
||||||
enum string MESSAGE = "A unittest should be annotated with at least @safe or @system";
|
enum string MESSAGE = "A unittest should be annotated with at least @safe or @system";
|
||||||
mixin AnalyzerInfo!"explicitly_annotated_unittests";
|
|
||||||
|
|
||||||
///
|
|
||||||
this(BaseAnalyzerArguments args)
|
|
||||||
{
|
|
||||||
super(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
override void visit(const Declaration decl)
|
|
||||||
{
|
|
||||||
if (decl.unittest_ !is null)
|
|
||||||
{
|
|
||||||
bool isSafeOrSystem;
|
|
||||||
if (decl.attributes !is null)
|
|
||||||
foreach (attribute; decl.attributes)
|
|
||||||
{
|
|
||||||
if (attribute.atAttribute !is null)
|
|
||||||
{
|
|
||||||
const token = attribute.atAttribute.identifier.text;
|
|
||||||
if (token == "safe" || token == "system")
|
|
||||||
{
|
|
||||||
isSafeOrSystem = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isSafeOrSystem)
|
|
||||||
{
|
|
||||||
auto token = decl.unittest_.findTokenForDisplay(tok!"unittest");
|
|
||||||
addErrorMessage(token, KEY, MESSAGE,
|
|
||||||
[
|
|
||||||
AutoFix.insertionBefore(token[0], "@safe ", "Mark unittest @safe"),
|
|
||||||
AutoFix.insertionBefore(token[0], "@system ", "Mark unittest @system")
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
decl.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
alias visit = BaseAnalyzer.visit;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import dscanner.analysis.config : Check, disabledConfig, StaticAnalysisConfig;
|
|
||||||
import dscanner.analysis.helpers : assertAnalyzerWarnings, assertAutoFix;
|
|
||||||
import std.format : format;
|
|
||||||
import std.stdio : stderr;
|
import std.stdio : stderr;
|
||||||
|
import std.format : format;
|
||||||
|
import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig;
|
||||||
|
import dscanner.analysis.helpers : assertAnalyzerWarnings;
|
||||||
|
|
||||||
StaticAnalysisConfig sac = disabledConfig();
|
StaticAnalysisConfig sac = disabledConfig();
|
||||||
sac.explicitly_annotated_unittests = Check.enabled;
|
sac.explicitly_annotated_unittests = Check.enabled;
|
||||||
|
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarningsDMD(q{
|
||||||
|
|
||||||
|
@disable foo() {}
|
||||||
|
|
||||||
@safe unittest {}
|
@safe unittest {}
|
||||||
@system unittest {}
|
@system unittest {}
|
||||||
pure nothrow @system @nogc unittest {}
|
pure nothrow @system @nogc unittest {}
|
||||||
|
|
||||||
unittest {} /+
|
unittest {} // [warn]: A unittest should be annotated with at least @safe or @system
|
||||||
^^^^^^^^ [warn]: %s +/
|
pure nothrow @nogc unittest {} // [warn]: A unittest should be annotated with at least @safe or @system
|
||||||
pure nothrow @nogc unittest {} /+
|
}c, sac);
|
||||||
^^^^^^^^ [warn]: %s +/
|
|
||||||
}c.format(
|
|
||||||
ExplicitlyAnnotatedUnittestCheck.MESSAGE,
|
|
||||||
ExplicitlyAnnotatedUnittestCheck.MESSAGE,
|
|
||||||
), sac);
|
|
||||||
|
|
||||||
// nested
|
// nested
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarningsDMD(q{
|
||||||
struct Foo
|
struct Foo
|
||||||
{
|
{
|
||||||
@safe unittest {}
|
@safe unittest {}
|
||||||
@system unittest {}
|
@system unittest {}
|
||||||
|
|
||||||
unittest {} /+
|
unittest {} // [warn]: A unittest should be annotated with at least @safe or @system
|
||||||
^^^^^^^^ [warn]: %s +/
|
pure nothrow @nogc unittest {} // [warn]: A unittest should be annotated with at least @safe or @system
|
||||||
pure nothrow @nogc unittest {} /+
|
|
||||||
^^^^^^^^ [warn]: %s +/
|
|
||||||
}
|
|
||||||
}c.format(
|
|
||||||
ExplicitlyAnnotatedUnittestCheck.MESSAGE,
|
|
||||||
ExplicitlyAnnotatedUnittestCheck.MESSAGE,
|
|
||||||
), sac);
|
|
||||||
|
|
||||||
|
|
||||||
// nested
|
|
||||||
assertAutoFix(q{
|
|
||||||
unittest {} // fix:0
|
|
||||||
pure nothrow @nogc unittest {} // fix:0
|
|
||||||
|
|
||||||
struct Foo
|
|
||||||
{
|
|
||||||
unittest {} // fix:1
|
|
||||||
pure nothrow @nogc unittest {} // fix:1
|
|
||||||
}
|
|
||||||
}c, q{
|
|
||||||
@safe unittest {} // fix:0
|
|
||||||
pure nothrow @nogc @safe unittest {} // fix:0
|
|
||||||
|
|
||||||
struct Foo
|
|
||||||
{
|
|
||||||
@system unittest {} // fix:1
|
|
||||||
pure nothrow @nogc @system unittest {} // fix:1
|
|
||||||
}
|
}
|
||||||
}c, sac);
|
}c, sac);
|
||||||
|
|
||||||
|
// TODO: Check and fix
|
||||||
|
//// nested
|
||||||
|
//assertAutoFix(q{
|
||||||
|
//unittest {} // fix:0
|
||||||
|
//pure nothrow @nogc unittest {} // fix:0
|
||||||
|
|
||||||
|
//struct Foo
|
||||||
|
//{
|
||||||
|
//unittest {} // fix:1
|
||||||
|
//pure nothrow @nogc unittest {} // fix:1
|
||||||
|
//}
|
||||||
|
//}c, q{
|
||||||
|
//@safe unittest {} // fix:0
|
||||||
|
//pure nothrow @nogc @safe unittest {} // fix:0
|
||||||
|
|
||||||
|
//struct Foo
|
||||||
|
//{
|
||||||
|
//@system unittest {} // fix:1
|
||||||
|
//pure nothrow @nogc @system unittest {} // fix:1
|
||||||
|
//}
|
||||||
|
//}c, sac);
|
||||||
|
|
||||||
stderr.writeln("Unittest for ExplicitlyAnnotatedUnittestCheck passed.");
|
stderr.writeln("Unittest for ExplicitlyAnnotatedUnittestCheck passed.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -945,10 +945,6 @@ private BaseAnalyzer[] getAnalyzersForModuleAndConfig(string fileName,
|
||||||
checks ~= new AutoFunctionChecker(args.setSkipTests(
|
checks ~= new AutoFunctionChecker(args.setSkipTests(
|
||||||
analysisConfig.auto_function_check == Check.skipTests && !ut));
|
analysisConfig.auto_function_check == Check.skipTests && !ut));
|
||||||
|
|
||||||
if (moduleName.shouldRun!ExplicitlyAnnotatedUnittestCheck(analysisConfig))
|
|
||||||
checks ~= new ExplicitlyAnnotatedUnittestCheck(args.setSkipTests(
|
|
||||||
analysisConfig.explicitly_annotated_unittests == Check.skipTests && !ut));
|
|
||||||
|
|
||||||
if (moduleName.shouldRun!ProperlyDocumentedPublicFunctions(analysisConfig))
|
if (moduleName.shouldRun!ProperlyDocumentedPublicFunctions(analysisConfig))
|
||||||
checks ~= new ProperlyDocumentedPublicFunctions(args.setSkipTests(
|
checks ~= new ProperlyDocumentedPublicFunctions(args.setSkipTests(
|
||||||
analysisConfig.properly_documented_public_functions == Check.skipTests && !ut));
|
analysisConfig.properly_documented_public_functions == Check.skipTests && !ut));
|
||||||
|
@ -1326,6 +1322,9 @@ MessageSet analyzeDmd(string fileName, ASTBase.Module m, const char[] moduleName
|
||||||
if (moduleName.shouldRunDmd!(LengthSubtractionCheck!ASTBase)(config))
|
if (moduleName.shouldRunDmd!(LengthSubtractionCheck!ASTBase)(config))
|
||||||
visitors ~= new LengthSubtractionCheck!ASTBase(fileName);
|
visitors ~= new LengthSubtractionCheck!ASTBase(fileName);
|
||||||
|
|
||||||
|
if (moduleName.shouldRunDmd!(ExplicitlyAnnotatedUnittestCheck!ASTBase)(config))
|
||||||
|
visitors ~= new ExplicitlyAnnotatedUnittestCheck!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