{"id":690565,"date":"2026-03-21T03:59:44","date_gmt":"2026-03-21T02:59:44","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=platform&#038;p=690565"},"modified":"2026-03-21T03:59:49","modified_gmt":"2026-03-21T02:59:49","slug":"como-ampliar-a-funcionalidade-do-qodana-adicionando-inspecoes-personalizadas-de-codigo","status":"publish","type":"platform","link":"https:\/\/blog.jetbrains.com\/pt-br\/platform\/2026\/03\/como-ampliar-a-funcionalidade-do-qodana-adicionando-inspecoes-personalizadas-de-codigo\/","title":{"rendered":"Como ampliar a funcionalidade do Qodana adicionando inspe\u00e7\u00f5es personalizadas de c\u00f3digo"},"content":{"rendered":"<p>O Qodana \u00e9 uma ferramenta de an\u00e1lise est\u00e1tica de c\u00f3digo que traz as <a href=\"https:\/\/www.jetbrains.com\/help\/idea\/code-inspection.html\" target=\"_blank\" rel=\"noreferrer noopener\">inspe\u00e7\u00f5es de c\u00f3digo<\/a> e as corre\u00e7\u00f5es r\u00e1pidas dos JetBrains IDEs para o dom\u00ednio da integra\u00e7\u00e3o cont\u00ednua. Ele pode ser executado <a href=\"https:\/\/qodana.cloud\" target=\"_blank\" rel=\"noreferrer noopener\">na nuvem<\/a> ou <a href=\"https:\/\/github.com\/JetBrains\/qodana-cli\" target=\"_blank\" rel=\"noreferrer noopener\">a partir de um container do Docker<\/a>, pode ser <a href=\"https:\/\/www.jetbrains.com\/help\/qodana\/ci.html\" target=\"_blank\" rel=\"noopener\">integrado<\/a> a pipelines de CI\/CD ou invocado a partir de um JetBrains IDE.<\/p>\n<p>O Qodana j\u00e1 oferece um conjunto impressionante de inspe\u00e7\u00f5es, mas n\u00e3o se limita ao que j\u00e1 vem instalado. Voc\u00ea pode adicionar inspe\u00e7\u00f5es personalizadas para fazer valerem caracter\u00edsticas e conven\u00e7\u00f5es espec\u00edficas de cada projeto.<\/p>\n<p>Por exemplo, imagine um projeto com uma conven\u00e7\u00e3o espec\u00edfica para o c\u00f3digo:<\/p>\n<blockquote class=\"wp-block-quote\">\n<p>Todas as classes Kotlin em um pacote <code>service<\/code> precisam ter o sufixo <code>Service<\/code>.<\/p>\n<\/blockquote>\n<p>Nesse caso, a classe <code>com.jetbrains.service.JetComponent<\/code> n\u00e3o estaria de acordo com essa conven\u00e7\u00e3o, enquanto <code>com.jetbrains.service.BrainComponentService<\/code> estaria perfeita. A seguir, criaremos um plug-in para implementar essa inspe\u00e7\u00e3o, permitindo que o Qodana fa\u00e7a valer essa conven\u00e7\u00e3o em projetos futuros.<\/p>\n<p>Podemos implementar essa conven\u00e7\u00e3o no c\u00f3digo criando uma <strong>inspe\u00e7\u00e3o de c\u00f3digo<\/strong> personalizada, envolta em um <strong>plug-in<\/strong>. Os plug-ins do Qodana s\u00e3o desenvolvidos da mesma forma que os dos JetBrains IDEs. Isso quer dizer que precisamos apenas criar um plug-in para a plataforma IntelliJ que possa ser executado no Qodana. Esta \u00e9 uma r\u00e1pida vis\u00e3o geral das etapas que realizaremos:<\/p>\n<ol>\n<li>Inicializar o projeto a partir de <a href=\"https:\/\/github.com\/JetBrains\/intellij-platform-plugin-template\" target=\"_blank\" rel=\"noreferrer noopener\">IntelliJ Platform Plugin Template<\/a>.<\/li>\n<li>Ajustar as propriedades do projeto, o descritor do plug-in e as depend\u00eancias necess\u00e1rias.<\/li>\n<li>Declarar a inspe\u00e7\u00e3o local no descritor do plug-in e implement\u00e1-la no Kotlin.<\/li>\n<li>Fazer a build do plug-in e empacot\u00e1-lo.<\/li>\n<li>No projeto de exemplo de teste, colocar o artefato do plug-in em um diret\u00f3rio apropriado.<\/li>\n<li>Ajustar o arquivo de configura\u00e7\u00f5es do Qodana.<\/li>\n<li>Executar o Qodana e examinar o relat\u00f3rio!<\/li>\n<\/ol>\n<h2 class=\"wp-block-heading\">Prepara\u00e7\u00e3o do projeto do plug-in<\/h2>\n<p>Para inicializar o projeto, visite o reposit\u00f3rio <a href=\"https:\/\/github.com\/JetBrains\/intellij-platform-gradle-plugin\" target=\"_blank\" rel=\"noreferrer noopener\">IntelliJ Platform Plugin Template<\/a> e clique no bot\u00e3o <em>Use this template<\/em> para criar um reposit\u00f3rio para o plug-in. D\u00ea a ele o nome de <code>classname-inspection-qodana-plugin<\/code>, copie a URL do projeto e abra-a no IntelliJ IDEA. Quando o projeto estiver pronto, personalize <code>gradle.properties<\/code> declarando <code>pluginGroup<\/code>, <code>pluginName<\/code> e <code>pluginRepositoryUrl<\/code>, conforme necess\u00e1rio. Lembre-se de clicar no bot\u00e3o flutuante <em>Sync Gradle Changes<\/em> para aplicar as altera\u00e7\u00f5es. Para modificar o <a href=\"https:\/\/plugins.jetbrains.com\/docs\/intellij\/plugin-configuration-file.html#idea-plugin__id\" target=\"_blank\" rel=\"noreferrer noopener\">identificador exclusivo do plug-in<\/a>, altere o elemento <code>id<\/code> no descritor <code>plugin.xml<\/code>.<\/p>\n<h3 class=\"wp-block-heading\">Declara\u00e7\u00e3o de depend\u00eancias<\/h3>\n<p>Nossa inspe\u00e7\u00e3o de c\u00f3digo tem como alvo classes Kotlin. Ent\u00e3o, precisamos adicionar o plug-in do Kotlin \u00e0s depend\u00eancias do plug-in do Qodana. O arquivo <code>gradle.properties<\/code> exige que voc\u00ea declare:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"ini\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">platformBundledPlugins = org.jetbrains.kotlin<\/pre>\n<p>Al\u00e9m disso, o descritor <code>plugin.xml<\/code> precisa conter o mesmo plug-in incorporado do Kotlin entre suas depend\u00eancias:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">org.jetbrains.kotlin<\/pre>\n<p>Mais uma vez, lembre-se de sincronizar as altera\u00e7\u00f5es com o Gradle, clicando no bot\u00e3o flutuante.<\/p>\n<p>Al\u00e9m disso, a inspe\u00e7\u00e3o de classe do Kotlin precisa ter suporte ao compilador Kotlin K2, que \u00e9 habilitado como padr\u00e3o desde a vers\u00e3o 2025.1 da plataforma IntelliJ. No descritor do plug-in, declare a extens\u00e3o <code>org.jetbrains.kotlin.supportsKotlinPluginMode<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">    \n<\/pre>\n<h3 class=\"wp-block-heading\">Cria\u00e7\u00e3o da inspe\u00e7\u00e3o de c\u00f3digo<\/h3>\n<p>O c\u00f3digo em si de qualquer inspe\u00e7\u00e3o de c\u00f3digo que tenha como alvo classes Kotlin requer tr\u00eas etapas:<\/p>\n<ol>\n<li>Declarar a extens\u00e3o <code>com.intellij.localInspection<\/code> no descritor do plug-in, juntamente com os atributos necess\u00e1rios e uma refer\u00eancia totalmente qualificada \u00e0 classe de implementa\u00e7\u00e3o.<\/li>\n<li>Criar uma classe de implementa\u00e7\u00e3o, de prefer\u00eancia em Kotlin.<\/li>\n<li>Fornecer um arquivo separado em HTML, contendo uma descri\u00e7\u00e3o da inspe\u00e7\u00e3o, diretrizes de uso e um exemplo.<\/li>\n<\/ol>\n<h4 class=\"wp-block-heading\">Declara\u00e7\u00e3o da extens\u00e3o<\/h4>\n<p>Adicione a seguinte declara\u00e7\u00e3o ao arquivo descritor <code>plugin.xml<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">    \n<\/pre>\n<p>O atributo <code>language<\/code> indica que a inspe\u00e7\u00e3o se aplica a arquivos de c\u00f3digo-fonte em Kotlin. \u00c9 importante manter a inspe\u00e7\u00e3o explicitamente habilitada, como padr\u00e3o; sen\u00e3o, o Qodana n\u00e3o a executar\u00e1. Depois, informe um atributo <code>displayName<\/code>, descritivo e leg\u00edvel por seres humanos, para ser exibido no relat\u00f3rio e nas configura\u00e7\u00f5es. O atributo <code>groupName<\/code> define a categoria da inspe\u00e7\u00e3o, mostrada tanto no relat\u00f3rio do Qodana quanto nas configura\u00e7\u00f5es do IDE. Por fim, d\u00ea um nome totalmente qualificado \u00e0 classe de implementa\u00e7\u00e3o.<\/p>\n<h4 class=\"wp-block-heading\">C\u00f3digo-fonte da inspe\u00e7\u00e3o de c\u00f3digo<\/h4>\n<p>O plug-in do Kotlin oferece uma classe \u00fatil como base para inspe\u00e7\u00f5es de Kotlin: <code>AbstractKotlinInspection<\/code>. Fa\u00e7a override do m\u00e9todo <code>buildVisitor<\/code> e forne\u00e7a uma inst\u00e2ncia do padr\u00e3o Visitor de PSI que percorre os elementos da classe Kotlin de forma type-safe. <code>classVisitor<\/code> \u00e9 uma fun\u00e7\u00e3o estilo DSL que retorna esse tipo de visitor PSI e \u00e9 invocada em qualquer classe Kotlin do projeto inspecionado.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">package org.intellij.sdk.codeInspection\n\nimport com.intellij.codeInspection.ProblemHighlightType\nimport com.intellij.codeInspection.ProblemsHolder\nimport com.intellij.psi.PsiElementVisitor\nimport org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKotlinInspection\nimport org.jetbrains.kotlin.psi.KtClass\nimport org.jetbrains.kotlin.psi.KtVisitorVoid\nimport org.jetbrains.kotlin.psi.classVisitor\n\nclass ServicePackageClassNameInspection : AbstractKotlinInspection() {\n    override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = classVisitor { klass -&gt;\n        val classNamePsi = klass.nameIdentifier ?: return@classVisitor\n        val classFqn = klass.fqName?.asString() ?: return@classVisitor\n        if (klass.packageLastComponent == \"service\" &amp;&amp; !classFqn.endsWith(\"Service\")) {\n            holder.registerProblem(\n                classNamePsi,\n                \"Class name in the 'service' package must have a 'Service' suffix\"\n            )\n        }\n    }\n\n    private val KtClass.packageLastComponent: String\n        get() = containingKtFile.packageFqName.shortName().asString()\n}<\/pre>\n<p>A subclasse do visitor extrai o nome totalmente qualificado da classe Kotlin, inspeciona o elemento de pacote mais \u00e0 direita e verifica o sufixo correspondente. Qualquer nome de classe inadequado ser\u00e1 relatado \u00e0 inst\u00e2ncia <em>ProblemsHolder<\/em> com a classe que o cont\u00e9m como elemento PSI e uma descri\u00e7\u00e3o leg\u00edvel do problema.<\/p>\n<h4 class=\"wp-block-heading\">Descri\u00e7\u00e3o da inspe\u00e7\u00e3o<\/h4>\n<p>Toda inspe\u00e7\u00e3o local precisa ser acompanhada de um arquivo de descri\u00e7\u00e3o, representada em HTML. Se voc\u00ea usar a corre\u00e7\u00e3o r\u00e1pida <em>Create description file ServicePackageClassNameInspection.html<\/em>, ser\u00e1 criado um arquivo com o nome <code>src\/main\/resources\/inspectionDescriptions\/ServicePackageClassName.html<\/code> no local apropriado. Voc\u00ea tamb\u00e9m ter\u00e1 que fornecer uma descri\u00e7\u00e3o, que ser\u00e1 mostrada no relat\u00f3rio do Qodana e nas configura\u00e7\u00f5es do IDE.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"html\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Reports class names in the <code>service<\/code> packages that lack the <code>Service<\/code> suffix.<\/pre>\n<p><b>Example:<\/b><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">\n  package com.example.foo.service\n  class SomeComponent {\n    \/* class members *\/\n  }<\/pre>\n<h2 class=\"wp-block-heading\">Build do plug-in<\/h2>\n<p>Tudo pronto \u2014 \u00e9 hora de fazer a build! Execute a tarefa <code>buildPlugin<\/code> do Gradle e veja o artefato <code>build\/distributions\/qodana-code-inspection-0.0.1.zip<\/code>, que estar\u00e1 dispon\u00edvel no diret\u00f3rio de sa\u00edda do Gradle. O arquivo JAR ser\u00e1 usado como artefato prim\u00e1rio na an\u00e1lise do Qodana.\u00a0<\/p>\n<h4 class=\"wp-block-heading\">Tenha em mente o tipo de artefato do plug-in<\/h4>\n<p>O Qodana n\u00e3o tem suporte direto a artefatos de plug-in em formato ZIP que incluam outros arquivos JAR ou depend\u00eancias de terceiros. Todo plug-in precisa ser empacotado em um s\u00f3 arquivo JAR ou descomprimido em um diret\u00f3rio espec\u00edfico.<\/p>\n<h2 class=\"wp-block-heading\">Execu\u00e7\u00e3o do Qodana em um projeto de teste<\/h2>\n<p>Vamos criar um projeto de teste em Kotlin que possamos inspecionar com o Qodana, ap\u00f3s ampli\u00e1-lo com nosso plug-in. Para executar localmente o plug-in do Qodana, certifique-se de que dois componentes de software estejam dispon\u00edveis no seu sistema:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.docker.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Docker<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/JetBrains\/qodana-cli\" target=\"_blank\" rel=\"noreferrer noopener\">Interface de linha de comando do Qodana<\/a><\/li>\n<\/ul>\n<p>Nosso projeto de teste precisa conter uma classe chamada <code>src\/main\/kotlin\/org\/intellij\/sdk\/qodana\/service\/SomeComponent.kt<\/code>, que n\u00e3o segue nossa conven\u00e7\u00e3o de c\u00f3digo, pois n\u00e3o tem o sufixo <code>Service<\/code>. H\u00e1 duas maneiras de integrar o plug-in ao Qodana:<\/p>\n<ul>\n<li>Public\u00e1-lo no JetBrains Marketplace<\/li>\n<li>Para uma implementa\u00e7\u00e3o mais r\u00e1pida, colocar o artefato em JAR do plug-in no diret\u00f3rio <code>.qodana<\/code> do seu projeto.<\/li>\n<\/ul>\n<p>Para simplificar a build, copie o arquivo <code>build\/distributions\/qodana-code-inspection-0.0.1.zip<\/code> do projeto do plug-in para o projeto de teste, como <code>.qodana\/qodana-code-inspection-0.0.1.zip<\/code>. Se o diret\u00f3rio <code>.qodana<\/code> n\u00e3o existir, crie-o primeiro. Depois, extraia o arquivo com a sua ferramenta ou programa preferido. O Qodana poder\u00e1 acessar o plug-in no diret\u00f3rio <code>build\/distributions\/qodana-code-inspection<\/code>.<\/p>\n<p>Al\u00e9m disso, o Qodana precisa ser configurado para incluir nossa inspe\u00e7\u00e3o personalizada de c\u00f3digo. Altere o arquivo <code>qodana.yaml<\/code>, no diret\u00f3rio-raiz do projeto de teste, desta forma:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">version: \"1.0\"\nlinter: qodana-jvm-community\ninclude:\n  - name: org.intellij.sdk.codeInspection.ServicePackageClassNameInspection<\/pre>\n<p>O bloco <code>include<\/code> precisa referenciar o nome totalmente qualificado da classe da inspe\u00e7\u00e3o de c\u00f3digo dispon\u00edvel no plug-in. Agora, execute o seguinte comando para executar o Qodana a partir do terminal:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">qodana scan --volume $PWD\/.qodana\/qodana-code-inspection:\/opt\/idea\/custom-plugins\/qodana-code-inspection<\/pre>\n<p>Isso baixar\u00e1 a imagem do Docker correspondente ao Qodana. Ser\u00e1 criado um container do Docker e ele ser\u00e1 executado com base na configura\u00e7\u00e3o do Qodana. Para tornar o plug-in personalizado acess\u00edvel durante a execu\u00e7\u00e3o do Qodana, monte o diret\u00f3rio do plug-in do sistema de arquivos local no diret\u00f3rio apropriado dentro do container do Docker com o Qodana. Depois de alguns minutos, o Qodana gerar\u00e1 um resumo do relat\u00f3rio e o imprimir\u00e1 na sa\u00edda-padr\u00e3o.<\/p>\n<pre class=\"EnlighterJSRAW\">Qodana - Detailed summary                                                                                                                                                                                                                \nAnalysis results: 1 problem detected                                                                                                                                                                                                     \nBy severity: High - 1                                                                                                                                                                                                                    \n-------------------------------------------------------                                                                                                                              \nName                           Severity  Problems count                                                                                                                                                             \n-------------------------------------------------------                                                                                                                              \nSDK: Discouraged class name    High      1                                                                                                                                                             \n-------------------------------------------------------<\/pre>\n<p>Abra o relat\u00f3rio completo no seu navegador:<\/p>\n<pre class=\"EnlighterJSRAW\">  Do you want to open the latest report [Y\/n]Yes\n\n!  Press Ctrl+C to stop serving the report\n\n  Showing Qodana report from http:\/\/localhost:8080\/... (10s)<\/pre>\n<p>O Qodana mostrar\u00e1 que <code>SomeComponent<\/code> n\u00e3o segue a conven\u00e7\u00e3o de c\u00f3digo especificada pela nossa inspe\u00e7\u00e3o local no plug-in.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-678097\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/02\/Qodana-Report.png\" alt=\"\" width=\"1999\" height=\"983\" \/><\/figure>\n<h4 class=\"wp-block-heading\">Dicas para execu\u00e7\u00f5es futuras<\/h4>\n<p>Se o plug-in do Qodana for modificado e tiver uma nova build, o cache do Qodana tamb\u00e9m precisar\u00e1 ser recriado. Nesse caso, use o par\u00e2metro de linha de comando <code>--clear-cache<\/code> para recarregar todas as depend\u00eancias de execu\u00e7\u00e3o do Qodana.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">qodana scan --clear-cache --volume $PWD\/.qodana\/qodana-code-inspection-0.0.1.jar:\/opt\/idea\/custom-plugins\/codeinspection.jar<\/pre>\n<h2 class=\"wp-block-heading\">Como integrar o Qodana ao seu IDE<\/h2>\n<p>O plug-in do Qodana pode ser instalado no IDE <a href=\"https:\/\/www.jetbrains.com\/help\/idea\/managing-plugins.html#install_plugin_from_disk\" target=\"_blank\" rel=\"noreferrer noopener\">a partir de um disco<\/a>. Sua inspe\u00e7\u00e3o de c\u00f3digo ser\u00e1 habilitada automaticamente e invocada para qualquer classe Kotlin de um projeto. Para verificar se isso est\u00e1 funcionando, revisite o projeto de teste, abra a classe <code>org.intellij.sdk.qodana.service.SomeComponent<\/code> e veja se o nome problem\u00e1tico da classe est\u00e1 sublinhado. Por conveni\u00eancia, ao passar o mouse sobre o nome da classe, aparecer\u00e1 o resultado da inspe\u00e7\u00e3o de c\u00f3digo, juntamente com a descri\u00e7\u00e3o do problema. Como alternativa, voc\u00ea pode abrir a janela de ferramentas <em>Problems<\/em> e localizar o alerta na lista de todos os problemas relatados por inspe\u00e7\u00f5es de c\u00f3digo.\u00a0<\/p>\n<p>Agora a inspe\u00e7\u00e3o de c\u00f3digo se comporta como qualquer inspe\u00e7\u00e3o fornecida pelo IDE. Em <em>Settings<\/em> | <em>Editor<\/em> | <em>Inspections<\/em> | <em>Kotlin<\/em>, voc\u00ea encontrar\u00e1 a inspe\u00e7\u00e3o SDK: Discouraged class name, juntamente com a descri\u00e7\u00e3o obtida do arquivo em HTML que fornecemos antes.<\/p>\n<h3 class=\"wp-block-heading\">Como executar o Qodana a partir do IDE<\/h3>\n<p>Agora que o plug-in est\u00e1 instalado, voc\u00ea tamb\u00e9m pode executar o Qodana a partir do seu IDE. Na janela de ferramentas <em>Problems<\/em>, v\u00e1 at\u00e9 a aba <em>Qodana<\/em> e clique no bot\u00e3o <em>Try Locally<\/em>. O Qodana ser\u00e1 executado com a configura\u00e7\u00e3o do arquivo <code>qodana.yaml<\/code>. O relat\u00f3rio do Qodana poder\u00e1 ser encontrado diretamente na janela de ferramentas.\u00a0<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-678108\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/02\/Qodana-Report-analysis.png\" alt=\"\" width=\"1116\" height=\"566\" \/><\/figure>\n<h2 class=\"wp-block-heading\">Os plug-ins do Qodana e o JetBrains Marketplace<\/h2>\n<p>Plug-ins de inspe\u00e7\u00f5es personalizadas que tenham tido builds corretas e testes apropriados podem ser <a href=\"https:\/\/plugins.jetbrains.com\/docs\/marketplace\/publishing-and-listing-your-plugin.html\" target=\"_blank\" rel=\"noreferrer noopener\">publicados no JetBrains Marketplace<\/a>, eliminando a necessidade de servi-los a partir do diret\u00f3rio <code>.qodana<\/code>. Voc\u00ea s\u00f3 precisa se certificar de que a configura\u00e7\u00e3o do Qodana especifique um identificador p\u00fablico de plug-in igual \u00e0 do elemento <code><mark class=\"has-inline-color\" style=\"color: #1c8212;\">id<\/mark><\/code> do descritor do plug-in.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">version: \"1.0\"\nlinter: qodana-jvm-community\nplugins: \n  - id: com.github.novotnyr.qodanacodeinspection<\/pre>\n<p>O comando <code>scan<\/code> do Qodana fica mais simples, pois n\u00e3o \u00e9 mais necess\u00e1rio montar o diret\u00f3rio <code>.qodana. <\/code><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">qodana scan<\/pre>\n<p>O Qodana baixar\u00e1 o plug-in do JetBrains Marketplace e executar\u00e1 todas as suas inspe\u00e7\u00f5es, gerando tanto uma sa\u00edda no console quanto um relat\u00f3rio em HTML, que poder\u00e1 ser exibido em um navegador de Web.<\/p>\n<h2 class=\"wp-block-heading\">Resumo<\/h2>\n<p>Aqui criamos um plug-in para o Qodana com uma inspe\u00e7\u00e3o de c\u00f3digo que verifica uma conven\u00e7\u00e3o espec\u00edfica do c\u00f3digo. H\u00e1 diversas maneiras de executar esse plug-in:<\/p>\n<ul>\n<li>Como um arquivo JAR colocado no diret\u00f3rio <code>.qodana<\/code> e inclu\u00eddo no arquivo &#8220;qodana.yaml&#8221;.<\/li>\n<li>Como uma refer\u00eancia a um plug-in dispon\u00edvel publicamente no JetBrains Marketplace.<\/li>\n<li>Como um arquivo JAR instalado no IDE, com a inspe\u00e7\u00e3o sendo aplicada em uma execu\u00e7\u00e3o local do Qodana.<\/li>\n<li>Como um arquivo JAR instalado no IDE, com a inspe\u00e7\u00e3o de c\u00f3digo inclu\u00edda entre as integradas.\u00a0<\/li>\n<\/ul>\n<p>Acesse os <a href=\"https:\/\/github.com\/JetBrains\/intellij-sdk-code-samples\/tree\/main\/code_inspection_qodana\" target=\"_blank\" rel=\"noreferrer noopener\">exemplos de c\u00f3digo do IntelliJ SDK<\/a> para ver exemplos concisos de plug-ins para o Qodana e um projeto de teste.<\/p>\n<p><em>Artigo original em ingl\u00eas por:<br \/><\/em><\/p>\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/02\/avatar0-1.jpg\" width=\"200\" height=\"200\" alt=\"R\u00f3bert Novotn\u00fd\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                            <h4>R\u00f3bert Novotn\u00fd<\/h4>\n                                        <p>R\u00f3bert Novotn\u00fd is a Developer Advocate, specializing in the IntelliJ Platform and plugin development.<\/p>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":1086,"featured_media":690567,"comment_status":"closed","ping_status":"closed","template":"","categories":[8844,1065,6924],"tags":[246,3233,41,6470],"cross-post-tag":[6687],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/platform\/690565"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/platform"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/types\/platform"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/users\/1086"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/comments?post=690565"}],"version-history":[{"count":2,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/platform\/690565\/revisions"}],"predecessor-version":[{"id":690590,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/platform\/690565\/revisions\/690590"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media\/690567"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media?parent=690565"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/categories?post=690565"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/tags?post=690565"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/cross-post-tag?post=690565"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}