D-scanner es una herramienta para analizar el código fuente D
Primero asegúrese de tener todo el código fuente. Ejecute git submodule update --init --recursive después de clonar el proyecto.
Para construir d-scanner, ejecute make (o el archivo build.bat en Windows). El tiempo de construcción puede ser bastante largo con el indicador de línea en versiones frontales mayores de 2.066, por lo que es posible que desee eliminarlo del script de compilación. El Makefile tiene objetivos "LDC" y "GDC" si prefiere compilar con uno de estos compiladores en lugar de DMD. Para instalar, simplemente coloque el binario generado (en la carpeta "bin") en algún lugar de su ruta $.
Las pruebas no funcionan con DUB. En Linux u OSX, ejecute las pruebas con make test . En Windows ejecuta las pruebas con build.bat test .
> dub fetch dscanner && dub run dscannerCon Docker no se requiere instalación:
docker run --rm -v $( pwd ) :/src dlangcommunity/dscannerLos siguientes ejemplos suponen que estamos analizando un archivo simple llamado helloworld.d
import std.stdio ;
void main ( string [] args)
{
writeln( " Hello World " );
}Usar
dscanner lint source/para ver una lista de problemas legible por humanos.
Los tipos de diagnóstico se pueden habilitar / deshabilitar utilizando un archivo de configuración, consulte el archivo --config argumento / dscanner.ini para obtener más información. Consejo: algunos IDE que integran D-Scanner pueden tener ayudantes para configurar los diagnósticos o ayudar a generar el archivo dscanner.ini.
Usar
dscanner fix source/ Para solucionar interactivamente todos los problemas reparables dentro del directorio de origen. Llame con --applySingle para aplicar automáticamente correcciones que no tienen múltiples soluciones automáticas.
Muchos editores D ya se envían con D-Scanner.
Para una salida de parsable CLI / herramienta, use
dscanner -S source/
# or
dscanner --report source/ El interruptor --report incluye toda la información, además de los autofijos baratos para calcular las autofijos que ya se resuelven con anticipación, así como los nombres para las autofijos que deben resolverse utilizando el interruptor --resolveMessage como se describe a continuación.
También puede especificar formatos personalizados usando -f / --errorFormat , donde también hay formatos incorporados para acciones de GitHub:
# 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/Para resolver soluciones de problemas automáticos para un uso de ubicación determinada
# 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 stdinSalidas 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" : " " },
]
}
]Algoritmo para aplicar reemplazos:
foreach_reverse (r; replacements)
codeBytes = codeBytes[ 0 .. r.range[ 0 ]] ~ r.newText ~ codeBytes[r.range[ 1 ] .. $]; Los reemplazos no se superponen, ordenados por range[0] en orden ascendente. Al combinar múltiples reemplazos diferentes, primero debe ordenarlos por range[0] para aplicar utilizando el algoritmo anterior.
La opción "-tokencount" o "-t" imprime el número de tokens en el archivo dado
$ dscanner --tokenCount helloworld.d
20
La opción "--imports" o "-i" imprime una lista de módulos importados por el archivo fuente dado.
$ dscanner --imports helloworld.d
std.stdio
Pasar argumentos "-i" (ubicaciones de importación) hará que D-scanner también intente resolver las ubicaciones de los módulos importados.
$ 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
Recuerde pasar el mapa de las ubicaciones de importación cuando 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
La opción "-RecursiveImports" es similar a "-Imports", excepto que enumera las importaciones de importaciones (y así sucesivamente) de manera recursiva. La opción de importación recursiva requiere que se especifiquen las rutas de importación para que funcionen correctamente.
Limitaciones:
version o static if .La opción "--SyntaxCheck" o "-S" imprime una lista de cualquier error o advertencia que se encuentre mientras levanta o analiza el archivo de origen dado. No hace ningún análisis semántico y no compila el código. El formato de los errores o advertencias se puede configurar con la opción "--Errorformat" o "-f".
La opción "--stylecheck" o "-s" ejecuta algunas verificaciones básicas de análisis estático en los archivos de origen dados, las fuentes contenidas en las carpetas dadas o las fuentes contenidas en el directorio de trabajo actual (cuando no se suministra nada). El formato de los errores o advertencias se puede configurar con la opción "--Errorformat" o "-f".
Las verificaciones estáticas en las pruebas unitarias pueden producir advertencias irrelevantes. Por ejemplo, es legítimo declarar una variable que no se usa si el objetivo es verificar que una función templatizada pueda instanciarse por inferencia del tipo de esta variable. Para evitar estos casos, es posible aprobar la opción "-skiptests".
Por defecto, todas las verificaciones están habilitadas. Los controles individuales se pueden habilitar o deshabilitar utilizando un archivo de configuración. Tal archivo se puede colocar, por ejemplo, es el directorio raíz de su proyecto. Ejecutar dscanner --defaultConfig generará un archivo de configuración predeterminado e imprimirá la ubicación del archivo. También puede especificar la ruta a un archivo de configuración utilizando la opción "--Config" si desea anular la configuración predeterminada o local.
Para cada verificación, son posibles tres valores:
"disabled" : el cheque no se realiza."enabled" : se realiza el cheque."skip-unittest" : la verificación se realiza pero no en las pruebas unitarias.Cualquier otro valor desactiva un cheque.
Tenga en cuenta que la opción "--skipTests" es el equivalente a cambiar cada verificación "enabled" mediante una verificación "skip-unittest" .
max_line_length .final , pero en este contexto es un NOOP.@trusted no se aplica a un alcance completo. Confiar en todo un alcance puede ser un problema cuando se agregan nuevas declaraciones y si no se verifican manualmente para ser confiables.if cambia case , bucle, && , || , ?: throw , catch , return , break , continue , goto y función literal) Vea esta lista de problemas abiertos para la lista de deseos.
La opción "-Informar" escribe un informe JSON en el documento de verificación de análisis estático anterior a la salida estándar. Este archivo generalmente es utilizado por el complemento D para Sonarqube ubicado aquí.
Uso de la opción "-Se puede crear un informe de datos genérico compatible con el formato de datos genéricos respaldado por el formato genérico de problemas genéricos admitido.
$ dscanner --reportFormat sonarQubeGenericIssueData . > sonar-generic-issue-data.json
Referencia al informe del nombre de archivo en sonar-project.properties utilizando la clave "sonar.externalissuesreportpaths"
sonar.externalIssuesReportPaths=sonar-generic-issue-data.json
ACK, GREP y el buscador de plata son útiles para encontrar usos de símbolos, pero su relación señal / ruido no es muy buena al buscar la declaración de un símbolo. Las opciones "--Declaración" o "-d" le permiten buscar una declaración de símbolos. Por ejemplo:
$ dscanner -d TokenStructure
./libdparse/src/std/lexer.d(248:8)
La opción "--sloc" o "-l" imprime el número de líneas de código en el archivo. En lugar de simplemente imprimir el número de saltos de línea, esto cuenta el número de semicolon, mientras que, si, do, de lo contrario, cambia, for, foreach, foreach_reverse, predeterminado y tokens de casos en el archivo.
$ ./dscanner --sloc helloworld.d
2
La opción "-Highlight" imprime el archivo de origen dado como HTML con sintaxis a la salida estándar. El estilo CSS utiliza el esquema de color solarizado de forma predeterminada, pero se puede personalizar utilizando la opción "THEME".
Los siguientes temas están disponibles:
solarized
solarized-dark
gruvbox
gruvbox-dark
No hay ejemplo. Ocuparía demasiado espacio
La opción "-ctags" o "-c" genera información CTAGS y la escribe en la salida estándar. Los argumentos de directorio se escanean recursivamente para archivos .d y .di .
$ 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
La salida de CTAGS usa los siguientes tipos de etiqueta:
Puede encontrar más información sobre el formato CTAGS aquí.
Las opciones --etags , -e y --etagsAll son similares a --ctags excepto que se genera un archivo de etiquetas compatible con EMACS. La opción --etagsAll genera etiquetas para declaraciones privadas y de paquetes además de lo que --etags y -e generan.
La opción "Ooutline" analiza el archivo fuente D dado y escribe un esquema simple de las declaraciones del archivo a STDOUT.
Si se encuentra un archivo dscanner.ini en el directorio de trabajo o cualquiera de sus padres, anula cualquier otro archivo de configuración.
Como ubicación final, D-Scanner usa el archivo de configuración dado en $HOME/.config/dscanner/dscanner.ini . Ejecutar --defaultConfig para regenerarlo.
La opción --config permite usar una ruta de archivo de configuración personalizada.
Las opciones "--ast" o "--xml" arrojarán el árbol de sintaxis abstracto completo del archivo de origen dado a la salida estándar en formato XML.
$ 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 >Para una salida más legible, vaya al comando a través de xmllint utilizando su interruptor de formato.
$ dscanner --ast helloworld.d | xmllint --format -
Es posible crear una nueva sección analysis.config.ModuleFilters en dscanner.ini . En esta sección opcional, se puede especificar una lista de selectores de inclusión y exclusión separada por comas para cada verificación en la que se debe aplicar el filtrado selectivo. Estos selectores dados coinciden con el nombre del módulo y las coincidencias parciales ( std. O .foo. ) Son posibles. Además, todos los selectores deben comenzar con + (inclusión) o - (exclusión). Los selectores de exclusión tienen prioridad sobre todos los operadores de inclusión. Por supuesto, para cada verificación, un conjunto selector diferente puede dar:
[analysis.config.ModuleFilters]
final_attribute_check = " +std.foo,+std.bar "
useless_initializer = " -std. "Algunos ejemplos:
+std. : Incluye todos los módulos que coinciden con std.+std.bitmanip,+std.json : aplica la verificación solo para estos dos módulos-std.bitmanip,-std.json : aplica la verificación de todos los módulos, pero estos dos+.bar : incluye todos los módulos coincidentes .bar (por ejemplo, foo.bar , abcbarros )-etc. : Excluye todos los módulos de .etc+std,-std.internal : incluye toda std , excepto los módulos internos