code_inspections.md: update/fix

This commit is contained in:
Yann Cébron 2021-06-03 17:43:42 +02:00
parent 8cf6d04f29
commit 49cc17a83b

View File

@ -1,6 +1,6 @@
[//]: # (title: Code Inspections)
<!-- Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<!-- Copyright 2000-2021 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
The IntelliJ Platform provides tools designed for static code analysis called _code inspections_, which help the user maintain and clean up code without actually executing it.
Custom code inspections can be implemented as IntelliJ Platform plugins.
@ -14,11 +14,12 @@ See [Inspections](https://jetbrains.design/intellij/text/inspections/) topic in
## Creating an Inspection Plugin
The [comparing_references_inspection](https://github.com/JetBrains/intellij-sdk-code-samples/tree/main/comparing_references_inspection) code sample adds a new inspection to the **Java | Probable Bugs** group in the [Inspections list](https://www.jetbrains.com/help/idea/inspections-settings.html).
The [comparing_references_inspection](https://github.com/JetBrains/intellij-sdk-code-samples/tree/main/comparing_references_inspection) code sample adds a new inspection to the <control>Java | Probable Bugs</control> group in the [Inspections list](https://www.jetbrains.com/help/idea/inspections-settings.html).
The inspection reports when the `==` or `!=` operator is used between Java expressions of reference types.
It illustrates the components for a custom inspection plugin:
* Describing an [inspection](#plugin-configuration-file) in the plugin configuration file.
* Implementing a [local inspection class](#inspection-implementation-java-class) to inspect Java code in the IntelliJ Platform-based IDE editor.
* Implementing a [local inspection class](#inspection-implementation-java-class) to inspect Java code in the editor.
* Creating a [visitor](#visitor-implementation-class) to traverse the PSI tree of the Java file being edited, inspecting for problematic syntax.
* Implementing a [quick fix](#quick-fix-implementation) class to correct syntax problems by altering the PSI tree as needed.
Quick fixes are displayed to the user like [intentions](code_intentions.md).
@ -29,18 +30,20 @@ It illustrates the components for a custom inspection plugin:
Although the IntelliJ Platform SDK code samples illustrate implementations of these components, it is often useful to see examples of inspections implemented in the _intellij_community_ code base.
This process can help find inspection descriptions and implementations based on what is visible in the IDE UI.
The overall approach works for inspections aimed at other languages as well.
* Find an existing inspection that is similar to the one you want to implement in the **Preferences | Editor | Inspections** panel.
* Find an existing inspection that is similar to the one you want to implement in the <menupath>Settings/Preferences | Editor | Inspections</menupath> panel.
Note the display name of the inspection.
For example, the Java/Probable Bugs inspection "Object comparison using '==', instead of 'equals()'" is very similar to `comparing_references_inspection`.
For example, the Java/Probable Bugs inspection <control>Object comparison using '==', instead of 'equals()'</control> is very similar to `comparing_references_inspection`.
* Use the display name text as the [target for a search](https://www.jetbrains.com/help/idea/finding-and-replacing-text-in-project.html) within the _intellij_community_ project.
This will identify a bundle file if the display name is localized.
If it is not localized, the search finds either the plugin configuration (`plugin.xml`) file where it is an attribute in the inspection description, or the implementation where it is provided by an overridden method.
If it is not localized, the search finds either the plugin configuration (<path>plugin.xml</path>) file where it is an attribute in the inspection description, or the implementation where it is provided by an overridden method.
* In the case of localization, copy the key from the bundle file identified by the search.
* Use the key text as the target for a search within the _intellij_community_ project.
This search locates the plugin configuration file that describes the inspection.
* From the inspection description entry find the `implementationClass` attribute value.
* Use the `implementationClass` text as the [target of a class search](https://www.jetbrains.com/help/idea/searching-everywhere.html#Searching_Everywhere.xml) in the _intellij_community_ codebase to find the implementation.
See also [Explore the IntelliJ Platform API](explore_api.md) for more information and strategies.
## Creating an Inspection
The [comparing_references_inspection](https://github.com/JetBrains/intellij-sdk-code-samples/tree/main/comparing_references_inspection) code sample reports when the `==` or `!=` operators are used between Java expressions of reference types.
The user can apply a quick fix to change `a==b` to `a.equals(b)`, or `a!=b` to `!a.equals(b)`.
@ -48,7 +51,7 @@ The user can apply a quick fix to change `a==b` to `a.equals(b)`, or `a!=b` to `
The details of the `comparing_references_inspection` implementation illustrate the components of an inspection plugin.
### Plugin Configuration File
The `comparing_references_inspection` is described as a `<localInspection>` extension point in the `comparing_references_inspection` plugin configuration ([`plugin.xml`](https://github.com/JetBrains/intellij-sdk-code-samples/blob/main/comparing_references_inspection/src/main/resources/META-INF/plugin.xml)) file.
The `comparing_references_inspection` is described as a `com.intellij.localInspection` extension point in the `comparing_references_inspection` plugin configuration ([`plugin.xml`](https://github.com/JetBrains/intellij-sdk-code-samples/blob/main/comparing_references_inspection/src/main/resources/META-INF/plugin.xml)) file.
There exist two types of inspection extensions:
* The `com.intellij.localInspection` extension point is used for inspections that operate on one file at a time, and also operate "on-the-fly" as the user edits the file.
@ -71,8 +74,8 @@ One of these classes is a good basis for a new inspection implementation, but a
The primary responsibilities of the inspection implementation class are to provide:
* A `PsiElementVisitor` object to traverse the PSI tree of the file being inspected.
* A `LocalQuickFix` class to change the syntax of an identified problem.
* A `JPanel` to be displayed in the _Inspections_ dialog.
* A `LocalQuickFix` class to fix an identified problem.
* A `JPanel` to be displayed in the <control>Inspections</control> settings dialog.
The `ComparingReferencesInspection` class defines two `String` fields:
* `QUICK_FIX_NAME` defines the string users see when prompted to apply the quick fix.
@ -107,24 +110,23 @@ The change to the PSI tree is accomplished by the usual approach to modification
The inspection preferences panel is used to display information and provide additional options for the inspection.
The panel created by `ComparingReferencesInspection.createOptionsPanel()` just defines a single `JTextField` to display in a `JPanel`.
This `JPanel` gets added to the default IntelliJ Platform _Inspections Preferences_ dialog when the `comparing_references_inspection` short name is selected.
This `JPanel` gets added to the <control>Inspections</control> settings dialog when the inspection is selected.
The `JTextField` allows editing of the `CHECKED_CLASSES` field while displayed in the panel.
Note that the IntelliJ Platform provides most of the UI displayed in the _Inspections Preferences_ panel.
As long as the inspection attributes and inspection description are defined correctly, the IntelliJ Platform displays the information in the _Inspections Preferences_ UI.
Note that the IntelliJ Platform provides most of the UI displayed in the <control>Inspections</control> panel.
### Inspection Description
The inspection description is an HTML file.
The description is displayed in the upper right panel of the _Inspections Preferences_ dialog when an inspection is selected from the list.
The description is displayed in the upper right panel of the <control>Inspections</control> settings dialog when an inspection is selected from the list.
Implicit in using [`LocalInspectionTool`](upsource:///platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java) in the class hierarchy of the inspection implementation means following some conventions.
* The inspection description file is expected to be located under `<resources root>/inspectionDescriptions/`.
* The inspection description file is expected to be located under <path>$RESOURCES_ROOT_DIRECTORY$/inspectionDescriptions/</path>.
If the inspection description file is to be located elsewhere, override `getDescriptionUrl()` in the inspection implementation class.
* The name of the description file is expected to be the inspection `<short name>.html` as provided by the inspection description, or the inspection implementation class.
* The name of the description file is expected to be the inspection <path>$SHORT_NAME$.html</path> as provided by the inspection description, or the inspection implementation class.
If a short name is not provided by the plugin, the IntelliJ Platform computes one by removing `Inspection` suffix from the implementation class name.
### Inspection Unit Test
> Please note that running the test requires setting system property `idea.home.path` in `test {}` block of `build.gradle`
> Please note that running the test requires setting system property `idea.home.path` in `test {}` block of <path>build.gradle</path>.
>
{type="note"}
@ -134,47 +136,42 @@ See the [Testing Plugins](testing_plugins.md) section for general information ab
The `comparing_references_inspection` test is based on the [`UsefulTestCase`](upsource:///platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java) class, part of the JUnit framework APIs.
This class handles much of the underlying boilerplate for tests.
By convention, the folder `<project root>/testData/` contains the test files.
The folder contains pairs of files for each test using the name convention `*.java` and `*.after.java`.
By convention, the folder <path>test/testData/</path> contains the test files.
The folder contains pairs of files for each test using the name convention <path>*.java</path> and <path>*.after.java</path>.
In the case of `comparing_references_inspection` the test files are `Eq.java` / `Eq.after.java`, and `Neq.java` / `Neq.after.java`.
In the case of `comparing_references_inspection` the test files are <path>Eq.java</path> / <path>Eq.after.java</path>, and <path>Neq.java</path> / <path>Neq.after.java</path>.
The `comparing_references_inspection` tests run the inspection on the `*.java` files, implement the quick fix, and compare the results with the respective `*.after.java` files.
The `comparing_references_inspection` tests run the inspection on the <path>*.java</path> files, implement the quick fix, and compare the results with the respective <path>*.after.java</path> files containing expected result.
## Running the Comparing References Inspection Code Sample
The [comparing_references_inspection](https://github.com/JetBrains/intellij-sdk-code-samples/tree/main/comparing_references_inspection) code sample adds a new inspection to the **Java | Probable Bugs** group in the [Inspections list](https://www.jetbrains.com/help/idea/inspections-settings.html).
The inspection reports when the `==` or `!=` operator is used between Java expressions of reference types.
The [comparing_references_inspection](https://github.com/JetBrains/intellij-sdk-code-samples/tree/main/comparing_references_inspection) code sample adds a new inspection to the <control>Java | Probable Bugs</control> group in the [Inspections List](https://www.jetbrains.com/help/idea/inspections-settings.html).
To run the sample plugin:
* Start IntelliJ IDEA, open the `intellij-sdk-docs` project, and highlight the [comparing_references_inspection](https://github.com/JetBrains/intellij-sdk-code-samples/tree/main/comparing_references_inspection) module.
* Open the [Project Structure](https://www.jetbrains.com/help/idea/project-structure-dialog.html) dialog and ensure that the project settings are valid for your environment.
* If necessary, modify the [Run/Debug Configurations](https://www.jetbrains.com/idea/webhelp/run-debug-configuration-plugin.html) for the `comparing_references_inspection` module.
* Run the plugin by choosing **Run** on the main menu.
See [Code Samples](code_samples.md) on how to set up and run the plugin.
### Configuring the Plugin
Once the plugin is launched, you can set the plugin options.
You can specify the Java classes to participate in the code inspection and the severity level of the found probable bugs.
On the main menu, open the **Preferences | Editor | Inspections** dialog.
In the list of the IntelliJ IDEA _Java_ inspections, expand the _Probable bugs_ node, and then click _SDK: '==' or '!=' instead of 'equals()'_.
On the main menu, open the <menupath>Settings/Preferences | Editor | Inspections</menupath> dialog.
In the list of the IntelliJ IDEA <control>Java</control> inspections, expand the <control>Probable bugs</control> node, and then click <control>SDK: '==' or '!=' instead of 'equals()'</control>.
![](comparingReferences_options.png)
Under **Options**, you can specify the following plugin settings:
* From the **Severity** list, select the severity level of probable bugs the plugin finds such as Warning, Info, etc.
* In the text box under **Severity**, specify the semicolon separated list of Java classes to participate in this code inspection.
* When finished, click **OK**.
Under <control>Options</control>, you can specify the following plugin settings:
* From the <control>Severity</control> list, select the severity level of probable bugs the plugin finds such as <control>Warning</control>, <control>Error</control>, etc.
* In the text box under <control>Severity</control>, specify the semicolon separated list of Java classes to participate in this code inspection.
* When finished, click <control>OK</control>.
### How does it work?
The plugin inspects your code opened in the IntelliJ IDEA editor or the code you are typing.
The plugin inspects your code opened in the IntelliJ IDEA editor.
The plugin highlights the code fragments where two variables of the reference type are separated by `==` or `!=` and proposes to replace this code fragment with `.equals()`:
![](comparingReferences.png)
In this example, the `str1` and `str2` are variables of the String type.
Clicking _SDK: Use equals()_ replaces:
Clicking <control>SDK: Use equals()</control> replaces:
```java
return (str1==str2);