D-Scanner é uma ferramenta para analisar o código-fonte D
Primeiro, verifique se você tem todo o código -fonte. Run git submodule update --init --recursive após clonar o projeto.
Para construir o D-Scanner, execute o arquivo make (ou Build.bat no Windows). O tempo de construção pode demorar bastante com o sinalizador -inline nas versões front -end com mais de 2,066, portanto, você pode removê -lo do script de construção. O Makefile possui alvos "LDC" e "GDC", se você preferir compilar com um desses compiladores em vez de DMD. Para instalar, basta colocar a pasta binária gerada (na pasta "bin") em algum lugar no seu caminho $.
Os testes não funcionam com dub. Em Linux ou OSX, execute os testes com make test . Em Windows, execute os testes com build.bat test .
> dub fetch dscanner && dub run dscannerCom o Docker, nenhuma instalação é necessária:
docker run --rm -v $( pwd ) :/src dlangcommunity/dscannerOs exemplos a seguir assumem que estamos analisando um arquivo simples chamado helloworld.d
import std.stdio ;
void main ( string [] args)
{
writeln( " Hello World " );
}Usar
dscanner lint source/Para ver uma lista legível de questões humanas.
Os tipos de diagnóstico podem ser ativados / desativados usando um arquivo de configuração, consulte o arquivo --config Argument / dscanner.ini para obter mais informações. Dica: Alguns IDEs que integram o D-Scanner podem ter ajudantes para configurar o diagnóstico ou ajudar a gerar o arquivo DScanner.ini.
Usar
dscanner fix source/ Para corrigir interativamente todos os problemas corrigíveis no diretório de origem. Ligue com --applySingle para aplicar automaticamente correções que não possuem várias soluções automáticas.
Muitos editores já são enviados com D-Scanner.
Para uma saída de saída da CLI / ferramenta, use -se também
dscanner -S source/
# or
dscanner --report source/ O Switch --report inclui todas as informações, além de calcular os autofixes que já estão resolvidos com antecedência, bem como os nomes dos autofixos que precisam ser resolvidos usando o interruptor --resolveMessage como descrito abaixo.
Você também pode especificar formatos personalizados usando -f / --errorFormat , onde também existem formatos internos para ações do 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 correções de problemas automáticos para um determinado local de uso
# 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 stdinSaídas 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 substituições:
foreach_reverse (r; replacements)
codeBytes = codeBytes[ 0 .. r.range[ 0 ]] ~ r.newText ~ codeBytes[r.range[ 1 ] .. $]; As substituições são não sobrepostas, classificadas por range[0] em ordem ascendente. Ao combinar várias substituições diferentes, você primeiro precisa classificá -las por range[0] para aplicar usando o algoritmo acima.
A opção "--TokEncount" ou "-t" imprime o número de tokens no arquivo especificado
$ dscanner --tokenCount helloworld.d
20
A opção "--imports" ou "-i" imprime uma lista de módulos importados pelo arquivo de origem fornecido.
$ dscanner --imports helloworld.d
std.stdio
A passagem de argumentos "-i" (locais de importação) fará com que o D-Scanner também tente resolver os locais dos 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
Lembre -se de passar no mapa nos locais de importação quando usar o Docker:
docker run --rm -v $(pwd):/src -v /usr/include/dlang/dmd:/d dlangcommunity/dscanner --imports helloworld.d -I/d
/d/std/stdio.d
A opção "--RecursiveImports" é semelhante a "--imports", exceto que lista as importações de importações (e assim por diante) recursivamente. A opção de importação recursiva exige que os caminhos de importação sejam especificados para funcionar corretamente.
Limitações:
version ou static if .A opção "--Syntoxcheck" ou "-s" imprime uma listagem de quaisquer erros ou avisos encontrados durante o lexing ou analisar o arquivo de origem fornecido. Não faz nenhuma análise semântica e não compila o código. O formato dos erros ou avisos pode ser configurado com a opção "--erRorformat" ou "-f".
A opção "-Stychecheck" ou "-s" executa algumas verificações básicas de análise estática em relação aos arquivos de origem fornecidos, as fontes contidas nas pastas fornecidas ou as fontes contidas no diretório de trabalho atual (quando nada é fornecido). O formato dos erros ou avisos pode ser configurado com a opção "--erRorformat" ou "-f".
Verificações estáticas nos testes de unidade podem produzir avisos irrelevantes. Por exemplo, é legítimo declarar uma variável que não é usada se o objetivo é verificar se uma função templatizada pode ser instanciada pela inferência do tipo dessa variável. Para evitar esses casos, é possível passar na opção "--skiptests".
Por padrão, todas as verificações estão ativadas. Verificações individuais podem ser ativadas ou desativadas usando um arquivo de configuração. Esse arquivo pode ser colocado, por exemplo, é o diretório raiz do seu projeto. A execução dscanner --defaultConfig gerará um arquivo de configuração padrão e imprimirá a localização do arquivo. Você também pode especificar o caminho para um arquivo de configuração usando a opção "--Config" se desejar substituir o padrão ou as configurações locais.
Para cada verificação, três valores são possíveis:
"disabled" : a verificação não é executada."enabled" : a verificação é executada."skip-unittest" : a verificação é executada, mas não nos testes de unidade.Qualquer outro valor desativa um cheque.
Observe que a opção "--Skiptests" é o equivalente a alterar cada verificação "enabled" por uma verificação "skip-unittest" .
max_line_length .final é usado, mas neste contexto é um Noop.@trusted não é aplicado a um escopo inteiro. Confiar em um escopo inteiro pode ser um problema quando novas declarações são adicionadas e se não forem verificadas manualmente para serem confiáveis.goto complexidade ciclomática por função e o unittest (começa em 1, aumentado em 1 em cada um if , case , loop, && , || ?: , joh, throw , catch , return , break , continue e funcione literal) Veja esta lista de questões abertas para a lista de desejos.
A opção "-Report" grava um relatório JSON no documento de análise estática verifica acima para saída padrão. Este arquivo geralmente é usado pelo plug -in D para Sonarqube localizado aqui.
Usando a opção "--ReportFormat SonarQuBeGeNericissUDATA" Um relatório em um formato de dados genéricos de problemas genéricos suportados por Sonar-Scanner pode ser criado.
$ dscanner --reportFormat sonarQubeGenericIssueData . > sonar-generic-issue-data.json
Refere-se ao relatório FileName em Sonar-Project.Properties usando a chave "SONAR.EXTERNALISSESREPORTATHS"
sonar.externalIssuesReportPaths=sonar-generic-issue-data.json
ACK, Grep e o pesquisador de prata são úteis para encontrar usos de símbolos, mas sua relação sinal / ruído não é muito boa ao procurar a declaração de um símbolo. As opções "-Declaração" ou "-d" permitem procurar uma declaração de símbolos. Por exemplo:
$ dscanner -d TokenStructure
./libdparse/src/std/lexer.d(248:8)
A opção "--sloc" ou "-l" imprime o número de linhas de código no arquivo. Em vez de simplesmente imprimir o número de quebras de linha, isso conta o número de semicolon, enquanto, se, senão, alterne, para, foreach, foreach_reverse, inadimculting e tokens de caso no arquivo.
$ ./dscanner --sloc helloworld.d
2
A opção "-Highlight" imprime o arquivo de origem fornecido como HTML iluminado por sintaxe na saída padrão. O Styling CSS usa o esquema de cores solarizado por padrão, mas pode ser personalizado usando a opção "-Theme".
Os seguintes temas estão disponíveis:
solarized
solarized-dark
gruvbox
gruvbox-dark
Nenhum exemplo. Levaria muito espaço
A opção "-ctags" ou "-c" gera informações do CTAGS e as grava na saída padrão. Os argumentos do diretório são digitalizados recursivamente quanto a arquivos .d e .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
A saída CTAGS usa os seguintes tipos de tags:
Mais informações sobre o formato CTAGS podem ser encontradas aqui.
As opções --etags , -e e --etagsAll são semelhantes a --ctags exceto que um arquivo de tags compatível com Emacs é gerado. A opção --etagsAll gera tags para declarações privadas e de pacotes, além do que --etags e -e geram.
A opção "-Outline" analisa o arquivo de origem D fornecido e grava um esboço simples das declarações do arquivo para Stdout.
Se um arquivo dscanner.ini estiver localizado no diretório de trabalho ou em qualquer um de seus pais, ele substituirá outros arquivos de configuração.
Como localização final, o D-Scanner usa o arquivo de configuração fornecido em $HOME/.config/dscanner/dscanner.ini . Run --defaultConfig para regenerá -lo.
A opção --config permite usar um caminho de arquivo de configuração personalizado.
As opções "--ast" ou "--xml" despejarão a árvore de sintaxe abstrata completa do arquivo de origem fornecido para a saída padrão no 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 uma saída mais legível, passe o comando através do XMLLINT usando sua chave de formatação.
$ dscanner --ast helloworld.d | xmllint --format -
É possível criar uma nova seção analysis.config.ModuleFilters no dscanner.ini . Nesta seção opcional, uma lista de seletores de inclusão e exclusão separada por vírgula pode ser especificada para cada verificação em que filtragem seletiva deve ser aplicada. Esses seletores dados correspondem ao nome do módulo e correspondências parciais ( std. Ou .foo. ) São possíveis. Além disso, todos os seletores devem começar com + (inclusão) ou - (exclusão). Os seletores de exclusão têm precedência sobre todos os operadores de inclusão. Obviamente, para cada verificação, um conjunto seletor diferente pode ser dado:
[analysis.config.ModuleFilters]
final_attribute_check = " +std.foo,+std.bar "
useless_initializer = " -std. "Alguns exemplos:
+std. : Inclui todos os módulos que correspondem std.+std.bitmanip,+std.json : aplica o cheque apenas para esses dois módulos-std.bitmanip,-std.json : aplica o cheque para todos os módulos, mas esses dois+.bar : inclui todos os módulos correspondentes .bar (por exemplo, foo.bar , abcbarros )-etc. : Exclui todos os módulos de .etc+std,-std.internal : inclui std inteira, exceto os módulos internos