Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions .dscanner.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
; Configure which static analysis checks are enabled
[analysis.config.StaticAnalysisConfig]
; Check variable, class, struct, interface, union, and function names against t
; he Phobos style guide
style_check="disabled"
; Check for array literals that cause unnecessary allocation
enum_array_literal_check="enabled"
; Check for poor exception handling practices
exception_check="enabled"
; Check for use of the deprecated 'delete' keyword
delete_check="enabled"
; Check for use of the deprecated floating point operators
float_operator_check="enabled"
; Check number literals for readability
number_style_check="enabled"
; Checks that opEquals, opCmp, toHash, and toString are either const, immutable
; , or inout.
object_const_check="enabled"
; Checks for .. expressions where the left side is larger than the right.
backwards_range_check="enabled"
; Checks for if statements whose 'then' block is the same as the 'else' block
if_else_same_check="enabled"
; Checks for some problems with constructors
constructor_check="enabled"
; Checks for unused variables and function parameters
unused_variable_check="disabled"
; Checks for unused labels
unused_label_check="enabled"
; Checks for duplicate attributes
duplicate_attribute="enabled"
; Checks that opEquals and toHash are both defined or neither are defined
opequals_tohash_check="disabled"
; Checks for subtraction from .length properties
length_subtraction_check="disabled"
; Checks for methods or properties whose names conflict with built-in propertie
; s
builtin_property_names_check="enabled"
; Checks for confusing code in inline asm statements
asm_style_check="enabled"
; Checks for confusing logical operator precedence
logical_precedence_check="enabled"
; Checks for undocumented public declarations
undocumented_declaration_check="disabled"
; Checks for poor placement of function attributes
function_attribute_check="disabled"
; Checks for use of the comma operator
comma_expression_check="enabled"
; Checks for local imports that are too broad
local_import_check="enabled"
; Checks for variables that could be declared immutable
could_be_immutable_check="disabled"
; Checks for redundant expressions in if statements
redundant_if_check="enabled"
; Checks for redundant parenthesis
redundant_parens_check="enabled"
; Checks for mismatched argument and parameter names
mismatched_args_check="enabled"
; Checks for labels with the same name as variables
label_var_same_name_check="enabled"
; Checks for lines longer than 120 characters
long_line_check="disabled"
; Checks for assignment to auto-ref function parameters
auto_ref_assignment_check="enabled"
; Checks for incorrect infinite range definitions
incorrect_infinite_range_check="enabled"
; Checks for asserts that are always true
useless_assert_check="enabled"
; Check for uses of the old-style alias syntax
alias_syntax_check="enabled"
; Checks for else if that should be else static if
static_if_else_check="enabled"
; Check for unclear lambda syntax
lambda_return_check="enabled"
; Check for auto function without return statement
auto_function_check="enabled"
; Check for sortedness of imports
imports_sortedness="disabled"
; Check for explicitly annotated unittests
explicitly_annotated_unittests="disabled"
; Check for properly documented public functions (Returns, Params)
properly_documented_public_functions="disabled"
; Check for useless usage of the final attribute
final_attribute_check="enabled"
; Check for virtual calls in the class constructors
vcall_in_ctor="enabled"
; Check for useless user defined initializers
useless_initializer="enabled"
; Check allman brace style
allman_braces_check="disabled"
; Check for redundant attributes
redundant_attributes_check="enabled"
1 change: 1 addition & 0 deletions .travis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ elif [[ $DC == ldc2 ]]; then
else
git submodule update --init --recursive
make test
make lint
fi
172 changes: 90 additions & 82 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ compilers instead of DMD. To install, simply place the generated binary (in the
# Usage
The following examples assume that we are analyzing a simple file called helloworld.d

import std.stdio;
void main(string[] args)
{
writeln("Hello World");
}
```d
import std.stdio;
void main(string[] args)
{
writeln("Hello World");
}
```

### Token Count
The "--tokenCount" or "-t" option prints the number of tokens in the given file
Expand Down Expand Up @@ -131,6 +133,7 @@ Note that the "--skipTests" option is the equivalent of changing each
* Useless initializers.
* Allman brace style
* Redundant visibility attributes
* Public declarations without a documented unittest. By default disabled.

#### Wishlist

Expand Down Expand Up @@ -214,83 +217,88 @@ If a `dscanner.ini` file is locate in the working directory or any of it's paren
The "--ast" or "--xml" options will dump the complete abstract syntax tree of
the given source file to standard output in XML format.

$ dscanner --ast helloworld.d
<module>
<declaration>
<importDeclaration>
<singleImport>
<identifierChain>
<identifier>std</identifier>
<identifier>stdio</identifier>
</identifierChain>
</singleImport>
</importDeclaration>
</declaration>
<declaration>
<functionDeclaration line="3">
<name>main</name>
<type pretty="void">
<type2>
void
</type2>
</type>
<parameters>
<parameter>
<name>args</name>
<type pretty="string[]">
<type2>
<symbol>
<identifierOrTemplateChain>
<identifierOrTemplateInstance>
<identifier>string</identifier>
</identifierOrTemplateInstance>
</identifierOrTemplateChain>
</symbol>
</type2>
<typeSuffix type="[]"/>
</type>
<identifier>args</identifier>
</parameter>
</parameters>
<functionBody>
<blockStatement>
<declarationsAndStatements>
<declarationOrStatement>
<statement>
<statementNoCaseNoDefault>
<expressionStatement>
<expression>
<assignExpression>
<functionCallExpression>
<unaryExpression>
<primaryExpression>
<identifierOrTemplateInstance>
<identifier>writeln</identifier>
</identifierOrTemplateInstance>
</primaryExpression>
</unaryExpression>
<arguments>
<argumentList>
<assignExpression>
<primaryExpression>
<stringLiteral>Hello World</stringLiteral>
</primaryExpression>
</assignExpression>
</argumentList>
</arguments>
</functionCallExpression>
</assignExpression>
</expression>
</expressionStatement>
</statementNoCaseNoDefault>
</statement>
</declarationOrStatement>
</declarationsAndStatements>
</blockStatement>
</functionBody>
</functionDeclaration>
</declaration>
</module>
```sh
$ dscanner --ast helloworld.d
```

```xml
<module>
<declaration>
<importDeclaration>
<singleImport>
<identifierChain>
<identifier>std</identifier>
<identifier>stdio</identifier>
</identifierChain>
</singleImport>
</importDeclaration>
</declaration>
<declaration>
<functionDeclaration line="3">
<name>main</name>
<type pretty="void">
<type2>
void
</type2>
</type>
<parameters>
<parameter>
<name>args</name>
<type pretty="string[]">
<type2>
<symbol>
<identifierOrTemplateChain>
<identifierOrTemplateInstance>
<identifier>string</identifier>
</identifierOrTemplateInstance>
</identifierOrTemplateChain>
</symbol>
</type2>
<typeSuffix type="[]"/>
</type>
<identifier>args</identifier>
</parameter>
</parameters>
<functionBody>
<blockStatement>
<declarationsAndStatements>
<declarationOrStatement>
<statement>
<statementNoCaseNoDefault>
<expressionStatement>
<expression>
<assignExpression>
<functionCallExpression>
<unaryExpression>
<primaryExpression>
<identifierOrTemplateInstance>
<identifier>writeln</identifier>
</identifierOrTemplateInstance>
</primaryExpression>
</unaryExpression>
<arguments>
<argumentList>
<assignExpression>
<primaryExpression>
<stringLiteral>Hello World</stringLiteral>
</primaryExpression>
</assignExpression>
</argumentList>
</arguments>
</functionCallExpression>
</assignExpression>
</expression>
</expressionStatement>
</statementNoCaseNoDefault>
</statement>
</declarationOrStatement>
</declarationsAndStatements>
</blockStatement>
</functionBody>
</functionDeclaration>
</declaration>
</module>
```

For more readable output, pipe the command through [xmllint](http://xmlsoft.org/xmllint.html)
using its formatting switch.
Expand Down
3 changes: 3 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ test: githash
./bin/dscanner-unittest
rm -f bin/dscanner-unittest

lint: dmdbuild
./bin/dscanner --config .dscanner.ini --styleCheck src

clean:
rm -rf dsc
rm -rf bin
Expand Down
4 changes: 2 additions & 2 deletions src/analysis/allman.d
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ class AllManCheck : BaseAnalyzer
super(fileName, null, skipTests);
foreach (i; 1 .. tokens.length - 1)
{
auto curLine = tokens[i].line;
auto prevTokenLine = tokens[i-1].line;
const curLine = tokens[i].line;
const prevTokenLine = tokens[i-1].line;
if (tokens[i].type == tok!"{" && curLine == prevTokenLine)
{
// ignore struct initialization
Expand Down
4 changes: 2 additions & 2 deletions src/analysis/builtin_property_names.d
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ private:
{
import std.algorithm : canFind;

return builtinProperties.canFind(name);
return BuiltinProperties.canFind(name);
}

enum string[] builtinProperties = ["init", "sizeof", "mangleof", "alignof", "stringof"];
enum string[] BuiltinProperties = ["init", "sizeof", "mangleof", "alignof", "stringof"];
int depth;
}

Expand Down
3 changes: 3 additions & 0 deletions src/analysis/config.d
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ struct StaticAnalysisConfig
@INI("Check for redundant attributes")
string redundant_attributes_check = Check.enabled;

@INI("Check public declarations without a documented unittest")
string has_public_example = Check.disabled;

@INI("Module-specific filters")
ModuleFilters filters;
}
Expand Down
4 changes: 2 additions & 2 deletions src/analysis/function_attributes.d
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ class FunctionAttributeCheck : BaseAnalyzer

override void visit(const InterfaceDeclaration dec)
{
auto t = inInterface;
const t = inInterface;
inInterface = true;
dec.accept(this);
inInterface = t;
}

override void visit(const ClassDeclaration dec)
{
auto t = inInterface;
const t = inInterface;
inInterface = false;
dec.accept(this);
inInterface = t;
Expand Down
Loading