mirror of
https://github.com/dlang-community/D-Scanner.git
synced 2025-04-26 05:10:03 +03:00
Starting work on 0.3.0
This commit is contained in:
parent
327e629867
commit
a3c4a5384a
35 changed files with 212 additions and 99 deletions
6
.gitmodules
vendored
6
.gitmodules
vendored
|
@ -5,3 +5,9 @@
|
|||
[submodule "inifiled"]
|
||||
path = inifiled
|
||||
url = https://github.com/burner/inifiled.git
|
||||
[submodule "containers"]
|
||||
path = containers
|
||||
url = https://github.com/economicmodeling/containers.git
|
||||
[submodule "dsymbol"]
|
||||
path = dsymbol
|
||||
url = https://github.com/Hackerpilot/dsymbol.git
|
||||
|
|
1
containers
Submodule
1
containers
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit d732a67e76f60fd037547c3ffe8776c6deda6bab
|
1
dsymbol
Submodule
1
dsymbol
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit ddf8c97753471388303d64a47bdade85cc4de003
|
|
@ -1 +1 @@
|
|||
Subproject commit 32f6d638e38888e1bb11cf43e93fe2d11132a98f
|
||||
Subproject commit 0dccfca0e2a132b3c862a62da1c323ccd24e622d
|
17
makefile
17
makefile
|
@ -7,12 +7,21 @@ SRC = src/*.d\
|
|||
src/analysis/*.d\
|
||||
libdparse/src/std/*.d\
|
||||
libdparse/src/std/d/*.d\
|
||||
inifiled/source/*.d
|
||||
INCLUDE_PATHS = -Ilibdparse/src
|
||||
inifiled/source/*.d\
|
||||
$(shell find dsymbol/src -name "*.d")\
|
||||
containers/src/containers/ttree.d\
|
||||
containers/src/containers/unrolledlist.d\
|
||||
containers/src/containers/hashset.d\
|
||||
containers/src/containers/internal/hash.d\
|
||||
containers/src/containers/internal/node.d\
|
||||
containers/src/containers/internal/storage_type.d\
|
||||
containers/src/memory/allocators.d\
|
||||
containers/src/memory/appender.d
|
||||
INCLUDE_PATHS = -Ilibdparse/src -Idsymbol/src -Icontainers/src
|
||||
VERSIONS =
|
||||
DEBUG_VERSIONS = -version=std_parser_verbose
|
||||
DMD_FLAGS = -w -O -release -inline
|
||||
#DMD_FLAGS = -w
|
||||
#DMD_FLAGS = -w -O -release -inline
|
||||
DMD_FLAGS = -w
|
||||
|
||||
all: dmdbuild
|
||||
ldc: ldcbuild
|
||||
|
|
|
@ -10,6 +10,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
/**
|
||||
* Checks for confusing asm expressions.
|
||||
|
@ -19,9 +20,9 @@ class AsmStyleCheck : BaseAnalyzer
|
|||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const AsmBrExp brExp)
|
||||
|
|
|
@ -4,6 +4,7 @@ import std.container;
|
|||
import std.string;
|
||||
import std.d.ast;
|
||||
import std.array;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
struct Message
|
||||
{
|
||||
|
@ -26,8 +27,9 @@ alias MessageSet = RedBlackTree!(Message, comparitor, true);
|
|||
abstract class BaseAnalyzer : ASTVisitor
|
||||
{
|
||||
public:
|
||||
this(string fileName)
|
||||
this(string fileName, const Scope* sc)
|
||||
{
|
||||
this.sc = sc;
|
||||
this.fileName = fileName;
|
||||
_messages = new MessageSet;
|
||||
}
|
||||
|
@ -61,6 +63,8 @@ protected:
|
|||
*/
|
||||
string fileName;
|
||||
|
||||
const(Scope)* sc;
|
||||
|
||||
MessageSet _messages;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_;
|
||||
|
||||
/**
|
||||
* The following code should be killed with fire:
|
||||
|
@ -29,9 +30,9 @@ class BuiltinPropertyNameCheck : BaseAnalyzer
|
|||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const FunctionDeclaration fd)
|
||||
|
|
|
@ -8,6 +8,7 @@ module analysis.comma_expression;
|
|||
import std.d.ast;
|
||||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import dsymbol.scope_;
|
||||
|
||||
/**
|
||||
* Check for uses of the comma expression.
|
||||
|
@ -16,9 +17,9 @@ class CommaExpressionCheck : BaseAnalyzer
|
|||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const Expression ex)
|
||||
|
|
|
@ -5,15 +5,16 @@ import std.d.lexer;
|
|||
import std.stdio;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
|
||||
class ConstructorCheck : BaseAnalyzer
|
||||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const ClassDeclaration classDeclaration)
|
||||
|
|
|
@ -10,6 +10,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_;
|
||||
|
||||
/**
|
||||
* Checks for use of the deprecated 'delete' keyword
|
||||
|
@ -18,9 +19,9 @@ class DeleteCheck : BaseAnalyzer
|
|||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const DeleteExpression d)
|
||||
|
|
|
@ -11,6 +11,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -21,9 +22,9 @@ class DuplicateAttributeCheck : BaseAnalyzer
|
|||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const Declaration node)
|
||||
|
|
|
@ -9,6 +9,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import std.algorithm : canFind;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
void doNothing(string, size_t, size_t, string, bool) {}
|
||||
|
||||
|
@ -16,9 +17,9 @@ class EnumArrayLiteralCheck : BaseAnalyzer
|
|||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
bool looking = false;
|
||||
|
|
|
@ -10,6 +10,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
/**
|
||||
* Checks for use of the deprecated floating point comparison operators.
|
||||
|
@ -20,9 +21,9 @@ class FloatOperatorCheck : BaseAnalyzer
|
|||
|
||||
enum string KEY = "dscanner.deprecated.floating_point_operators";
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const RelExpression r)
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
|
||||
module analysis.function_attributes;
|
||||
|
||||
import analysis.base;
|
||||
import std.d.ast;
|
||||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
|
||||
import std.stdio;
|
||||
import dsymbol.scope_;
|
||||
|
||||
/**
|
||||
* Prefer
|
||||
|
@ -25,9 +25,9 @@ class FunctionAttributeCheck : BaseAnalyzer
|
|||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const InterfaceDeclaration dec)
|
||||
|
|
|
@ -8,15 +8,14 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import std.d.formatter;
|
||||
import analysis.base;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
class IfStatementCheck : BaseAnalyzer
|
||||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
import std.container.binaryheap : heapify;
|
||||
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const IfStatement ifStatement)
|
||||
|
|
|
@ -6,12 +6,11 @@
|
|||
module analysis.ifelsesame;
|
||||
|
||||
import std.stdio;
|
||||
|
||||
import std.d.ast;
|
||||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
/**
|
||||
* Checks for duplicated code in conditional and logical expressions.
|
||||
|
@ -25,9 +24,9 @@ class IfElseSameCheck : BaseAnalyzer
|
|||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const IfStatement ifStatement)
|
||||
|
|
|
@ -11,6 +11,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -20,9 +21,9 @@ class LengthSubtractionCheck : BaseAnalyzer
|
|||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const AddExpression addExpression)
|
||||
|
|
|
@ -10,6 +10,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_;
|
||||
|
||||
/**
|
||||
* Checks for local imports that import all symbols.
|
||||
|
@ -22,9 +23,9 @@ class LocalImportCheck : BaseAnalyzer
|
|||
/**
|
||||
* Construct with the given file name.
|
||||
*/
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
mixin visitThing!StructBody;
|
||||
|
|
|
@ -10,6 +10,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_;
|
||||
|
||||
/**
|
||||
* Checks for code with confusing && and || operator precedence
|
||||
|
@ -24,9 +25,9 @@ class LogicPrecedenceCheck : BaseAnalyzer
|
|||
|
||||
enum string KEY = "dscanner.confusing.logical_precedence";
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const OrOrExpression orOr)
|
||||
|
|
56
src/analysis/mismatched_args.d
Normal file
56
src/analysis/mismatched_args.d
Normal file
|
@ -0,0 +1,56 @@
|
|||
module analysis.mismatched_args;
|
||||
|
||||
struct ArgMismatch
|
||||
{
|
||||
size_t argIndex;
|
||||
size_t paramIndex;
|
||||
}
|
||||
|
||||
ArgMismatch[] compareArgsToParams(const string[] params, const string[] args) pure
|
||||
in
|
||||
{
|
||||
assert(args.length == params.length);
|
||||
}
|
||||
body
|
||||
{
|
||||
ArgMismatch[] retVal;
|
||||
foreach (i, arg; args)
|
||||
{
|
||||
if (arg is null || arg == params[i])
|
||||
continue;
|
||||
foreach (j, param; params)
|
||||
if (param == arg)
|
||||
retVal ~= ArgMismatch(i, j);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
string createWarningFromMismatch(ref const ArgMismatch mismatch, const string commonName) pure
|
||||
{
|
||||
import std.format : format;
|
||||
|
||||
return "Argument %d is named '%s', but this is the name of parameter %d".format(
|
||||
mismatch.argIndex + 1, commonName, mismatch.paramIndex + 1);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
{
|
||||
string[] args = ["a", "b", "c"];
|
||||
string[] params = ["a", "b", "c"];
|
||||
immutable res = compareArgsToParams(params, args);
|
||||
assert(res == []);
|
||||
}
|
||||
{
|
||||
string[] args = ["a", "c", "b"];
|
||||
string[] params = ["a", "b", "c"];
|
||||
immutable res = compareArgsToParams(params, args);
|
||||
assert(res == [ArgMismatch(1, 2), ArgMismatch(2, 1)]);
|
||||
}
|
||||
{
|
||||
string[] args = ["a", "c", "b"];
|
||||
string[] params = ["alpha", "bravo", "c"];
|
||||
immutable res = compareArgsToParams(params, args);
|
||||
assert(res == [ArgMismatch(1, 2)]);
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
/**
|
||||
* Checks for long and hard-to-read number literals
|
||||
|
@ -23,9 +24,9 @@ public:
|
|||
/**
|
||||
* Constructs the style checker with the given file name.
|
||||
*/
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const Token t)
|
||||
|
|
|
@ -11,6 +11,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
/**
|
||||
* Checks that opEquals, opCmp, toHash, and toString are either const,
|
||||
|
@ -20,9 +21,9 @@ class ObjectConstCheck : BaseAnalyzer
|
|||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
mixin visitTemplate!ClassDeclaration;
|
||||
|
|
|
@ -10,6 +10,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
/**
|
||||
* Checks for when a class/struct has the method opEquals without toHash, or
|
||||
|
@ -19,9 +20,9 @@ class OpEqualsWithoutToHashCheck : BaseAnalyzer
|
|||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const ClassDeclaration node)
|
||||
|
|
|
@ -10,6 +10,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -30,9 +31,9 @@ class PokemonExceptionCheck : BaseAnalyzer
|
|||
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const LastCatch lc)
|
||||
|
|
|
@ -10,6 +10,7 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
/**
|
||||
* Checks for .. expressions where the left side is larger than the right. This
|
||||
|
@ -26,9 +27,9 @@ class BackwardsRangeCheck : BaseAnalyzer
|
|||
* Params:
|
||||
* fileName = the name of the file being analyzed
|
||||
*/
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const ForeachStatement foreachStatement)
|
||||
|
@ -56,7 +57,7 @@ class BackwardsRangeCheck : BaseAnalyzer
|
|||
|
||||
override void visit(const AddExpression add)
|
||||
{
|
||||
auto s = state;
|
||||
immutable s = state;
|
||||
state = State.ignore;
|
||||
add.accept(this);
|
||||
state = s;
|
||||
|
|
|
@ -8,14 +8,15 @@ module analysis.redundant_parens;
|
|||
import std.d.ast;
|
||||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
class RedundantParenCheck : BaseAnalyzer
|
||||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const IfStatement statement)
|
||||
|
|
|
@ -14,6 +14,8 @@ import std.array;
|
|||
import std.d.lexer;
|
||||
import std.d.parser;
|
||||
import std.d.ast;
|
||||
import std.allocator : CAllocatorImpl;
|
||||
import std.typecons:scoped;
|
||||
|
||||
import analysis.config;
|
||||
import analysis.base;
|
||||
|
@ -44,6 +46,11 @@ import analysis.unmodified;
|
|||
import analysis.if_statements;
|
||||
import analysis.redundant_parens;
|
||||
|
||||
import memory.allocators:BlockAllocator;
|
||||
|
||||
import dsymbol.scope_;
|
||||
import dsymbol.conversion;
|
||||
|
||||
bool first = true;
|
||||
|
||||
void messageFunction(string fileName, size_t line, size_t column, string message,
|
||||
|
@ -166,33 +173,36 @@ MessageSet analyze(string fileName, const Module m,
|
|||
if (!staticAnalyze)
|
||||
return null;
|
||||
|
||||
auto allocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 16)))();
|
||||
const(Scope)* moduleScope = generateAutocompleteTrees(m, allocator);
|
||||
|
||||
BaseAnalyzer[] checks;
|
||||
|
||||
if (analysisConfig.style_check) checks ~= new StyleChecker(fileName);
|
||||
if (analysisConfig.enum_array_literal_check) checks ~= new EnumArrayLiteralCheck(fileName);
|
||||
if (analysisConfig.exception_check) checks ~= new PokemonExceptionCheck(fileName);
|
||||
if (analysisConfig.delete_check) checks ~= new DeleteCheck(fileName);
|
||||
if (analysisConfig.float_operator_check) checks ~= new FloatOperatorCheck(fileName);
|
||||
if (analysisConfig.number_style_check) checks ~= new NumberStyleCheck(fileName);
|
||||
if (analysisConfig.object_const_check) checks ~= new ObjectConstCheck(fileName);
|
||||
if (analysisConfig.backwards_range_check) checks ~= new BackwardsRangeCheck(fileName);
|
||||
if (analysisConfig.if_else_same_check) checks ~= new IfElseSameCheck(fileName);
|
||||
if (analysisConfig.constructor_check) checks ~= new ConstructorCheck(fileName);
|
||||
if (analysisConfig.unused_label_check) checks ~= new UnusedLabelCheck(fileName);
|
||||
if (analysisConfig.unused_variable_check) checks ~= new UnusedVariableCheck(fileName);
|
||||
if (analysisConfig.duplicate_attribute) checks ~= new DuplicateAttributeCheck(fileName);
|
||||
if (analysisConfig.opequals_tohash_check) checks ~= new OpEqualsWithoutToHashCheck(fileName);
|
||||
if (analysisConfig.length_subtraction_check) checks ~= new LengthSubtractionCheck(fileName);
|
||||
if (analysisConfig.builtin_property_names_check) checks ~= new BuiltinPropertyNameCheck(fileName);
|
||||
if (analysisConfig.asm_style_check) checks ~= new AsmStyleCheck(fileName);
|
||||
if (analysisConfig.logical_precedence_check) checks ~= new LogicPrecedenceCheck(fileName);
|
||||
if (analysisConfig.undocumented_declaration_check) checks ~= new UndocumentedDeclarationCheck(fileName);
|
||||
if (analysisConfig.function_attribute_check) checks ~= new FunctionAttributeCheck(fileName);
|
||||
if (analysisConfig.comma_expression_check) checks ~= new CommaExpressionCheck(fileName);
|
||||
if (analysisConfig.local_import_check) checks ~= new LocalImportCheck(fileName);
|
||||
if (analysisConfig.could_be_immutable_check) checks ~= new UnmodifiedFinder(fileName);
|
||||
if (analysisConfig.redundant_parens_check) checks ~= new RedundantParenCheck(fileName);
|
||||
version(none) if (analysisConfig.redundant_if_check) checks ~= new IfStatementCheck(fileName);
|
||||
if (analysisConfig.style_check) checks ~= new StyleChecker(fileName, moduleScope);
|
||||
if (analysisConfig.enum_array_literal_check) checks ~= new EnumArrayLiteralCheck(fileName, moduleScope);
|
||||
if (analysisConfig.exception_check) checks ~= new PokemonExceptionCheck(fileName, moduleScope);
|
||||
if (analysisConfig.delete_check) checks ~= new DeleteCheck(fileName, moduleScope);
|
||||
if (analysisConfig.float_operator_check) checks ~= new FloatOperatorCheck(fileName, moduleScope);
|
||||
if (analysisConfig.number_style_check) checks ~= new NumberStyleCheck(fileName, moduleScope);
|
||||
if (analysisConfig.object_const_check) checks ~= new ObjectConstCheck(fileName, moduleScope);
|
||||
if (analysisConfig.backwards_range_check) checks ~= new BackwardsRangeCheck(fileName, moduleScope);
|
||||
if (analysisConfig.if_else_same_check) checks ~= new IfElseSameCheck(fileName, moduleScope);
|
||||
if (analysisConfig.constructor_check) checks ~= new ConstructorCheck(fileName, moduleScope);
|
||||
if (analysisConfig.unused_label_check) checks ~= new UnusedLabelCheck(fileName, moduleScope);
|
||||
if (analysisConfig.unused_variable_check) checks ~= new UnusedVariableCheck(fileName, moduleScope);
|
||||
if (analysisConfig.duplicate_attribute) checks ~= new DuplicateAttributeCheck(fileName, moduleScope);
|
||||
if (analysisConfig.opequals_tohash_check) checks ~= new OpEqualsWithoutToHashCheck(fileName, moduleScope);
|
||||
if (analysisConfig.length_subtraction_check) checks ~= new LengthSubtractionCheck(fileName, moduleScope);
|
||||
if (analysisConfig.builtin_property_names_check) checks ~= new BuiltinPropertyNameCheck(fileName, moduleScope);
|
||||
if (analysisConfig.asm_style_check) checks ~= new AsmStyleCheck(fileName, moduleScope);
|
||||
if (analysisConfig.logical_precedence_check) checks ~= new LogicPrecedenceCheck(fileName, moduleScope);
|
||||
if (analysisConfig.undocumented_declaration_check) checks ~= new UndocumentedDeclarationCheck(fileName, moduleScope);
|
||||
if (analysisConfig.function_attribute_check) checks ~= new FunctionAttributeCheck(fileName, moduleScope);
|
||||
if (analysisConfig.comma_expression_check) checks ~= new CommaExpressionCheck(fileName, moduleScope);
|
||||
if (analysisConfig.local_import_check) checks ~= new LocalImportCheck(fileName, moduleScope);
|
||||
if (analysisConfig.could_be_immutable_check) checks ~= new UnmodifiedFinder(fileName, moduleScope);
|
||||
if (analysisConfig.redundant_parens_check) checks ~= new RedundantParenCheck(fileName, moduleScope);
|
||||
version(none) if (analysisConfig.redundant_if_check) checks ~= new IfStatementCheck(fileName, moduleScope);
|
||||
|
||||
foreach (check; checks)
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@ class StatsCollector : BaseAnalyzer
|
|||
|
||||
this(string fileName)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, null);
|
||||
}
|
||||
|
||||
override void visit(const Statement statement)
|
||||
|
|
|
@ -13,8 +13,8 @@ import std.array;
|
|||
import std.conv;
|
||||
import std.format;
|
||||
import analysis.helpers;
|
||||
|
||||
import analysis.base;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
class StyleChecker : BaseAnalyzer
|
||||
{
|
||||
|
@ -25,9 +25,9 @@ class StyleChecker : BaseAnalyzer
|
|||
enum string moduleNameRegex = `^[\p{Ll}_\d]+$`;
|
||||
enum string KEY = "dscanner.style.phobos_naming_convention";
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const ModuleDeclaration dec)
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
module analysis.undocumented;
|
||||
|
||||
import analysis.base;
|
||||
import dsymbol.scope_ : Scope;
|
||||
import std.d.ast;
|
||||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
|
||||
import std.stdio;
|
||||
|
||||
/**
|
||||
|
@ -19,9 +19,9 @@ class UndocumentedDeclarationCheck : BaseAnalyzer
|
|||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const Module mod)
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
module analysis.unmodified;
|
||||
|
||||
import analysis.base;
|
||||
import dsymbol.scope_ : Scope;
|
||||
import std.container;
|
||||
import std.d.ast;
|
||||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
|
||||
/**
|
||||
* Checks for variables that could have been declared const or immutable
|
||||
|
@ -17,9 +18,9 @@ class UnmodifiedFinder:BaseAnalyzer
|
|||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
///
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
override void visit(const Module mod)
|
||||
|
@ -41,7 +42,7 @@ class UnmodifiedFinder:BaseAnalyzer
|
|||
override void visit(const StructBody structBody)
|
||||
{
|
||||
pushScope();
|
||||
auto oldBlockStatementDepth = blockStatementDepth;
|
||||
immutable oldBlockStatementDepth = blockStatementDepth;
|
||||
blockStatementDepth = 0;
|
||||
structBody.accept(this);
|
||||
blockStatementDepth = oldBlockStatementDepth;
|
||||
|
|
|
@ -10,6 +10,7 @@ import std.d.lexer;
|
|||
import analysis.base;
|
||||
import std.container;
|
||||
import std.regex : Regex, regex, matchAll;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
/**
|
||||
* Checks for unused variables.
|
||||
|
@ -22,9 +23,9 @@ class UnusedVariableCheck : BaseAnalyzer
|
|||
* Params:
|
||||
* fileName = the name of the file being analyzed
|
||||
*/
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
re = regex("[\\p{Alphabetic}_][\\w_]*");
|
||||
}
|
||||
|
||||
|
|
|
@ -9,14 +9,15 @@ import std.d.ast;
|
|||
import std.d.lexer;
|
||||
import analysis.base;
|
||||
import analysis.helpers;
|
||||
import dsymbol.scope_ : Scope;
|
||||
|
||||
class UnusedLabelCheck : BaseAnalyzer
|
||||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
this(string fileName, const(Scope)* sc)
|
||||
{
|
||||
super(fileName);
|
||||
super(fileName, sc);
|
||||
}
|
||||
|
||||
static struct Label
|
||||
|
|
16
src/main.d
16
src/main.d
|
@ -1,4 +1,4 @@
|
|||
// Copyright Brian Schott (Hackerpilot) 2012.
|
||||
// Copyright Brian Schott (Hackerpilot) 2012-2015.
|
||||
// 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)
|
||||
|
@ -31,6 +31,8 @@ import dscanner_version;
|
|||
|
||||
import inifiled;
|
||||
|
||||
import dsymbol.modulecache;
|
||||
|
||||
int main(string[] args)
|
||||
{
|
||||
version (unittest)
|
||||
|
@ -65,6 +67,7 @@ int run(string[] args)
|
|||
string configLocation;
|
||||
bool printVersion;
|
||||
bool explore;
|
||||
string[] importPaths;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -75,7 +78,7 @@ int run(string[] args)
|
|||
"ast|xml", &ast, "imports|i", &imports, "outline|o", &outline,
|
||||
"tokenDump", &tokenDump, "styleCheck|S", &styleCheck,
|
||||
"defaultConfig", &defaultConfig, "declaration|d", &symbolName,
|
||||
"config", &configLocation, "report", &report,
|
||||
"config", &configLocation, "report", &report, "I", &importPaths,
|
||||
"version", &printVersion, "muffinButton", &muffin, "explore", &explore);
|
||||
}
|
||||
catch (ConvException e)
|
||||
|
@ -121,7 +124,13 @@ int run(string[] args)
|
|||
return 0;
|
||||
}
|
||||
|
||||
auto optionCount = count!"a"([sloc, highlight, ctags, tokenCount,
|
||||
const(string[]) absImportPaths = importPaths.map!(
|
||||
a => a.absolutePath().buildNormalizedPath()).array();
|
||||
|
||||
if (absImportPaths.length)
|
||||
ModuleCache.addImportPaths(absImportPaths);
|
||||
|
||||
immutable optionCount = count!"a"([sloc, highlight, ctags, tokenCount,
|
||||
syntaxCheck, ast, imports, outline, tokenDump, styleCheck, defaultConfig,
|
||||
report, symbolName !is null, etags, etagsAll]);
|
||||
if (optionCount > 1)
|
||||
|
@ -274,7 +283,6 @@ int run(string[] args)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
string[] expandArgs(string[] args)
|
||||
{
|
||||
// isFile can throw if it's a broken symlink.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue