A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/dlang-community/D-Scanner below:

dlang-community/D-Scanner: Swiss-army knife for D source code

D-Scanner is a tool for analyzing D source code

First make sure that you have all the source code. Run git submodule update --init --recursive after cloning the project.

To build D-Scanner, run make (or the build.bat file on Windows). The build time can be rather long with the -inline flag on front-end versions older than 2.066, so you may wish to remove it from the build script. The makefile has "ldc" and "gdc" targets if you'd prefer to compile with one of these compilers instead of DMD. To install, simply place the generated binary (in the "bin" folder) somewhere on your $PATH.

Testing does not work with DUB. Under linux or OSX run the tests with make test. Under Windows run the tests with build.bat test.

> dub fetch dscanner && dub run dscanner

With Docker no installation is required:

docker run --rm -v $(pwd):/src dlangcommunity/dscanner

The following examples assume that we are analyzing a simple file called helloworld.d

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

Use

to view a human readable list of issues.

Diagnostic types can be enabled/disabled using a configuration file, check out the --config argument / dscanner.ini file for more info. Tip: some IDEs that integrate D-Scanner may have helpers to configure the diagnostics or help generate the dscanner.ini file.

Use

to interactively fix all fixable issues within the source directory. Call with --applySingle to automatically apply fixes that don't have multiple automatic solutions.

Many D editors already ship with D-Scanner.

For a CLI / tool parsable output use either

dscanner -S source/
# or
dscanner --report source/

The --report switch includes all information, plus cheap to compute autofixes that are already resolved ahead of time, as well as the names for the autofixes that need to be resolved using the --resolveMessage switch like described below.

You can also specify custom formats using -f / --errorFormat, where there are also built-in formats for GitHub Actions:

# for GitHub actions: (automatically adds annotations to files in PRs)
dscanner -S -f github source/
# custom format:
dscanner -S -f '{filepath}({line}:{column})[{type}]: {message}' source/

To resolve automatic issue fixes for a given location use

# collecting automatic issue fixes
# --resolveMessage <line>:<column> <filename>
dscanner --resolveMessage 11:3 file.d
# --resolveMessage b<byteIndex> <filename>
dscanner --resolveMessage b512 file.d
# <filename> may be omitted to read from stdin

outputs JSON:

// list of available auto-fixes at the given location
[
	{
		"name": "Make function const",
		// byte range `[start, end)` what code to replace
		// this is sorted by range[0]
		"replacements": [
			// replace: range[0] < range[1], newText != ""
			{"range": [10, 14], "newText": "const "},
			// insert: range[0] == range[1], newText != ""
			{"range": [20, 20], "newText": "auto"},
			// remove: range[0] < range[1], newText == ""
			{"range": [30, 40], "newText": ""},
		]
	}
]

Algorithm to apply replacements:

foreach_reverse (r; replacements)
	codeBytes = codeBytes[0 .. r.range[0]] ~ r.newText ~ codeBytes[r.range[1] .. $];

Replacements are non-overlapping, sorted by range[0] in ascending order. When combining multiple different replacements, you first need to sort them by range[0] to apply using the algorithm above.

The "--tokenCount" or "-t" option prints the number of tokens in the given file

$ dscanner --tokenCount helloworld.d
20

The "--imports" or "-i" option prints a listing of modules imported by the given source file.

$ dscanner --imports helloworld.d
std.stdio

Passing "-I" arguments (import locations) will cause D-Scanner to also attempt to resolve the locations of the imported modules.

$ dscanner --imports helloworld.d -I ~/.dvm/compilers/dmd-2.071.1-b2/src/phobos/ -I ~/.dvm/compilers/dmd-2.071.1-b2/src/druntime/src/
/home/brian/.dvm/compilers/dmd-2.071.1-b2/src/phobos/std/stdio.d

Remember to pass map the import locations when you use Docker:

docker run --rm -v $(pwd):/src -v /usr/include/dlang/dmd:/d dlangcommunity/dscanner --imports helloworld.d -I/d
/d/std/stdio.d

The "--recursiveImports" option is similar to "--imports", except that it lists imports of imports (and so on) recursively. The recursive import option requires import paths to be specified in order to work correctly.

Limitations:

The "--syntaxCheck" or "-s" option prints a listing of any errors or warnings found while lexing or parsing the given source file. It does not do any semantic analysis and it does not compile the code. The format of the errors or warnings can be configured with the "--errorFormat" or "-f" option.

The "--styleCheck" or "-S" option runs some basic static analysis checks against the given source files, the sources contained in the given folders, or the sources contained in the current working directory (when nothing is supplied). The format of the errors or warnings can be configured with the "--errorFormat" or "-f" option.

Skip style checks in the tests

Static checks in the unit tests can produce irrelevant warnings. For example, it's legit to declare a variable that's not used if the goal is to verify that a templatized function can be instantiated by inference of the type of this variable. To avoid these cases, it's possible to pass the "--skipTests" option.

By default all checks are enabled. Individual checks can be enabled or disabled by using a configuration file. Such a file can be placed, for example, is the root directory of your project. Running dscanner --defaultConfig will generate a default configuration file and print the file's location. You can also specify the path to a configuration file by using the "--config" option if you want to override the default or the local settings.

For each check, three values are possible:

Any other value deactivates a check.

Note that the "--skipTests" option is the equivalent of changing each "enabled" check by a "skip-unittest" check.

See this list of open issues for the wishlist.

The "--report" option writes a JSON report on the static analysis checks document above to standard output. This file is usually used by the D plugin for SonarQube located here.

Using option "--reportFormat sonarQubeGenericIssueData" a report in a sonar-scanner supported Generic Issue Data format can be created.

$ dscanner --reportFormat sonarQubeGenericIssueData . > sonar-generic-issue-data.json

Reference the report filename in sonar-project.properties using key "sonar.externalIssuesReportPaths"

sonar.externalIssuesReportPaths=sonar-generic-issue-data.json

Ack, grep, and The Silver Searcher are useful for finding usages of symbols, but their signal to noise ratio is not very good when searching for a symbol's declaration. The "--declaration" or "-d" options allow you to search for a symbols declaration. For example:

$ dscanner -d TokenStructure
./libdparse/src/std/lexer.d(248:8)

The "--sloc" or "-l" option prints the number of lines of code in the file. Instead of simply printing the number of line breaks, this counts the number of semicolon, while, if, do, else, switch, for, foreach, foreach_reverse, default, and case tokens in the file.

$ ./dscanner --sloc helloworld.d
2

The "--highlight" option prints the given source file as syntax-highlighted HTML to the standard output. The CSS styling uses the Solarized color scheme by default, but can be customised using the "--theme" option.

The following themes are available:

The "--ctags" or "-c" option generates CTAGS information and writes it to the standard output. Directory arguments are scanned recursively for .d and .di files.

$ dscanner --ctags helloworld.d
!_TAG_FILE_FORMAT	2
!_TAG_FILE_SORTED	1
!_TAG_FILE_AUTHOR	Brian Schott
!_TAG_PROGRAM_URL	https://github.com/Hackerpilot/Dscanner/
main	helloworld.d	3;"	f	arity:1

CTAGS output uses the following tag kinds:

More information on the CTAGS format can be found here.

The --etags, -e, and --etagsAll options are similar to --ctags except that an Emacs-compatible tags file is generated. The --etagsAll option generates tags for private and package declarations in addition to what --etags and -e generate.

The "--outline" option parses the given D source file and writes an simple outline of the file's declarations to stdout.

If a dscanner.ini file is locate in the working directory or any of it's parents, it overrides any other configuration files.

As final location, D-Scanner uses the configuration file given in $HOME/.config/dscanner/dscanner.ini. Run --defaultConfig to regenerate it.

The --config option allows one to use a custom configuration file path.

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>

For more readable output, pipe the command through xmllint using its formatting switch.

$ dscanner --ast helloworld.d | xmllint --format -
Selecting modules for a specific check

It is possible to create a new section analysis.config.ModuleFilters in the dscanner.ini. In this optional section a comma-separated list of inclusion and exclusion selectors can be specified for every check on which selective filtering should be applied. These given selectors match on the module name and partial matches (std. or .foo.) are possible. Moreover, every selectors must begin with either + (inclusion) or - (exclusion). Exclusion selectors take precedence over all inclusion operators. Of course, for every check a different selector set can given:

[analysis.config.ModuleFilters]
final_attribute_check = "+std.foo,+std.bar"
useless_initializer = "-std."

A few examples:


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4