FlexInspect
Starting from version 2024.1 of IntelliJ IDEA, you can develop your own inspections specific to your project using the IntelliJ API and Kotlin. You can:
Access the PSI representation of the source code,
Debug new inspections on the fly,
Observe your new custom inspections in action including highlighting of the code fragments that do not meet expected behavior.
Using FlexInspect, you can get access to the same API that is used by all IntelliJ IDEA and Qodana inspections, and run these inspections on your entire project using Qodana to ensure that your entire team follows the standards defined by you.
You can develop local inspections that run within a file scope, global inspections that run within a project scope as described in the Run Qodana locally section, and inspect your code in CI pipelines. Currently, FlexInspect supports any language covered by IntelliJ IDEA either natively or through additional plugins. For example, Java, Kotlin, JS, TypeScript, PHP, Go, Python, Ruby, SQL, XML, CSS, YAML, JSON, SHELL, and DOCKERFILE are supported.
Prerequisites
Make sure that IntelliJ IDEA is installed on your machine.
Ensure that your version of IntelliJ IDEA supports the language you want to develop an inspection for. Out of the box, IntelliJ IDEA supports Java and Kotlin. The Ultimate edition of IntelliJ IDEA also provides the default support for JavaScript and TypeScript. To provide support for other languages like PHP, Go, and Python, you can install plugins from JetBrains Marketplace. The detailed information is available on the IntelliJ IDEA documentation portal.
Because all inspections are developed using the Kotlin language, you need to know the basics of Kotlin.
How it works
You write your inspections in Kotlin and store them in the inspections
directory of your project as .inspection.kts
files. Each .inspection.kts
file contains Kotlin code to check your code using the API provided by the Program Structure Interface or PSI. IntelliJ IDEA reads .inspection.kts
files, compiles the inspection code on the fly, and then it executes compiled inspections.
Program Structure Interface (PSI)
PSI is an AST representation of your code corresponding to a source file's structure. In case of Java code, PSI reflects basic blocks of a Java file like package and import statements, class statements, method invocations, and other nodes. FlexInspect uses the PSI tree representation of your code to obtain the list of the code nodes that can be inspected using your inspections.
In IntelliJ IDEA, you can navigate through PSI via the PSI Viewer tool. To do it, in IntelliJ IDEA you can open a file that you would like to view with PSI Viewer, and then navigate to Tools | View PSI Structure of Current File.
Inspection types
You can create local and global inspections.
A local inspection operates on a file level and inspects each file of your project separately from others. Once you create a local inspection, IntelliJ IDEA will run it for an opened file in the editor.
A global inspection operates on a project level using the project scope for inspection. For example, you can create inspections that can check whether specific files exist in your project. You can run global inspections as described in the Run Qodana locally section.
How to start
This section shows how to create an inspection example that will inspect whether a Java class has a constructor method.
Create an inspection file
To create a new .inspection.kts
template file, follow the procedure below.
In your project, create the
inspections
directory.In the project navigator of IntelliJ IDEA, hover over the
inspections
directory, right-click the directory, navigate to .On the dialog that opens, you can choose among the local and global inspection templates that you can use for your inspection. Empty local and global templates are universal for any language supported by FlexInspect, while local Java, Kotlin, JavaScript and Typescript templates are dedicated to these languages.
Each file can contain multiple inspections. CamelCase is the preferable naming method for
.inspection.kts
files.
Here is the animation showing how you can create an inspection.
The created file already contains code examples and explanations, which lets you start to develop your own inspection.
Study the PSI tree of your code
In IntelliJ IDEA, open the file that you would like to analyze using your inspection.
Navigate to
. Here you can explore the PSI tree of your file, APIs available for PSI nodes contained in the file, and come up with algorithms that would operate with this PSI tree.
For example, to check whether a method is a constructor, you can use the isConstructor()
PSI method available for each method of a class.
Create your inspection
You can develop the inspection using the template that you have already created. To check whether a class has a constructor method, in this example you can iterate over all methods and use the isConstructor()
method. If there is no constructor method, the inspection generates the error showing that a class has no constructor method.
Here is the Kotlin snippet for the NoConstructor.inspection.kts
file containing inline comments.
Test your inspection in the IDE
After creating the inspection, you can see the compilation status on the toolbar in the upper part of the inspection file. When you change the inspection code, you need to explicitly recompile the inspection using the recompile button in the left part of the toolbar, or use the Alt+Shift+Enter/⌥⇧Enter shortcut.
You can also open files using PSI Viewer and study inspection examples.
To see how the new inspection functions on your code, open a file containing a problem the inspection is supposed to highlight.
Run your custom inspection using Qodana
FlexInspect is supported by the default inspection profiles.
To inspect your entire project with the new inspection locally, run Qodana as explained in the Run Qodana locally section.
To run your custom inspection in a CI pipeline, you can visit the Integration with CI systems section and find the instructions for your CI/CD solution. Because your inspection is already contained in the inspections
directory of your project, it is already available for inspecting your code.
You can use the inspection name from the id
field of the inspection file to disable or enable your custom inspection in the qodana.yaml
file.