mirror of
https://github.com/JetBrains/intellij-sdk-code-samples.git
synced 2025-07-30 18:27:49 +08:00
upsource:// links: remove <!<!--#Lnn--> anchors
This commit is contained in:
parent
bd6691fcda
commit
f668ade6df
@ -18,10 +18,10 @@ For each element type that you want to store in the stub tree, you need to perfo
|
||||
* Define an interface for the stub, derived from the [`StubElement`](upsource:///platform/core-api/src/com/intellij/psi/stubs/StubElement.java) interface ([example](upsource:///plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/PropertyStub.java)).
|
||||
* Provide an implementation for the interface ([example](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyStubImpl.java)).
|
||||
* Make sure that the interface for the PSI element extends [`StubBasedPsiElement`](upsource:///platform/core-api/src/com/intellij/psi/StubBasedPsiElement.java) parameterized by the type of the stub interface ([example](upsource:///plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/Property.java)).
|
||||
* Make sure that the implementation class for the PSI element extends [`StubBasedPsiElementBase`](upsource:///platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java) parameterized by the type of the stub interface ([example](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java)<!--#L45-->). Provide both a constructor that accepts an `ASTNode` and a constructor which accepts a stub.
|
||||
* Make sure that the implementation class for the PSI element extends [`StubBasedPsiElementBase`](upsource:///platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java) parameterized by the type of the stub interface ([example](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java)). Provide both a constructor that accepts an `ASTNode` and a constructor which accepts a stub.
|
||||
* Create a class which implements `IStubElementType` and is parameterized with the stub interface and the actual PSI element interface ([example](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/parsing/PropertyStubElementType.java)). Implement the `createPsi()` and `createStub()` methods for creating PSI from a stub and vice versa. Implement the `serialize()` and `deserialize()` methods for storing the data in a binary stream.
|
||||
* Use the class implementing `IStubElementType` as the element type constant when parsing ([example](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/parsing/PropertiesElementTypes.java)).
|
||||
* Make sure that all methods in the PSI element interface access the stub data rather than the PSI tree when appropriate ([example: `Property.getKey()` implementation](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java)<!--#L95-->).
|
||||
* Make sure that all methods in the PSI element interface access the stub data rather than the PSI tree when appropriate ([example: `Property.getKey()` implementation](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java)).
|
||||
|
||||
The following steps need to be performed only once for each language that supports stubs:
|
||||
|
||||
@ -44,7 +44,7 @@ When building the stub tree, you can at the same time put some data about the st
|
||||
|
||||
A stub index is a class which extends [`AbstractStubIndex`](upsource:///platform/indexing-api/src/com/intellij/psi/stubs/AbstractStubIndex.java). In the most common case, when the key type is `String`, you use a more specific base class, namely [`StringStubIndexExtension`](upsource:///platform/indexing-api/src/com/intellij/psi/stubs/StringStubIndexExtension.java). Stub index implementation classes are registered in the `com.intellij.stubIndex` extension point.
|
||||
|
||||
To put data into an index, you implement the method `IStubElementType.indexStub()` ([example: `JavaClassElementType.indexStub()`](upsource:///java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java)<!--#L189-->). This method accepts an `IndexSink` as a parameter, and puts in the index ID and the key for each index in which the element should be stored.
|
||||
To put data into an index, you implement the method `IStubElementType.indexStub()` ([example: `JavaClassElementType.indexStub()`](upsource:///java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java)). This method accepts an `IndexSink` as a parameter, and puts in the index ID and the key for each index in which the element should be stored.
|
||||
|
||||
To access the data from an index, the following two methods are used:
|
||||
|
||||
|
@ -49,4 +49,4 @@ Two common filter implementations you may want to reuse are [`RegexpFilter`](ups
|
||||
|
||||
## Starting a run configuration from code
|
||||
|
||||
If you have an existing run configuration that you need to execute, the easiest way to do so is to use [`ProgramRunnerUtil.executeConfiguration()`](upsource:///platform/execution-impl/src/com/intellij/execution/ProgramRunnerUtil.java)<!--#L110-->. The method takes a [`Project`](upsource:///platform/core-api/src/com/intellij/openapi/project/Project.java), a [`RunnerAndConfigurationSettings`](upsource:///platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java), as well as an [`Executor`](upsource:///platform/lang-api/src/com/intellij/execution/Executor.java). To get the `RunnerAndConfigurationSettings` for an existing configuration, you can use, for example, `RunManager.getConfigurationSettings(ConfigurationType)`. As the last parameter, you normally pass either `DefaultRunExecutor.getRunExecutorInstance()` or `DefaultDebugExecutor.getDebugExecutorInstance()`.
|
||||
If you have an existing run configuration that you need to execute, the easiest way to do so is to use [`ProgramRunnerUtil.executeConfiguration()`](upsource:///platform/execution-impl/src/com/intellij/execution/ProgramRunnerUtil.java). The method takes a [`Project`](upsource:///platform/core-api/src/com/intellij/openapi/project/Project.java), a [`RunnerAndConfigurationSettings`](upsource:///platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java), as well as an [`Executor`](upsource:///platform/lang-api/src/com/intellij/execution/Executor.java). To get the `RunnerAndConfigurationSettings` for an existing configuration, you can use, for example, `RunManager.getConfigurationSettings(ConfigurationType)`. As the last parameter, you normally pass either `DefaultRunExecutor.getRunExecutorInstance()` or `DefaultDebugExecutor.getDebugExecutorInstance()`.
|
||||
|
@ -24,15 +24,15 @@ The easiest way to implement this interface is to use the [`ConfigurationTypeBas
|
||||
|
||||
## Configuration factory
|
||||
|
||||
All run configurations are created by the [`ConfigurationFactory`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java) registered for a particular `ConfigurationType`. It's possible that one `ConfigurationType` [has more than one](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationType.java)<!--#L34--> `ConfigurationFactory`:
|
||||
All run configurations are created by the [`ConfigurationFactory`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java) registered for a particular `ConfigurationType`. It's possible that one `ConfigurationType` [has more than one](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationType.java) `ConfigurationFactory`:
|
||||
|
||||

|
||||
|
||||
The key API of [`ConfigurationFactory`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java), and the only method that you're required to implement, is the [`createTemplateConfiguration`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java)<!--#L45--> method. This method is called once per project to create the template run configuration.
|
||||
The key API of [`ConfigurationFactory`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java), and the only method that you're required to implement, is the [`createTemplateConfiguration`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java) method. This method is called once per project to create the template run configuration.
|
||||
|
||||
All real run configurations (loaded from the workspace or created by the user) are called by cloning the template through the [`createConfiguration`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java)<!--#L39--> method.
|
||||
All real run configurations (loaded from the workspace or created by the user) are called by cloning the template through the [`createConfiguration`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java) method.
|
||||
|
||||
You can customize additional aspects of your configuration factory by overriding the [`getIcon`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java)<!--#L59-->, [`getAddIcon`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java)<!--#L55-->, [`getName`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java)<!--#L51--> and the default settings methods. These additional overrides are optional.
|
||||
You can customize additional aspects of your configuration factory by overriding the [`getIcon`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java), [`getAddIcon`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java)<!--#L55-->, [`getName`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java)<!--#L51--> and the default settings methods. These additional overrides are optional.
|
||||
|
||||
## Run configuration
|
||||
|
||||
@ -52,15 +52,15 @@ When implementing a run configuration, you may want to use one of the common bas
|
||||
|
||||
That common run configuration settings might be modified via:
|
||||
|
||||
[`RunConfiguration`-specific UI](upsource:///platform/lang-api/src/com/intellij/execution/configurations/RunConfiguration.java)<!--#L48-->. That is handled by [`SettingsEditor`](upsource:///platform/platform-api/src/com/intellij/openapi/options/SettingsEditor.java)<!--#L97-->:
|
||||
[`RunConfiguration`-specific UI](upsource:///platform/lang-api/src/com/intellij/execution/configurations/RunConfiguration.java). That is handled by [`SettingsEditor`](upsource:///platform/platform-api/src/com/intellij/openapi/options/SettingsEditor.java)<!--#L97-->:
|
||||
|
||||
* [`getComponent()`](upsource:///platform/platform-api/src/com/intellij/openapi/options/SettingsEditor.java)<!--#L97--> method is called by the IDE and shows run configuration specific UI.
|
||||
* [`resetFrom()`](upsource:///platform/platform-api/src/com/intellij/openapi/options/SettingsEditor.java)<!--#L83--> is called to discard all non-confirmed user changes made via that UI.
|
||||
* [`applyTo()`](upsource:///platform/platform-api/src/com/intellij/openapi/options/SettingsEditor.java)<!--#L93--> is called to confirm the changes, i.e. copy current UI state into the target settings object.
|
||||
* [`getComponent()`](upsource:///platform/platform-api/src/com/intellij/openapi/options/SettingsEditor.java) method is called by the IDE and shows run configuration specific UI.
|
||||
* [`resetFrom()`](upsource:///platform/platform-api/src/com/intellij/openapi/options/SettingsEditor.java) is called to discard all non-confirmed user changes made via that UI.
|
||||
* [`applyTo()`](upsource:///platform/platform-api/src/com/intellij/openapi/options/SettingsEditor.java) is called to confirm the changes, i.e. copy current UI state into the target settings object.
|
||||
|
||||
## Persistence
|
||||
|
||||
That run configuration settings are persistent, i.e. they are stored at file system and loaded back on the IDE startup. That is performed via [`writeExternal()`](upsource:///platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java)<!--#L27--> and [`readExternal()`](upsource:///platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java)<!--#L26--> methods of [`RunConfiguration`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/RunConfiguration.java) class correspondingly.
|
||||
That run configuration settings are persistent, i.e. they are stored at file system and loaded back on the IDE startup. That is performed via [`writeExternal()`](upsource:///platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) and [`readExternal()`](upsource:///platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java)<!--#L26--> methods of [`RunConfiguration`](upsource:///platform/lang-api/src/com/intellij/execution/configurations/RunConfiguration.java) class correspondingly.
|
||||
|
||||
The actual configurations stored by the *IntelliJ Platform* are represented by instances of the [`RunnerAndConfigurationSettings`](upsource:///platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java) class, which combines a run configuration with runner-specific settings, as well as keeping track of certain run configuration flags such as "temporary" or "singleton".
|
||||
|
||||
|
@ -47,8 +47,8 @@ The same threading requirements also apply to functions like [`LocalFileSystem.r
|
||||
|
||||
In nearly all cases, using asynchronous refreshes is strongly preferred. If there is some code that needs to be executed after the refresh is complete, the code should be passed as a `postRunnable` parameter to one of the refresh methods:
|
||||
|
||||
* [`RefreshQueue.createSession()`](upsource:///platform/analysis-api/src/com/intellij/openapi/vfs/newvfs/RefreshQueue.java)<!--#L36-->
|
||||
* [`VirtualFile.refresh()`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java)<!--#L681-->
|
||||
* [`RefreshQueue.createSession()`](upsource:///platform/analysis-api/src/com/intellij/openapi/vfs/newvfs/RefreshQueue.java)
|
||||
* [`VirtualFile.refresh()`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java)
|
||||
|
||||
Synchronous refreshes can cause deadlocks in some cases, depending on which locks are held by the thread invoking the refresh operation.
|
||||
|
||||
@ -56,7 +56,7 @@ Synchronous refreshes can cause deadlocks in some cases, depending on which lock
|
||||
|
||||
All changes happening in the virtual file system, either as a result of refresh operations or caused by user's actions, are reported as _virtual file system events_. VFS events are always fired in the event dispatch thread, and in a write action.
|
||||
|
||||
The most efficient way to listen to VFS events is to implement [`BulkFileListener`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/newvfs/BulkFileListener.java) and to subscribe with it to the [`VirtualFileManager.VFS_CHANGES`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java)<!--#L34--> topic.
|
||||
The most efficient way to listen to VFS events is to implement [`BulkFileListener`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/newvfs/BulkFileListener.java) and to subscribe with it to the [`VirtualFileManager.VFS_CHANGES`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java) topic.
|
||||
A non-blocking variant [`AsyncFileListener`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/AsyncFileListener.java) is also available in 2019.2 or later.
|
||||
See [How do I get notified when VFS changes?](/basics/architectural_overview/virtual_file.md#how-do-i-get-notified-when-vfs-changes) for implementation details.
|
||||
|
||||
@ -64,6 +64,6 @@ See [How do I get notified when VFS changes?](/basics/architectural_overview/vir
|
||||
|
||||
VFS events are sent both before and after each change, and you can access the old contents of the file in the before event. Note that events caused by a refresh are sent after the changes have already occurred on disk - so when you process the `beforeFileDeletion` event, for example, the file has already been deleted from disk. However, it is still present in the VFS snapshot, and you can access its last contents using the VFS API.
|
||||
|
||||
Note that a refresh operation fires events only for changes in files that have been loaded in the snapshot. For example, if you accessed a `VirtualFile` for a directory but never loaded its contents using [`VirtualFile.getChildren()`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java)<!--#L135-->, you may not get `fileCreated` notifications when files are created in that directory.
|
||||
Note that a refresh operation fires events only for changes in files that have been loaded in the snapshot. For example, if you accessed a `VirtualFile` for a directory but never loaded its contents using [`VirtualFile.getChildren()`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java), you may not get `fileCreated` notifications when files are created in that directory.
|
||||
|
||||
If you loaded only a single file in a directory using `VirtualFile.findChild()`, you will get notifications for changes to that file, but you may not get created/deleted notifications for other files in the same directory.
|
||||
|
@ -16,7 +16,7 @@ Creating a fully correct AST node from scratch is quite difficult.
|
||||
Thus, surprisingly, the easiest way to get the replacement node is to create a dummy file in the custom language so that it would contain the necessary node in its parse tree, build the parse tree and extract the necessary node from it.
|
||||
|
||||
**Example:**
|
||||
[`setName()`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java)<!--#L58-->
|
||||
[`setName()`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java)
|
||||
implementation for a
|
||||
[Properties language plugin](upsource:///plugins/properties)
|
||||
|
||||
|
@ -12,7 +12,7 @@ In addition to that, to support _Safe Delete_, a plugin needs to implement two t
|
||||
interface, registered in the `com.intellij.lang.refactoringSupport` extension point, and the `isSafeDeleteAvailable()` method, which checks if the _Safe Delete_ refactoring is available for a specific PSI element
|
||||
|
||||
* The
|
||||
[`PsiElement.delete()`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java)<!--#L371-->
|
||||
[`PsiElement.delete()`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java)
|
||||
method for the
|
||||
[`PsiElement`](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java)
|
||||
subclasses for which _Safe Delete_ is available.
|
||||
@ -20,7 +20,7 @@ In addition to that, to support _Safe Delete_, a plugin needs to implement two t
|
||||
|
||||
|
||||
**Example:**
|
||||
[`delete()`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java)<!--#L363-->
|
||||
[`delete()`](upsource:///plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java)
|
||||
implementation for a Property in
|
||||
[Properties language plugin](upsource:///plugins/properties/)
|
||||
|
||||
|
@ -26,7 +26,7 @@ To reuse the *IntelliJ Platform* implementation of the
|
||||
the plugin returns a
|
||||
[`TreeBasedStructureViewBuilder`](upsource:///platform/editor-ui-api/src/com/intellij/ide/structureView/TreeBasedStructureViewBuilder.java)
|
||||
from its
|
||||
[`PsiStructureViewFactory.getStructureViewBuilder()`](upsource:///platform/editor-ui-api/src/com/intellij/lang/PsiStructureViewFactory.java)<!--#L35-->
|
||||
[`PsiStructureViewFactory.getStructureViewBuilder()`](upsource:///platform/editor-ui-api/src/com/intellij/lang/PsiStructureViewFactory.java)
|
||||
method.
|
||||
As the model for the builder, the plugin can specify a subclass of
|
||||
[`TextEditorBasedStructureViewModel`](upsource:///platform/editor-ui-api/src/com/intellij/ide/structureView/TextEditorBasedStructureViewModel.java),
|
||||
|
@ -13,10 +13,10 @@ objects, defining specific templates which can be used for surrounding the selec
|
||||
|
||||
When the _Surround With_ action is invoked, the IDE queries all surround descriptors for the language until it finds one that returns a non-empty array from its `getElementsToSurround()` method.
|
||||
Then it calls the
|
||||
[`Surrounder.isApplicable()`](upsource:///platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java)<!--#L46-->
|
||||
[`Surrounder.isApplicable()`](upsource:///platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java)
|
||||
method for each surrounder in that descriptor to check if the specific template is applicable in the current context.
|
||||
Once the user selects a specific surrounder from the popup menu, the
|
||||
[`Surrounder.surroundElements()`](upsource:///platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java)<!--#L57-->
|
||||
[`Surrounder.surroundElements()`](upsource:///platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java)
|
||||
method is used to execute the surround action.
|
||||
|
||||
**Example:**
|
||||
|
@ -108,7 +108,7 @@ public void doChange(Context context) {
|
||||
*Existing resources*
|
||||
|
||||
* *MessageBus* instances are available via
|
||||
[`ComponentManager.getMessageBus()`](upsource:///platform/extensions/src/com/intellij/openapi/components/ComponentManager.java)<!--#L85-->
|
||||
[`ComponentManager.getMessageBus()`](upsource:///platform/extensions/src/com/intellij/openapi/components/ComponentManager.java)
|
||||
(many standard interfaces implement it, e.g.
|
||||
[`Application`](upsource:///platform/core-api/src/com/intellij/openapi/application/Application.java),
|
||||
[`Project`](upsource:///platform/core-api/src/com/intellij/openapi/project/Project.java);
|
||||
|
Loading…
x
Reference in New Issue
Block a user