PK $ DevkitIconMappings.json{
"icons": {
"expui": {
"gutter": {
"descriptionFile@14x14.svg": "icons/gutter/descriptionFile.svg",
"diff@14x14.svg": "icons/gutter/diff.svg",
"plugin@14x14.svg": "icons/gutter/plugin.svg",
"properties@14x14.svg": "icons/gutter/properties.svg"
},
"addSDK.svg": "icons/add_sdk.svg",
"sdkClosed.svg": "icons/sdk_closed.svg"
}
}
}PK ʑ intellij.devkit.core.xml
LocalQuickFix
and IntentionAction
implementations that prevent intention preview
action from functioning properly. Additionally, excessive @SafeFieldForPreview
annotations are reported on fields
whose types are known to be safe.
Intention preview is an IntelliJ platform feature that displays how quick-fix or intention action
will change the current file when applied. To implement this in quick fixes,
LocalQuickFix.generatePreview()
is called with a custom ProblemDescriptor
that points to the non-physical copy of current file. In intention actions, IntentionAction.generatePreview()
is called with the non-physical copy of current file and imaginary editor.
Normally, these methods just delegate to LocalQuickFix.applyFix()
or IntentionAction.invoke()
.
However, some quick-fixes may refer directly or indirectly to physical elements and use them for writing. As a result,
preview won't work, as the quick-fix will attempt to update physical PSI instead of non-physical one.
To avoid this, default implementation of generatePreview()
delegates only if all the
instance fields of a quick fix or intention action class have safe types: primitives, Strings, etc.
You may fix this problem in a number of ways:
@SafeFieldForPreview
. You can also use
@SafeTypeForPreview
if the field type can never store any writable PSI reference.
getFileModifierForPreview()
method and create a copy of the quick-fix
rebinding it to the non-physical file copy which is supplied as a parameter. Use
PsiTreeUtil.findSameElementInCopy()
to find the corresponding PSI elements inside the
supplied non-physical copy.
ProblemDescriptor.getPsiElement()
in quick fix or from the supplied file/editor in intention action.
You may also inherit the abstract LocalQuickFixAndIntentionActionOnPsiElement
class and
implement its invoke()
and isAvailable()
methods, which have
startElement
and endElement
parameters. These parameters are automatically
mapped to a non-physical file copy for you.
generatePreview()
method and provide completely custom preview behavior.
For example, it's possible to display a custom HTML document instead of actual preview if your action
does something besides modifying a current file.
This inspection does not report if a custom implementation of getFileModifierForPreview()
or generatePreview()
exists. However, this doesn't mean that the implementation is correct and preview works.
Please test. Also note that preview result is calculated in background thread, so you cannot start a write action
during the preview or do any operation that requires a write action. Finally, no preview is generated automatically
if startInWriteAction()
returns false
. In this case, having custom generatePreview()
implementation is desired.
New in 2022.1
PK rQb @ inspectionDescriptions/ActionPresentationInstantiatedInCtor.html
Reports any actions that are registered in the plugin.xml
file and instantiate
the com.intellij.openapi.actionSystem.Presentation
object in their constructors.
Any of the constructors of AnAction
with parameters instantiate the Presentation
object. However, instantiating the Presentation
object in constructor results in allocating
resources, which may not be necessary. Instead of creating an instance of Presentation
that
stores text, description, or icon, it is more efficient to utilize no-argument constructors of
AnAction
and other base classes and follow the convention for setting the text, description,
and icon in plugin.xml
. The IDE will load text, description, and icon only when the action
is actually displayed in the UI.
The convention for setting the text, description, and icon is as follows:
id
attribute for the action in the plugin.xml
file.
icon
attribute if an icon is needed.
<actions>
):
action.<action-id>.text=Translated Action Text
action.<action-id>.description=Translated Action Description
Bad example:
// NewKotlinFileAction.kt
internal class NewKotlinFileAction : AnAction(
KotlinBundle.message("action.new.file.text"),
KotlinBundle.message("action.new.file.description"),
KotlinIcons.FILE
)
<action
class="org.jetbrains.kotlin.idea.actions.NewKotlinFileAction"
</action>
Good example:
// NewKotlinFileAction.kt
internal class NewKotlinFileAction : AnAction()
<action
id="Kotlin.NewFile"
class="org.jetbrains.kotlin.idea.actions.NewKotlinFileAction"
icon="org.jetbrains.kotlin.idea.KotlinIcons.FILE">
</action>
# KotlinBundle.properties
action.Kotlin.NewFile.text=Kotlin Class/File
action.Kotlin.NewFile.description=Creates a new Kotlin class or file
New in 2023.2
PK 36`J J J inspectionDescriptions/ApplicationServiceAsStaticFinalFieldOrProperty.html Reports assignments of application services to static final fields / immutable properties.Note: Hereinafter, static in Kotlin refers to members of non-anonymous objects or top-level declarations.
Such services' assignments contribute to global state and make it impossible to tear down an application and set up another one in tests, therefore, repeated tests in the same process may fail. The only exception is an explicit constructor call to store dummy/default instances.
The recommended way to avoid storing services is to retrieve a service locally.
Alternatively, one can wrap it in java.util.function.Supplier
(Java, Kotlin)
or convert the property to a function (Kotlin).
Example (Java):
// Bad:
private static final ManagingFS ourInstance = ApplicationManager.getApplication().getService(ManagingFS.class);
// Good:
private static final Supplier<ManagingFS> ourInstance = CachedSingletonsRegistry.lazy(() -> {
return ApplicationManager.getApplication().getService(ManagingFS.class);
});
// Exception:
private static final UniqueVFilePathBuilder DUMMY_BUILDER = new UniqueVFilePathBuilder()
While services' assignments to properties without backing fields don't cause the aforementioned problem,
using an explicit getInstance()
method to retrieve a service is preferred over using a property:
MyApplicationService.getInstance()
calls consistent
when used both in Kotlin, and Java.MyApplicationService.getInstance()
consistent with MyProjectService.getInstance(project)
,
both on the declaration and call sites.For better tooling performance, it is always advised to keep an explicit method return type.
Example:
@Service
class MyApplicationService {
companion object {
@JvmStatic
val instance: MyApplicationService // bad
get() = service()
}
}
@Service
class MyApplicationService {
companion object {
@JvmStatic
fun getInstance(): MyApplicationService = service() // good
}
}
New in 2023.3 PK H H inspectionDescriptions/CallingMethodShouldBeRequiresBlockingContext.html
Highlights calls of method annotated with @RequiresBlockingMethod
inside non-annotated method.
@RequiresBlockingMethod
to clearly state its contract.
PK yT 4 inspectionDescriptions/CancellationCheckInLoops.html
Reports loops, forEach
-like methods, and ContainerUtil.process()
with missing cancellation checks.
Runs only within the methods with com.intellij.util.concurrency.annotations.RequiresReadLock
annotation.
Example:
@RequiresReadLock
fun doSomething() {
...
for (item in items) {
ProgressManager.checkCanceled() // should be present in the first line
...
}
items.forEach {
ProgressManager.checkCanceled() // should be present in the first line
...
}
...
}
In the case of nested loops with nothing in between:
@RequiresReadLock
fun doSomething() {
...
for (item in items) {
// nothing in between
for (inner in item.inners) {
ProgressManager.checkCanceled() // should be present in the first line of the inner loop only
...
}
}
...
}
In blocking context com.intellij.openapi.progress.ProgressManager#checkCanceled
should be used,
while com.intellij.openapi.progress.CoroutinesKt#checkCancelled
should be used in suspending one.
See Background Processes and ProcessCanceledException in IntelliJ Platform Plugin SDK docs for more details.
New in 2023.1 PK ? 2 inspectionDescriptions/ComponentNotRegistered.html
Reports plugin components and actions that are not registered in aplugin.xml
descriptor.
This eases developing new components when using the "Create Class" intention and helps keep track of potentially obsolete components.
Provided quick-fix to register the component adds necessary registration in plugin.xml
descriptor.
Configure the inspection:
The following problems are reported:
AnAction
class.New in 2023.2 PK ȇ C inspectionDescriptions/ExtensionRegisteredAsServiceOrComponent.html
Reports extension implementation being additionally registered as a service/component.While there can be multiple extension instances, the IntelliJ Platform ensures that only one instance of a service/component is loaded, thus registering the same class as both an extension and a service/component may cause issues.
New in 2023.2 PK f- - + inspectionDescriptions/FileEqualsUsage.html
Reports usages ofjava.io.File.equals()/hashCode()/compareTo()
methods.
These do not honor case-insensitivity on macOS.
Use com.intellij.openapi.util.io.FileUtil.filesEquals()/fileHashCode()/compareFiles()
methods instead.
Application
or Project
as a parent Disposable
in plugin code.
Such usages will lead to plugins not being unloaded correctly. Please see Choosing a Disposable Parent in SDK Docs.
PK _ E inspectionDescriptions/IncorrectProcessCanceledExceptionHandling.html ReportsProcessCanceledException
s handled in an incorrect way.
ProcessCanceledException
and its inheritors must not be caught, swallowed, logged, or handled in any way.
Instead, it must be rethrown so that the infrastructure can handle it correctly.
Inspection reports both explicit ProcessCanceledException
or its inheritors catching,
as well as catching RuntimeException
, Exception
and Throwable
covering ProcessCanceledException
.
Example:
// bad:
try {
// ...
} catch (ProcessCanceledException e) { // exception should not be swallowed
}
// bad:
try {
// ...
} catch (ProcessCanceledException e) {
LOG.error("Error occurred", e); // exception should not be logged
throw e;
}
// good:
try {
// ...
} catch (ProcessCanceledException e) {
// additional actions
throw e;
}
New in 2023.2
PK &| 6 inspectionDescriptions/IncorrectServiceRetrieving.html Reports the following problems when retrieving services:Example (Kotlin):
@Service
class MyAppService
@Service(Service.Level.PROJECT)
class MyProjectService(private val project: Project)
// Bad:
val projectService = service<MyProjectService>() // The project-level service is retrieved as an application-level service
val applicationService = project.service<MyAppService>() // The application-level service is retrieved as a project-level service
// Good:
val projectService = project.service<MyProjectService>()
val applicationService = service<MyAppService>();
New in 2023.2 PK SLǥ C inspectionDescriptions/InspectionDescriptionNotFoundInspection.html
Reports inspections that are missing an HTML description file, i.e. a file containing a text like this.The Create description file quick-fix creates a template HTML description file.
PK v` ` 5 inspectionDescriptions/InspectionUsingGrayColors.html Reports usages ofjava.awt.Color
to create gray colors.
The Convert to 'Gray' quick fix replaces it using com.intellij.ui.Gray
constants instead.
Examples:
// bad:
Color gray = new Color(37, 37, 37);
// good:
Color gray = Gray._37;
PK gep p B inspectionDescriptions/IntentionDescriptionNotFoundInspection.html
Reports intentions that are missing an HTML description file, before.template
file or after.template
file.
These are shown in Settings | Editor | Intentions.
The Create description file quick-fix creates a template HTML description file.
PK A# * inspectionDescriptions/LeakableMapKey.html Reports usingLanguage
or FileType
as a map key in plugin code.
Such usages might lead to inability to unload the plugin properly.
Please consider using String
as keys instead.
See Dynamic Plugins in SDK Docs for more information.
PK vp p 5 inspectionDescriptions/LightServiceMigrationCode.html Reports classes that can be marked as light services using the@com.intellij.openapi.components.Service
annotation
instead of being registered as services in plugin.xml
A service that is not intended for overriding is not required to be registered in the plugin.xml
file.
Instead, annotate the service class with the @Service
annotation. For project-level services, specify
@Service(Service.Level.PROJECT)
.
Requirements:
final
.serviceInterface
is not specified.com.intellij.openapi.components.PersistentStateComponent
,
roaming must be disabled (roamingType = RoamingType.DISABLED
).
os
, client
, overrides
, id
, preload
.See Services in IntelliJ Platform Plugin SDK docs for more details.
See also the Plugin DevKit | Plugin descriptor | A service can be converted to a light one
inspection.
New in 2023.2 PK q 4 inspectionDescriptions/LightServiceMigrationXML.html
Reports services registered inplugin.xml
that can be converted to light ones.
A service that is not intended for overriding is not required to be registered in the plugin.xml
file.
Instead, annotate the service class with the @com.intellij.openapi.components.Service
annotation. For
project-level services, specify @Service(Service.Level.PROJECT)
.
Requirements:
final
.serviceInterface
is not specified.com.intellij.openapi.components.PersistentStateComponent
,
roaming must be disabled (roamingType = RoamingType.DISABLED
).
os
, client
, overrides
, id
, preload
.Also reports services registered in plugin.xml
whose classes are already annotated with @Service
.
See Services in IntelliJ Platform Plugin SDK docs for more details.
See also the Plugin DevKit | Code | A service can be converted to a light one
inspection.
New in 2023.2 PK .~ ~ 3 inspectionDescriptions/LightServiceMustBeFinal.html
Reports classes annotated with the@com.intellij.openapi.components.Service
annotation that are not final.
Suggests making a class final if it is concrete.
Example:
// MyService.kt
@Service(Service.Level.APP)
open class MyService
After the quick-fix is applied:
// MyService.kt
@Service(Service.Level.APP)
class MyService
Suggests removing the @Service
annotation if it is an abstract class or interface.
Example:
// MyService.java
@Service(Service.Level.APP)
abstract class MyService {}
After the quick-fix is applied:
// MyService.java
abstract class MyService {}
New in 2023.2 PK gL} E inspectionDescriptions/ListenerImplementationMustNotBeDisposable.html
Reports listener implementations that implementcom.intellij.openapi.Disposable
.
Listener implementations must be stateless and must not implement life-cycle, including com.intellij.openapi.Disposable
.
See documentation for more information.
New in 2023.3
PK I