Merge pull request #179 from JetBrains/revert-174-IJSDK-473

Revert "IJSDK-473"
This commit is contained in:
John Hake 2019-06-17 21:11:33 -07:00 committed by GitHub
commit f1a689c8d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
106 changed files with 1521 additions and 1463 deletions

1
.gitignore vendored
View File

@ -37,7 +37,6 @@ _includes
### Gradle template
.gradle
build/
_idea-sandbox/
# Ignore Gradle GUI config
gradle-app.setting

16
.idea/gradle.xml generated
View File

@ -2,17 +2,6 @@
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$/code_samples/action_basics" />
<option name="gradleHome" value="C:/Program Files (x86)/Gradle/gradle-2.9" />
<option name="gradleJvm" value="1.8 202b1483.58" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$/code_samples/action_basics" />
</set>
</option>
</GradleProjectSettings>
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$/code_samples/gradle_plugin_demo" />
@ -23,6 +12,11 @@
<option value="$PROJECT_DIR$/code_samples/gradle_plugin_demo" />
</set>
</option>
<option name="myModules">
<set>
<option value="$PROJECT_DIR$/code_samples/gradle_plugin_demo" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>

View File

@ -5,7 +5,6 @@
<excludeFolder url="file://$MODULE_DIR$/.bundle" />
<excludeFolder url="file://$MODULE_DIR$/.git-metadata" />
<excludeFolder url="file://$MODULE_DIR$/_site" />
<excludeFolder url="file://$MODULE_DIR$/code_samples/_idea-sandbox" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />

7
.idea/misc.xml generated
View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="IU-191.7479.19" project-jdk-type="IDEA JDK">
<output url="file://$PROJECT_DIR$/Build" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="false" assert-keyword="true" jdk-15="true" project-jdk-name="IntelliJ IDEA IU-144.3600.7" project-jdk-type="IDEA JDK">
<output url="file://$PROJECT_DIR$/build" />
</component>
</project>

View File

@ -1,46 +1,30 @@
---
title: Contributing
title: Contributing to the IntelliJ Platform SDK
---
Thanks for contributing! Here are a few useful things to know before submitting your Pull Request.
This document describes our contribution guidelines for the open source IntelliJ Platform SDK documentation and sample code.
Before you begin contributing content to the SDK, please read this page thoroughly as well as the [Code of Conduct](/CODE_OF_CONDUCT.md) and [License](https://github.com/JetBrains/intellij-sdk-docs/blob/master/LICENSE.txt) documents.
For information about contributing to the IntelliJ Platform itself, please visit [Contributing to the IntelliJ Platform](/basics/platform_contributions.md).
* Licensing - see [LICENSE.txt](LICENSE.txt)
* [Contributing to the IntelliJ Platform](#contributing-to-the-intellij-platform)
* [Setting up your environment](#setting-up-your-environment)
* [Developing with Docker](#developing-with-docker)
* [Developing locally](#developing-locally)
* [Markup](#markup)
* [_SUMMARY.md](#summarymd)
* [Redirects](#redirects)
* [Table of contents](#table-of-contents)
* [Liquid tags and filters](#liquid-tags-and-filters)
* [Syntax highlighting](#syntax-highlighting)
* [Tables](#tables)
* [Links](#links)
* [Callouts](#notes-and-callouts)
* [Images](#images)
* Style guide
* [A word on submodules](#a-word-on-submodules)
## Contributing to the IntelliJ Platform
This document describes our contribution guidelines for the IntelliJ SDK Docs. For information about contributing to the IntelliJ Platform, please visit [Contributing to the IntelliJ Platform](/basics/platform_contributions.md).
## Setting up your environment
Here are some useful things to know before authoring SDK content and submitting your Pull Request.
* Dummy list item
{:toc}
## Setting Up the Documentation Build Environment
This site runs via [Jekyll](https://jekyllrb.com), which is a popular static site generator, written in Ruby. It can be hosted locally to ensure that any changes are correct. Once set up, running the site is as easy as calling `rake preview`.
Alternatively, the site can also be hosted in a [Docker container](https://www.docker.com). On Mac and Windows, this means the site is hosted in a virtual machine. Docker maintains this container, building it based on the instructions in the [`Dockerfile`](Dockerfile). All dependencies (Ruby, etc.) are automatically installed when building the image, which reduces the manual configuration steps. The Docker image is also used to build the [published site](https://www.jetbrains.org/intellij/sdk/docs/index.html), so it is a known working environment.
### Developing with Docker
### Developing Documentation with Docker
Follow these steps to work with Docker:
* Firstly, install Docker, using the [Docker Toolbox](https://www.docker.com/docker-toolbox).
* On Windows and Mac, start the Docker host virtual machine (start the "Docker Quickstart terminal" or run "Kitematic". See the Getting Started guides on [docker.com](https://www.docker.com) for more details).
* On Windows and Mac, start the Docker host virtual machine (start the "Docker Quickstart terminal" or run "Kitematic." See the Getting Started guides on [docker.com](https://www.docker.com) for more details).
* Clone the [`intellij-sdk-docs`](https://github.com/JetBrains/intellij-sdk-docs) repo to the local machine, and [initialise the `sdkdocs-template` submodule](#a-word-on-submodules).
* Change the current directory to the parent directory of the git repo.
* Run `docker build -t intellij-sdk-docs .`. This will build the docker image from the current folder, and give it the tag `intellij-sdk-docs`.
* Run `docker build -t intellij-sdk-docs .` to build the docker image from the current folder, and give it the tag `intellij-sdk-docs`.
* Note that this must be run from a command prompt that has the various `DOCKER_*` environment variables set up, such as the Docker Quickstart Terminal.
* Run `docker run -p 4000:4000 -v $PWD:/usr/src/app intellij-sdk-docs`. This command will:
* Start the docker container called `intellij-sdk-docs`.
@ -52,33 +36,35 @@ Follow these steps to work with Docker:
>
> Alternatively, modify the virtual machine's settings to automatically forward port 4000 to `localhost`. See this [blog post](https://acaird.github.io/computers/2014/11/16/docker-virtualbox-host-networking) for more details.
* Mount the current directory (`$PWD` is a Unix style environment variable. You can use `%CD%` on Windows, or specify the full path) as `/usr/src/app` inside the docker container. This means the docker image will see the `intellij-sdk-docs` repo as the folder `/usr/src/app`.
* Mount the current directory (`$PWD` is a Unix style environment variable. You can use `%CD%` on Windows, or specify the full path) as `/usr/src/app` inside the docker container. The docker image will see the `intellij-sdk-docs` repo as the folder `/usr/src/app`.
> **NOTE** If running on Windows in an msys bash script (e.g. the "Docker Quickstart terminal"), the path to the local folder needs to be properly escaped, or the msys environment will translate the paths to standard Windows path, and you will see an error such as `invalid value "C:\\Users\\...;C:\\Program Files\\Git\\usr\\src\\app" for flag -v`. To fix this, prefix the full path with double slashes, e.g. `-v //c/Users/...`, or `docker run -p 4000:4000 -v /$PWD:/usr/src/app intellij-sdk-docs` (note the leading slash before `$PWD`).
> **NOTE** If running on Windows in an MSYS bash script (e.g. the "Docker Quickstart terminal"), the path to the local folder needs to be properly escaped, or the MSYS environment will translate the paths to standard Windows path, and causing an error such as `invalid value "C:\\Users\\...;C:\\Program Files\\Git\\usr\\src\\app" for flag -v`. To fix this problem, prefix the full path with double slashes, e.g. `-v //c/Users/...`, or `docker run -p 4000:4000 -v /$PWD:/usr/src/app intellij-sdk-docs` (note the leading slash before `$PWD`).
* Run the commands specific in the Dockerfile's `CMD` instruction, which runs both `rake bootstrap`, which ensures all of the prerequisites are installed, and `rake preview`, which builds the site and starts to host it.
* Finally, you can access the newly created site by visiting [http://localhost:4000/intellij/sdk/docs/](http://localhost:4000/intellij/sdk/docs/), or by using the IP address of the docker client virtual machine (see note above).
* Run the commands in the Dockerfile's `CMD` instruction to execute:
* `rake bootstrap`, which ensures all of the prerequisites are installed,
* `rake preview`, which builds the site and starts to host it.
* Finally, you can access the newly created site by visiting [http://localhost:4000/intellij/sdk/docs/](http://localhost:4000/intellij/sdk/docs/), or by using the IP address of the docker client virtual machine (see the note above).
### Developing locally
### Developing Documentation Locally
To build the documentation site, you will need:
To build the documentation site, you need:
* Ruby 2 - Jekyll is a Ruby application.
* Ruby 2 DevKit (for Windows) - Some of Jekyll's dependencies need to be compiled, and require the DevKit to be installed.
* `gem install bundler` - the site uses [Bundler](https://bundler.io) to manage gem dependencies within the repo, rather than globally installing to the local operating system. Run this command to install the Bundler toolset globally.
**OS X**
#### macOS
OS X comes with Ruby already installed. The only steps required are:
macOS comes with Ruby already installed. The only steps required are:
* `gem install bundler`
**Windows**
#### Windows
* Install [Ruby 2](https://rubyinstaller.org) and the [Ruby 2 DevKit](http://rubyinstaller.org/downloads/) (one of the gems needs to build a native component)
* After installing the DevKit, make sure to edit the `config.yml` file to point to the Ruby installation
This is made easier if you use [Chocolatey](https://chocolatey.org), a package manager for Windows:
This installation is easier if you use [Chocolatey](https://chocolatey.org), a package manager for Windows:
* `choco install ruby`
* `choco install ruby2.devkit`
@ -88,202 +74,54 @@ This is made easier if you use [Chocolatey](https://chocolatey.org), a package m
> **NOTE** Before running the `rake bootstrap` step listed below, please run the `devkitvars.bat` file from the DevKit. E.g. `C:\tools\DevKit\devkitvars.bat`
### Bootstrapping the environment
### Bootstrapping the Documentation Build Environment
1. Ensure Bundler is installed - `gem install bundler`
1. Ensure Bundler is installed - `gem install bundler`.
2. On Windows, ensure the `devkitvars.bat` file has been run in the current command prompt (e.g. `c:\tools\DevKit\devkitvars.bat`).
3. Clone the documentation site.
4. Initialise and update the `sdkdocs-template` submodule - `git submodule init` and `git submodule update`
4. Initialize and update the `sdkdocs-template` submodule - `git submodule init` and `git submodule update`
5. `rake bootstrap` - this uses Bundler to download all required gems.
6. `rake preview` - this will build the site, and host it in a local webserver.
6. `rake preview` - this will build the site, and host it in a local webserver.
### Building and previewing the site
### Building and Previewing the Site
To build and test the site, simply run `rake preview`. This will build the site and host it, using the config provided. The URL of the hosted site is displayed on the screen and depends on the `baseurl` field defined in `_config.yml`.
To build and test the site, run `rake preview`. This will build the site and host it, using the config provided. The URL of the hosted site is displayed on the screen and depends on the `baseurl` field defined in `_config.yml`.
> **NOTE** You must use `localhost` as hostname, otherwise fonts will fail to load.
> **NOTE** You must use `localhost` as hostname, _NOT_ 0.0.0.0, otherwise fonts fail to load.
## Markup
## Documentation Repository Submodules
The `sdkdocs-template` directory is actually a Git submodule, and it contains a submodule to the private `webhelp-template` repository.
The `sdkdocs-template` repository contains build scripts and compiled and minified JS and CSS that allow the site to run.
The private `webhelp-template` repository contains the code to build the JS and CSS.
It is currently closed source, but the plan is to make it open source at some point, in which case it is likely the two repositories will be merged.
By default, when building the site, all files are copied to the destination `_site` folder. Some files are excluded in the `_config.yml` and `sdkdocs-template/jekyll/_config-defaults.yml` files. The documentation files themselves are [Markdown](https://daringfireball.net/projects/markdown/) files (`.md`) that get automatically converted to HTML when the site is built.
After cloning, a submodule needs to be initialized and updated:
However, only markdown files beginning with a [YAML](https://yaml.org) header are converted. If the markdown file doesn't contain a header, it won't be converted. In other words, to convert a `.md` file to HTML, it should look like this:
```md
---
---
# Introduction
Lorem ipsum...
```sh
git submodule init
git submodule update
```
The two lines at the top of the file are the markers of the YAML "front matter". Fields can be added in between these markers, and are used when generating the HTML. Typically, this header will be empty, although it is required by Jekyll (if omitted, the file isn't converted).
Initialization creates a `.gitmodules` file, register a submodule in the `sdkdocs-template` folder and check out the files.
Note that when a repo is added as a submodule, it doesn't get a `.git` folder, but instead gets a `.git` file that points to the actual location of the `.git` folder.
The YAML header can contain data that is used when generating the site. For example, the page title can be specified as a simple piece of markdown - `# Title`, or it can be specified in the YAML, and the page template will display it appropriately:
A submodule can be updated using normal git commands such as `git pull`.
It can be switched to a different branch using `git checkout`, and any changes to the currently checked out revision need to be committed back into the main repository using git commands.
A submodule is initially cloned at a specific revision, and not as part of a branch.update
```md
---
title: The Title Of The Page
---
Lorem ipsum...
```
The YAML header can also include [redirect](#redirects) information.
### _SUMMARY.md
The table of contents for the site is displayed in the tree view on the left-hand side of the site, and it is generated from the `_SUMMARY.md` file. It is a simple markdown list, with each item in the list being a link to another markdown page, either in the root folder, or sub-folders. The list can have nested items, which will be displayed as child items in the table of contents.
```md
# Summary
* [Introduction](README.md)
* [About This Guide](Intro/About.md)
* [Key Topics](Intro/KeyTopics.md)
```
The contents can be split into "parts" by separating the list into several lists, each new list starting with a level 2 heading (`##`).
```md
# Summary
* [Introduction](README.md)
* [About This Guide](Intro/About.md)
* [Key Topics](Intro/KeyTopics.md)
## Part I - Extending the Platform
* [Getting Started](Docs/GettingStarted.md)
* ...
```
If a node doesn't have a link, but is just plain text, it will still appear in the table of contents but will be greyed out and not clickable. It acts as a placeholder for a documentation item. This is useful to keep track of what should be documented, but hasn't yet, and can be useful to show readers that the topic exists, but isn't yet documented (Pull Requests always welcome!).
### Redirects
The documentation site is set up to include the [jekyll-redirect-from](https://github.com/jekyll/jekyll-redirect-from) plugin, which will generate "dummy" pages that automatically redirect to a given page. For example, to specify that the `index.html` page will be generated to redirect to `README.md`, the `README.md` file should include the following in the YAML header:
```md
---
redirect_from:
- /index.html
---
# Introduction
Lorem ipsum...
```
This will create an `index.html` file that will automatically redirect to the generated `README.html` file. This is very useful to allow the site URL to automatically show the `README.html` file - `http://localhost:4001/foo-test/` will try to load `index.html`, which will automatically redirect to `README.html`.
It is also useful to redirect when renaming or moving files. Multiple redirects can be added to the YAML header.
### Table of contents
The site is configured to use the [Kramdown Markdown converter](http://kramdown.gettalong.org), which adds some extra features over traditional markdown, such as "attribute lists", which can apply attributes to the generated elements.
One useful attribute is `{:toc}`, which can be applied to a list item, which will get replaced with a list of links to header items. E.g. the following list item will be replaced by links to all of the header items in the page:
```md
* Dummy list item
{:toc}
```
Further Kramdown features are described on the [converter page](https://kramdown.gettalong.org/converter/html.html), and attribute lists are described on the [syntax page](http://kramdown.gettalong.org/syntax.html). Note that source code formatting is configured to use [GitHub Flavoured Mardown](https://help.github.com/articles/github-flavored-markdown/) and "code fences", see below.
### Liquid tags and filters
Jekyll uses the [Liquid](https://shopify.github.io/liquid/) templating language to process files. This means standard Liquid tags and filters are available. There should be little need to use them, however, as the Markdown format is already quite rich. See the [Jekyll site](http://jekyllrb.com/docs/templates/) for more details.
### Syntax highlighting
Source code can be represented by using [GitHub Flavoured Markdown](https://help.github.com/articles/github-flavored-markdown/) code fences, which are three backticks:
```
// Source code goes here...
```
Syntax highlighting can be applied by specifying the language after the first set of ticks:
```csharp
// Some C# code
```
```java
// Some Java code
```
Here is the list of [supported languages](https://github.com/jneen/rouge/wiki/List-of-supported-languages-and-lexers) (and also [Kotlin](https://kotlinlang.org), of course).
Please keep code samples concise and avoid any unnecessary "surrounding" code or import statements.
<!-- Not currently supported by rouge, or by the site's CSS
The site is also configured to highlight a range of files in the source code, by specifying `{start-end}` which is the start and end line of the highlighting:
```java{2-3}
// Not highlighted
// Highlighted
// Highlighted
// Not highlighted
```
-->
### Tables
The Kramdown parser also supports tables. The syntax is to use the pipe (`|`) and minus symbols:
```md
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Blah | Blah | Blah |
```
### Links
Links are handled as normal markdown links and can be linked to external sites, pages within the sites, or headings in the sites. When a Markdown header is converted to an HTML header, it is assigned an ID, so it can be linked, e.g. `## Introduction` will get the ID of `introduction`, and can be linked either in the same page `[click here](#introduction)` or cross-page `[click here](page.html#introduction)`. The anchor name will be all lower case, and spaces are replaced with `-`, e.g. `## Page setup` becomes `#page-setup`.
* `[External site](http://example.org)` will link to an external site
* `[Other page in current directory](Page2.md)` will link to a page in the same directory as the current page. Note that the extension is `.md`, NOT `.html`.
* `[Page in another folder](/Folder2/Page2.md)` will link to a page in another folder. Note that the URL is navigating from root - this works even if the site is hosted in a sub-folder (e.g. this link will work for `http://localhost:4000/devguide/Folder2/Page2.html`). Relative links will also work (`../Folder2/Page2.md`).
* `[Link to section on another page](Page2.md#another-section)` will link to a heading on another page. The ID of the heading is generated by making the text lowercase and replacing spaces with `-`.
* `[Link to section on current page](#another-section)` will link to a heading on the current page.
### Notes and callouts
Notes and callouts can be specified using the blockquote syntax. The converter will look at the first following word to see if it is bold. If so, it will apply that as a callout style. For example:
> **NOTE** This is a note
Will be displayed as a callout, styled as a "note". The other styles available for callouts are "note", "warning", "tip" and "todo".
### Images
Images can be included by adding the file directly to the repository and adding a link to the image like so:
![Alt text](path-to-img.png)
Please, downscale screenshots made at high resolution.
![Alt text](path-to-img.png){:width="42px"}
## A word on submodules
The `sdkdocs-template` repo is added as a submodule, and it also contains a submodule to the private `webhelp-template` repo. The `sdkdocs-template` repo contains build time scripts and compiled and minified JS and CSS that allow the site to run. The private `webhelp-template` repo contains the code to build the JS and CSS. It is currently closed source, but the plan is to make it open source at some point, in which case, it is likely the two repos will be merged.
After cloning, a submodule needs to be initialised and updated:
```
git submodule init
git submodule update
```
This will create a `.gitmodules` file, register a submodule in the `sdkdocs-template` folder, and check out the files. (Note that when a repo is added as a submodule, it doesn't get a `.git` folder, but instead gets a `.git` file that points to the location of the `.git` folder.
A submodule can be updated using normal git commands such as `git pull`. It can be switched to a different branch using `git checkout`, and any changes to the currently checked out revision need to be committed back into the main repo, as normal git commands. It is initially cloned at a specific revision, and not as part of a branch.update
If changes are made to the submodule, they should be made on a branch to a clone, and a Pull Request sent. Changes can be made and committed, and the hosting repo will need to commit a pointer to the current version of the submodule.
If changes are made to the submodule, they should be made on a branch to a clone, and a Pull Request sent.
Changes can be made and committed, and the hosting repository will need to commit a pointer to the current version of the submodule.
If there are any problems with the `sdkdocs-template`, please [raise an issue](https://github.com/JetBrains/sdkdocs-template/issues).
## Creating IntelliJ Platform SDK Content
Content contributions to the IntelliJ Platform SDK are welcome.
Please download or clone the open source SDK project from [GitHub](https://github.com/JetBrains/intellij-sdk-docs), make additions or changes, and submit a pull request.
Before creating or altering content, please consult these guides:
* [SDK Documentation Style Guide](intro/sdk_style.md).
This guide describes documentation conventions in terms of Markdown syntax.
Always test documentation changes using a [preview](#building-and-previewing-the-site) of the site.
* [SDK Code Sample Guidelines](intro/sdk_code_guidelines.md).
Conventions for code sample organization, project settings, and naming conventions are described in this document.
Always test code changes by building and testing the SDK code sample.

View File

@ -3,12 +3,15 @@
* [Introduction](welcome.md)
* [The IntelliJ Platform](intro/intellij_platform.md)
* [Contributing to the IntelliJ Platform](basics/platform_contributions.md)
* [IntelliJ Coding Guidelines](basics/intellij_coding_guidelines.md)
* [About this Guide](intro/about.md)
* [IntelliJ Platform Coding Guidelines](basics/intellij_coding_guidelines.md)
* [The IntelliJ Platform SDK](intro/about.md)
* [Key Topics](intro/key_topics.md)
* [Contributing](CONTRIBUTING.md)
* [Contributing to the SDK](CONTRIBUTING.md)
* [SDK Docs Style Guide](intro/sdk_style.md)
* [SDK Code Sample Guidelines](intro/sdk_code_guidelines.md)
* [Code of Conduct](CODE_OF_CONDUCT.md)
* [Getting Help](intro/getting_help.md)
* [Recently Updated](recently_updated.md)
## Part I - Plugins
* [Introduction](basics.md)
@ -16,7 +19,6 @@
* [Getting Started](basics/getting_started.md)
* [Using Gradle](tutorials/build_system.md)
* [Getting Started with Gradle](tutorials/build_system/prerequisites.md)
* [Configuring Gradle Projects](tutorials/build_system/gradle_guide.md)
* [Publishing Your Plugin](tutorials/build_system/deployment.md)
* [Using DevKit](basics/getting_started/using_dev_kit.md)
* [Setting Up a Development Environment](basics/getting_started/setting_up_environment.md)
@ -25,6 +27,7 @@
* [Running and Debugging a Plugin](basics/getting_started/running_and_debugging_a_plugin.md)
* [Deploying a Plugin](basics/getting_started/deploying_plugin.md)
* [Publishing a Plugin](basics/getting_started/publishing_plugin.md)
* [IDE Development Instances](basics/ide_development_instance.md)
* [Custom Plugin Repositories](basics/getting_started/update_plugins_format.md)
* [Plugin Structure](basics/plugin_structure.md)
* [Plugin Content](basics/plugin_structure/plugin_content.md)
@ -44,7 +47,6 @@
* [UI Tools](reference_guide/internal_actions/internal_ui_sub.md)
* [UI Inspector](reference_guide/internal_actions/internal_uii.md)
* [Laf Defaults](reference_guide/internal_actions/internal_ui_lafd.md)
* [IDE Development Instances](basics/ide_development_instance.md)
* [Plugin Development FAQ](faq.md)
## Part II - Base Platform
@ -66,6 +68,7 @@
* [Miscellaneous Swing Components](user_interface_components/misc_swing_components.md)
* [Icons and Images](reference_guide/work_with_icons_and_images.md)
* [Color Scheme Management](reference_guide/color_scheme_management.md)
* [Kotlin UI DSL](user_interface_components/kotlin_ui_dsl.md)
* [UI Themes](reference_guide/ui_themes/themes_intro.md)
* [Creating UI Themes](reference_guide/ui_themes/themes.md)
* [Customizing a UI Theme](reference_guide/ui_themes/themes_customize.md)

View File

@ -4,7 +4,7 @@ title: Consulting
The following independent companies and individuals provide paid plugin consulting and development services.
>> **NOTE** JetBrains is not responsible for nor guarantees the performance of these independent third-party companies.
> **NOTE** JetBrains is not responsible for nor guarantees the performance of these independent third-party companies.
| Name | Contact | Notes |
|-------|---------|-------|

View File

@ -39,3 +39,7 @@ The general read/write action rules are in effect. In addition to that, any oper
If the file corresponding to a `Document` is read-only (for example, not checked out from the version control system), document modifications will fail. Thus, before modifying the `Document`, it is necessary to call `ReadonlyStatusHandler.getInstance(project).ensureFilesWritable()` to check out the file if necessary.
All text strings passed to `Document` modification methods (`setText`, `insertString`, `replaceString`) must use only \n as line separators.
## Are there any utilities available for working with Documents?
[`DocumentUtil`](upsource:///platform/core-impl/src/com/intellij/util/DocumentUtil.java) contains utility methods for `Document` processing. This allows you to get information like the text offsets of particular lines. This is particularly useful when you need text location/offset information about a given PsiElement.

View File

@ -4,7 +4,7 @@ title: PSI Elements
A PSI (Program Structure Interface) file represents a hierarchy of PSI elements (so-called _PSI trees_). A single PSI file (itself being a PSI element) may contain several PSI trees in specific programming languages. A PSI element, in its turn, can have child PSI elements.
PSI elements and operations at the level of individual PSI elements are used to explore the internal structure of source code as it is interpreted by the **IntelliJ Platform**. For example, you can use PSI elements to perform code analysis, such as [code inspections](https://www.jetbrains.com/help/idea/code-inspection.html) or [intention actions](http://www.jetbrains.com/idea/help/intention-actions.html).
PSI elements and operations at the level of individual PSI elements are used to explore the internal structure of source code as it is interpreted by the **IntelliJ Platform**. For example, you can use PSI elements to perform code analysis, such as [code inspections](https://www.jetbrains.com/help/idea/code-inspection.html) or [intention actions](https://www.jetbrains.com/idea/help/intention-actions.html).
The [PsiElement](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java) class is the common base class for PSI elements.

View File

@ -37,6 +37,12 @@ If you do need to create a file through VFS, you can use the `VirtualFile.create
The `VirtualFileManager.addVirtualFileListener()` method allows you to receive notifications about all changes in the VFS.
## Are there any utilities for analyzing and manipulating virtual files?
[`VfsUtil`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VfsUtil.java) and [`VfsUtilCore`](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java) provide utility methods for analyzing files in the Virtual File System.
You can use [`ProjectLocator`](upsource:///platform/core-api/src/com/intellij/openapi/project/ProjectLocator.java) to find the projects that contain a given virtual file.
## How do I extend VFS?
To provide an alternative file system implementation (for example, an FTP file system), implement the [VirtualFileSystem](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFileSystem.java) class (most likely you'll also need to implement `VirtualFile`), and register your implementation as an [application component](/basics/plugin_structure/plugin_components.md).

View File

@ -37,6 +37,7 @@ The following branch numbers are used for *IntelliJ Platform* based products and
| Branch number | IntelliJ Platform version |
|-----------------------------------------------------------------|---------------------------|
| [192](https://github.com/JetBrains/intellij-community/tree/192) | 2019.2 |
| [191](https://github.com/JetBrains/intellij-community/tree/191) | 2019.1 |
| [183](https://github.com/JetBrains/intellij-community/tree/183) | 2018.3 |
| [182](https://github.com/JetBrains/intellij-community/tree/182) | 2018.2 |

View File

@ -2,7 +2,7 @@
title: Creating a Plugin Project
---
>> **NOTE** For new projects, it is recommend to use [Gradle](/tutorials/build_system.md).
> **NOTE** For new projects, it is recommend to use [Gradle](/tutorials/build_system.md).
This section explains how you can create a new plugin project from scratch using the New Project wizard. Optionally, you can import an existing project or import a project from external models. You can also add a new plugin module to an existing *IntelliJ Platform* project.
For more information, refer to the [IntelliJ IDEA Web Help](https://www.jetbrains.com/idea/help/new-project-wizard.html).

View File

@ -4,7 +4,7 @@ title: Running and Debugging a Plugin
It's possible to run and debug a plugin directly from the *IntelliJ IDEA*. You need a configured special profile (a *Plugin* Run/Debug configuration) that specifies the plugin module, VM parameters and other specific options. When you run such profile, it launches the IDE with your plugin installed.
For information on how to change the Run/Debug configuration profile, refer to [Run/Debug Configuration](https://www.jetbrains.com/help/idea/run-debug-configuration.html) and [Run/Debug Configuration: Plugin](http://www.jetbrains.com/idea/help/run-debug-configuration-plugin.html) in *IntelliJ IDEA* Web Help.
For information on how to change the Run/Debug configuration profile, refer to [Run/Debug Configuration](https://www.jetbrains.com/help/idea/run-debug-configuration.html) and [Run/Debug Configuration: Plugin](https://www.jetbrains.com/idea/help/run-debug-configuration-plugin.html) in *IntelliJ IDEA* Web Help.
Using *IntelliJ IDEA*'s debugger, you can find out the origin of the run-time errors and exceptions.

View File

@ -2,7 +2,7 @@
title: Using DevKit
---
>> **NOTE** For new projects, it is recommend to use [Gradle](/tutorials/build_system.md).
> **NOTE** For new projects, it is recommend to use [Gradle](/tutorials/build_system.md).
_Plugin DevKit_ is a bundled IntelliJ IDEA plugin for developing plugins for the IntelliJ Platform using IntelliJ IDEA's
own build system. It provides its custom SDK type and a set of actions for building plugins within the IDE.

View File

@ -1,41 +1,74 @@
---
title: IDE Development Instances - Settings, Caches, Logs, and Plugins
title: IDE Development Instances
redirect_from:
- /basics/settings_caches_logs.html
---
A JetBrains feature for developing plugins is to run or debug a plugin project from within a JetBrains IDE, e.g. IntelliJ IDEA.
[Selecting the **Run** menu](https://www.jetbrains.com/help/idea/running-and-debugging-plugins.html) will launch
a _Development Instance_ of the IDE with your plugin enabled.
A JetBrains feature for developing plugins is running or debugging a plugin project from within an IntelliJ Platform-based IDE such as IntelliJ IDEA.
Selecting the [**Run**](getting_started/running_and_debugging_a_plugin.md) menu for a DevKit-based project, or the [**runIde**](/tutorials/build_system/prerequisites.md#running-a-simple-gradle-based-intellij-platform-plugin) task for a Gradle-based project will launch a _Development Instance_ of the IDE with the plugin enabled.
This page describes how to control some of the settings for the Development Instance.
The **Sandbox Home** directory contains the
[settings, caches, logs, and plugins](#development-instance-settings-caches-logs-and-plugins)
for a Development Instance of the IDE. This information is stored in a different location than for the
[installed IDE itself](https://intellij-support.jetbrains.com/hc/en-us/articles/206544519-Directories-used-by-the-IDE-to-store-settings-caches-plugins-and-logs).
## Using a JetBrains Runtime for the Development Instance
A common use case is to develop (build) a plugin project against a JDK, e.g. Java 8, and then run or debug the plugin in a Development Instance of the IDE.
In such a situation, it is important the Development Instance uses a JetBrains Runtime rather than the JDK used to build the plugin project.
The JetBrains Runtime is an environment for running IntelliJ Platform-based IDEs on Windows, macOS, and Linux.
It has some modifications by JetBrains, such as fixes for native crashes not present in official JDK builds.
A version of the JetBrains Runtime is bundled with all IntelliJ Platform-based IDEs.
To produce accurate results while running or debugging a plugin project in a Development Instance, follow the procedures below to ensure the Development Instance uses a JetBrains Runtime.
### Determining a JetBrains Runtime Version
The JetBrains Runtime is determined from the JDK version used to build the plugin project.
If a plugin is being developed against the Java 8 SE Development Kit 8 for macOS, for example, `jdk-8u212-macosx-x64.dmg`.
(This example will use macOS, but Windows and Linux follow the same procedure.)
To acquire the compatible JetBrains Runtime:
* Go to the [JetBrains Bintray site](https://bintray.com/jetbrains/intellij-jbr).
* Select the package name corresponding to the platform and SDK version.
In this case the package name is `jbrsdk8-osx-x64` for **j**et **b**rains **r**untime _sdk_ version 8, maxOS x64 hardware.
* On the macOS package page of the JetBrains Bintray site, select the **Files** menu.
* In the list of files, find the name that satisfies:
* The version and build number match the JDK used to build the plugin project.
For example, `jbrx-8u212-osx-x64` matches the Java 8 JDK, build 212: `jdk-8u212-macosx-x64`.
* Pick the highest JetBrains Runtime build number available.
For example, as of this writing, the file is `jbrx-8u212-osx-x64-b1566.8.tar.gz`, meaning build 1566.8 for this JetBrains Runtime matching Java 8 JDK build 212.
### Setting a JetBrains Runtime for Gradle-Based Plugin Projects
By default, the Gradle plugin will fetch and use the version of the JetBrains Runtime for the Development Instance corresponding to the version of the IntelliJ Platform used for building the plugin project.
In this situation no additional configuration is required.
### Setting a JetBrains Runtime for DevKit-Based Plugin Projects
The [Run Configuration](https://www.jetbrains.com/help/idea/creating-and-editing-run-debug-configurations.html#edit) for a DevKit-based plugin project controls the JDK used to run and debug a plugin project in a Development Instance.
The default Run Configuration uses the same JDK for building the plugin project and running the plugin in a Development Instance.
To change the runtime for the Development Instance, set the _JRE:_ field in the Run Configuration edit dialog to use a downloaded JetBrains Runtime.
Continuing from the example [above](#determining-a-jetbrains-runtime-version), the _JRE:_ field is set to use `jbrx-8u212-osx-x64-1566_8`
![Setting Run Configuration JRE](img/jbr_runconfig.png){:width="900px"}
## The Development Instance Sandbox Directory
The _Sandbox Home_ directory contains the [settings, caches, logs, and plugins](#development-instance-settings-caches-logs-and-plugins) for a Development Instance of the IDE.
This information is stored in a different location than for the [installed IDE itself](https://intellij-support.jetbrains.com/hc/en-us/articles/206544519-Directories-used-by-the-IDE-to-store-settings-caches-plugins-and-logs).
### Sandbox Home Location for Gradle-Based Plugin Projects
For Gradle-based plugins, the default **Sandbox Home** location is defined by the IntelliJ Platform `gradle-intellij-plugin`.
See [Configuring a Gradle Plugin Project](/tutorials/build_system/prerequisites.md)
for more information about specifying a **Sandbox Home** location. The default **Sandbox Home** location
for Gradle-based plugin projects is:
For Gradle-based plugins, the default Sandbox Home location is defined by the IntelliJ Platform `gradle-intellij-plugin`.
See [Configuring a Gradle Plugin Project](/tutorials/build_system/prerequisites.md) for more information about specifying a Sandbox Home location.
The default Sandbox Home location for Gradle-based plugin projects is:
* **Windows** `<Project Dir>\build\idea-sandbox`
* **Linux or macOS** `<Project Dir>/build/idea-sandbox`
### Sandbox Home Location for DevKit-Based Plugin Projects
For DevKit-based plugins, the default **Sandbox Home** location is defined in the IntelliJ Platform Plugin SDK.
For DevKit-based plugins, the default Sandbox Home location is defined in the IntelliJ Platform Plugin SDK.
See specifying the [Sandbox Home for DevKit Projects](/basics/getting_started/setting_up_environment.md) for more information.
The default **Sandbox Home** directory location for DevKit-based plugin projects is:
The default Sandbox Home directory location for DevKit-based plugin projects is:
* **Windows:** `<User home>\.<product_system_name><product_version>\system\plugins-sandbox\`
* **Linux:** `~/.<product_system_name><product_version>/system/plugins-sandbox/`
* **macOS** `~/Library/Caches/<product_system_name><product_version>/plugins-sandbox/`
### Development Instance Settings, Caches, Logs, and Plugins
Within the **Sandbox Home** directory are subdirectories pertaining to the Development Instance:
Within the Sandbox Home directory are subdirectories pertaining to the Development Instance:
* `config` contains settings for the IDE instance.
* `plugins` contains folders for each plugin being run in the IDE instance.
* `system/caches` or `system\caches` holds the IDE instance data.
* `system/log` or `system\log` contains the `idea.log` file for the IDE instance.
Each of these **Sandbox Home** subdirectories can be manually cleared to reset the IDE Development Instance.
At the next launch of a Development Instance the subdirectories will be repopulated with the appropriate information.
Each of these Sandbox Home subdirectories can be manually cleared to reset the IDE Development Instance.
At the next launch of a Development Instance, the subdirectories will be repopulated with the appropriate information.

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

View File

@ -1,5 +1,5 @@
---
title: IntelliJ Coding Guidelines
title: IntelliJ Platform Coding Guidelines
---
If you are writing code that you would like to contribute to the IntelliJ Platform (either as a patch or as a plugin), following these guidelines will make it easier for the JetBrains development team to review and accept your changes.

View File

@ -103,7 +103,7 @@ The simplest ways of specifying the `@Storage` annotation are as follows (since
By specifying a different value for the `value` parameter (`file` before 2016.x), the state will be persisted in a different file.
>> **NOTE** For application-level components it is strongly recommended to use a custom file, using of `other.xml` is deprecated.
> **NOTE** For application-level components it is strongly recommended to use a custom file, using of `other.xml` is deprecated.
The `roamingType` parameter of the `@Storage` annotation specifies the roaming type when the Settings Repository plugin is used.

View File

@ -8,46 +8,56 @@ The following is a sample plugin configuration file. This sample showcases and d
<!-- `url` specifies the URL of the plugin homepage (can be opened from "Plugins" settings dialog) -->
<idea-plugin url="https://www.jetbrains.com/idea">
<!-- Plugin name -->
<!-- Plugin name. It should be short and descriptive but does
not have to be identical to the name of the JAR file.
Displayed in the "Plugins" settings dialog and the plugin repository Web interface. -->
<name>VssIntegration</name>
<!-- Unique identifier of the plugin.
<!-- Unique identifier of the plugin. Should be FQN.
Cannot be changed between the plugin versions.
If not specified, assumed to be equal to <name>. -->
If not specified, assumed to be equal to <name>. This can have brittle results. -->
<id>com.jetbrains.vssintegration</id>
<!-- Description of the plugin. -->
<description>Vss integration plugin</description>
<!-- Description of the plugin.
Should be short and to the point.
Start the description with a verb in present simple form such as
"integrates", "synchronizes", "adds support for" or "lets you view".
Dont use marketing adjectives like “simple”, “lightweight”, or “professional”.
Dont repeat the name of the plugin.
For plugins that add language/platform/framework support, the description MUST specify
the version of the corresponding language/platform/framework.
Don't mention the IDE compatibility. E.g. don't say "Adds support to IntelliJ IDEA for..."
Displayed in the "Plugins" settings dialog and the plugin repository Web interface. -->
<description>Integrates Volume Snapshot Service W10</description>
<!-- Description of changes in the latest version of the plugin.
Displayed in the "Plugins" settings dialog and in the
plugin repository Web interface. -->
Displayed in the "Plugins" settings dialog and the plugin repository Web interface. -->
<change-notes>Initial release of the plugin.</change-notes>
<!-- Plugin version -->
<version>1.0</version>
<!-- Plugin version
Recommended format is BRANCH.BUILD.FIX (MAJOR.MINOR.FIX)
Displayed in the "Plugins" settings dialog and the plugin repository Web interface. -->
<version>1.0.0</version>
<!-- The vendor of the plugin.
The optional "url" attribute specifies the URL of the vendor homepage.
The optional "email" attribute specifies the e-mail address of the vendor.-->
<vendor url="https://www.jetbrains.com" email="support@jetbrains.com" />
The optional "email" attribute specifies the e-mail address of the vendor.
Displayed in the "Plugins" settings dialog and the plugin repository Web interface. -->
<vendor url="https://www.jetbrains.com" email="support@jetbrains.com">A Company Inc.</vendor>
<!-- The unique identifiers of the plugins on which this plugin depends. -->
<depends>com.MyFirstPlugin</depends>
<!-- Mandatory dependencies on plugins or modules.
The FQN module names in <depends> elements are used to determine IDE compatibility for the plugin.
Include at least the module shown below to indicate compatibility with IntelliJ Platform-based products.
Also include dependencies on other plugins as needed.
See "Compatibility with Multiple Products" and "Plugin Dependencies" for more information. -->
<depends>com.intellij.modules.platform</depends>
<depends>com.third.party.plugin</depends>
<!-- Optional dependency on another plugin.
If the plugin with the "com.MySecondPlugin" ID is installed,
the contents of mysecondplugin.xml (the format of this file
conforms to the format of plugin.xml) will be loaded. -->
If the plugin with the "com.MySecondPlugin" ID is installed, the contents of mysecondplugin.xml
(the format of this file conforms to the format of plugin.xml) will be loaded. -->
<depends optional="true" config-file="mysecondplugin.xml">com.MySecondPlugin</depends>
<!-- Allows a plugin to integrate its help system (in JavaHelp format)
with the IDE help system. The "file" attribute specifies the name
of the JAR file in the "help" subdirectory of the plugin directory.
The "path" attribute specifies the name of the helpset file within
the JAR file.-->
<helpset file="myhelp.jar" path="/Help.hs" />
<!-- Minimum and maximum build of IDE compatible with the plugin -->
<idea-version since-build="183" until-build="183.*"/>

View File

@ -30,7 +30,7 @@ To clarify this procedure, consider the following sample section of the plugin.x
```
* The `interface` attribute sets an interface the plugin that contributes to the extension point must implement.
* The `beanClass` attribute sets a bean class that specifies one or several properties annotated with the [@Attribute](upsource:///xml/dom-openapi/src/com/intellij/util/xml/Attribute.java) annotation.
* The `beanClass` attribute sets a bean class that specifies one or several properties annotated with the [@Attribute](upsource:///platform/util/src/com/intellij/util/xmlb/annotations/Attribute.java) annotation.
The plugin that contributes to the extension point will read those properties from the `plugin.xml` file.
@ -54,17 +54,20 @@ public class MyBeanClass1 extends AbstractExtensionPointBean {
}
```
Note that to declare an extension designed to access the `MyExtensionPoint1` extension point, your `plugin.xml` file must contain the `<MyExtensionPoint1>` tag with the `key` and `implementationClass` attributes set to appropriate values (see sample below).
To declare an extension designed to access the `MyExtensionPoint1` extension point, your `plugin.xml` file must contain the `<MyExtensionPoint1>` tag with the `key` and `implementationClass` attributes set to appropriate values (see sample below).
**To declare an extension**
1. For the `<extensions>` element, set the `xmlns` (deprecated) or `defaultExtensionNs` attribute to one of the following values:
> **TIP** Auto-completion is available for all these steps.
1. For the `<extensions>` element, set the `defaultExtensionNs` attribute to one of the following values:
* `com.intellij`, if your plugin extends the IntelliJ Platform core functionality.
* `{ID of a plugin}`, if your plugin extends a functionality of another plugin.
2. Add a new child element to the `<extensions>` element. The child element name must match the name of the extension point you want the extension to access.
3. Depending on the type of the extension point, do one of the following:
* If the extension point was declared using the `interface` attribute, for newly added child element, set the `implementation` attribute to the name of the class that implements the specified interface.
* If the extension point was declared using the `beanClass` attribute, for newly added child element, set all attributes annotated with the [@Attribute](upsource:///xml/dom-openapi/src/com/intellij/util/xml/Attribute.java) annotations in the specified bean class.
* If the extension point was declared using the `beanClass` attribute, for newly added child element, set all attributes annotated with the [@Attribute](upsource:///platform/util/src/com/intellij/util/xmlb/annotations/Attribute.java) annotations in the specified bean class.
To clarify this procedure, consider the following sample section of the `plugin.xml` file that defines two extensions designed to access the `appStarter` and `applicationConfigurable` extension points in the *IntelliJ Platform* and one extension to access the `MyExtensionPoint1` extension point in a test plugin:
@ -84,6 +87,33 @@ To clarify this procedure, consider the following sample section of the `plugin.
<MyExtensionPoint1 key="keyValue" implementationClass="MyTestPackage.MyClassImpl"></MyExtensionPoint1>
</extensions>
```
### Extension default properties
The following properties are available always:
- `id` - unique ID
- `order` - allows to order all defined extensions using `first`, `last` or `before|after [id]` respectively
- `os` - allows to restrict extension to given OS, e.g., `os="windows"` registers the extension on Windows only
### Extension properties code insight
Several tooling features are available to help configuring bean class extension points in `plugin.xml`.
Property names matching the following list will resolve to FQN:
- `implementation`
- `className`
- `serviceInterface` / `serviceImplementation`
- ending with `Class` (case-sensitive)
A required parent type can be specified in the extension point declaration via nested `<with>`:
```xml
<extensionPoint name="myExtension" beanClass="MyExtensionBean">
<with attribute="psiElementClass" implements="com.intellij.psi.PsiElement"/>
</extensionPoint>
```
Property name `language` will automatically resolve to all present `Language` IDs.
Specifying `@org.jetbrains.annotations.Nls` verifies capitalization of UI text properties according to given `capitalization` value (2019.2 and later).
## How to get the extension points list?
@ -93,6 +123,3 @@ To get a list of extension points available in the *IntelliJ Platform* core, con
* [`PlatformExtensionPoints.xml`](upsource:///platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml)
* [`VcsExtensionPoints.xml`](upsource:///platform/platform-resources/src/META-INF/VcsExtensionPoints.xml)
## Additional Information and Samples
For samples plugins and detailed instructions on how to create your plugin that contributes to the IDEA core, refer to Customizing the IDEA Settings Dialog and Creation of Tool Windows.

View File

@ -41,9 +41,12 @@ This page gives a list of recipes for the most common operations for working wit
### How do I get a reference to the containing package of a Java class?
```java
PsiJavaFile javaFile = (PsiJavaFile) psiClass.getContaningFile();
PsiJavaFile javaFile = (PsiJavaFile) psiClass.getContainingFile();
PsiPackage pkg = JavaPsiFacade.getInstance(project).findPackage(javaFile.getPackageName());
```
```
or
`com.intellij.psi.util.PsiUtil.getPackageName()`
### How do I find the methods overriding a specific method?

View File

@ -16,7 +16,7 @@ In a product with 15+ years of lifetime that has gone through a large number of
Another consequence of our testing approach is what our test framework does not provide:
* We do not provide a recommended approach to mocking. We have a few tests in our codebase that use JMock, but in general, we find it difficult to mock all of the interactions with *IntelliJ Platform* components that your plugin class will need to have, and we recommend working with real components instead.
* We do not provide a general-purpose framework for Swing UI testing. You can try using tools such as [FEST](https://code.google.com/p/fest/) or [Sikuli](http://www.sikuli.org/) for plugin UI testing, but we don't use either of them and cannot provide any guidelines for their use. Internally, we use manual testing for testing our Swing UIs.
* We do not provide a general-purpose framework for Swing UI testing. You can try using tools such as [FEST](https://code.google.com/p/fest/) or [Sikuli](http://sikulix.com/) for plugin UI testing, but we don't use either of them and cannot provide any guidelines for their use. Internally, we use manual testing for testing our Swing UIs.
* [Tests and Fixtures](/basics/testing_plugins/tests_and_fixtures.md)
* [Light and Heavy Tests](/basics/testing_plugins/light_and_heavy_tests.md)

View File

@ -55,7 +55,8 @@ 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 the `BulkFileListener` interface 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 the `BulkFileListener` interface and to subscribe with it to the [VirtualFileManager.VFS_CHANGES](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java)<!--#L34--> topic.
A non-blocking variant `AsyncFileListener` is also available in 2019.2 or later.
This API gives you all the changes detected during the refresh operation in one list, and lets you process them in batch. Alternatively, you can implement the `VirtualFileListener` interface and register it using [VirtualFileManager.addVirtualFileListener()](upsource:///platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java)<!--#L113-->. This will let you process the events one by one.

View File

@ -1,11 +0,0 @@
# Created by .ignore support plugin (hsz.mobi)
### Gradle template
.gradle
build/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar

View File

@ -1,30 +0,0 @@
plugins {
id 'java'
id 'org.jetbrains.intellij' version '0.4.8'
}
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
// See https://github.com/JetBrains/gradle-intellij-plugin/
intellij {
// Define IntelliJ Platform API version to use for building this plugin
version '2019.1'
// Prevents patching <idea-version> attributes in plugin.xml
updateSinceUntilBuild = false
// Define a shared sandbox directory for running code sample plugins within an IDE.
sandboxDirectory = file("${project.projectDir}/../_idea-sandbox")
}
// Force javadoc rebuild before jar is built
jar.dependsOn javadoc

View File

@ -1,5 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -1,172 +0,0 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

View File

@ -1,84 +0,0 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -1,2 +0,0 @@
rootProject.name = 'action_basics'

View File

@ -1,10 +0,0 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package icons;
import com.intellij.openapi.util.IconLoader;
import javax.swing.*;
public class ActionBasicsIcons {
public static final Icon Sdk_default_icon = IconLoader.getIcon("/icons/sdk_16.svg");
}

View File

@ -1,33 +0,0 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.intellij.sdk.action;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.editor.Editor;
import icons.ActionBasicsIcons;
/**
* Creates an action group to contain menu actions. See plugin.xml declarations.
* @author Anna Bulenkova
* @author jhake
*/
public class CustomDefaultActionGroup extends DefaultActionGroup {
/**
* Given CustomDefaultActionGroup is derived from ActionGroup, in this context
* update() determines whether the action group itself should be enabled or disabled.
* Requires an editor to be active in order to enable the group functionality.
* @see com.intellij.openapi.actionSystem.AnAction#update(AnActionEvent)
* @param event Event received when the associated group-id menu is chosen.
*/
@Override
public void update(AnActionEvent event) {
// Enable/disable depending on whether user is editing
Editor editor = event.getData(CommonDataKeys.EDITOR);
event.getPresentation().setEnabled(editor != null);
// Take this opportunity to set an icon for the menu entry.
event.getPresentation().setIcon(ActionBasicsIcons.Sdk_default_icon);
}
}

View File

@ -1,39 +0,0 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.intellij.sdk.action;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import icons.ActionBasicsIcons;
import org.jetbrains.annotations.NotNull;
/**
* Demonstrates adding an action group to a menu statically in plugin.xml, and then creating a menu item
* within the group at runtime. See plugin.xml for the declaration of DynamicActionGroup,
* and note the group declaration does not contain an action.
* DynamicActionGroup is based on ActionGroup because menu children are determined
* on rules other than just positional constraints.
*
* @author Anna Bulenkova
* @see ActionGroup
*/
public class DynamicActionGroup extends ActionGroup {
/**
* Returns an array of menu actions for the group.
*
* @param e Event received when the associated group-id menu is chosen.
* @return AnAction[] An instance of AnAction, in this case containing a single instance of the
* PopupDialogAction class.
*/
@NotNull
@Override
public AnAction[] getChildren(AnActionEvent e) {
return new AnAction[]{ new PopupDialogAction("Action Added at Runtime",
"Dynamic Action Demo",
ActionBasicsIcons.Sdk_default_icon)
};
}
}

View File

@ -1,78 +0,0 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.intellij.sdk.action;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.pom.Navigatable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* Action class to demonstrate how to interact with the IntelliJ Platform.
* The only action this class performs is to provide the user with a popup dialog as feedback.
* Typically this class is instantiated by the IntelliJ Platform framework based on declarations
* in the plugin.xml file. But when added at runtime this class is instantiated by an action group.
*/
public class PopupDialogAction extends AnAction {
/**
* This default constructor is used by the IntelliJ Platform framework to
* instantiate this class based on plugin.xml declarations. Only needed in PopupDialogAction
* class because a second constructor is overridden.
* @see AnAction#AnAction()
*/
public PopupDialogAction() {
super();
}
/**
* This constructor is used to support dynamically added menu actions.
* It sets the text, description to be displayed for the menu item.
* Otherwise, the default AnAction constructor is used by the IntelliJ Platform.
* @param text The text to be displayed as a menu item.
* @param description The description of the menu item.
* @param icon The icon to be used with the menu item.
*/
public PopupDialogAction(@Nullable String text, @Nullable String description, @Nullable Icon icon) {
super(text, description, icon);
}
/**
* Gives the user feedback when the dynamic action menu is chosen.
* Pops a simple message dialog. See the psi_demo plugin for an
* example of how to use AnActionEvent to access data.
* @param event Event received when the associated menu item is chosen.
*/
@Override
public void actionPerformed(@NotNull AnActionEvent event) {
// Using the event, create and show a dialog
Project currentProject = event.getProject();
StringBuffer dlgMsg = new StringBuffer(event.getPresentation().getText() + " Selected!");
String dlgTitle = event.getPresentation().getDescription();
// If an element is selected in the editor, add info about it.
Navigatable nav = event.getData(CommonDataKeys.NAVIGATABLE);
if (nav != null) {
dlgMsg.append(String.format("\nSelected Element: %s", nav.toString()));
}
Messages.showMessageDialog(currentProject, dlgMsg.toString(), dlgTitle, Messages.getInformationIcon());
}
/**
* Determines whether this menu item is available for the current context.
* Requires a project to be open.
* @param e Event received when the associated group-id menu is chosen.
*/
@Override
public void update(AnActionEvent e) {
// Set the availability based on whether a project is open
Project project = e.getProject();
e.getPresentation().setEnabledAndVisible(project != null);
}
}

View File

@ -1,77 +0,0 @@
<!-- Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<idea-plugin>
<!-- Unique id for this plugin. Must stay constant for the life of the plugin. -->
<id>org.intellij.sdk.action</id>
<!-- Text to display as name on Preferences/Settings | Plugin page -->
<name>SDK: Action Sample Project</name>
<!-- The version of this plugin -->
<version>2.0.0</version>
<!-- Compatible with the following versions of IntelliJ Platform:
version 2018.3 (build #183) and newer. -->
<idea-version since-build="183"/>
<!-- Indicate this plugin can be loaded in all IntelliJ Platform-based products. -->
<depends>com.intellij.modules.platform</depends>
<!-- Text to display as description on Preferences/Settings | Plugin page -->
<description>
<![CDATA[
Demonstrates implementing Action and Action Group patterns.<br> Adds entries to the Tools menu.
]]>
</description>
<change-notes>
<![CDATA[
<ul>
<li><b>2.0.0</b> Renamed from register_actions and converted to Gradle project.</li>
<li><b>1.1</b> Refactor to give users feedback when menu items are selected.</li>
<li><b>1.0</b> Release 2018.3 and earlier.</li>
</ul>
]]>
</change-notes>
<!-- Text to display as company information on Preferences/Settings | Plugin page -->
<vendor url="https://plugins.jetbrains.com">IntelliJ Platform SDK</vendor>
<actions>
<!-- See https://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html#registering-actions-in-pluginxml
for information about the elements and attributes used for actions and groups. -->
<!-- This <action> element adds a static menu item in first position of the Tools menu that shows PopupDialogAction. -->
<action id="org.intellij.sdk.action.PopupDialogAction" class="org.intellij.sdk.action.PopupDialogAction"
text="Pop Dialog Action" description="SDK Action Example" icon="ActionBasicsIcons.Sdk_default_icon">
<keyboard-shortcut first-keystroke="control alt A" second-keystroke="C" keymap="$default"/>
<mouse-shortcut keystroke="control button3 doubleClick" keymap="$default"/>
<add-to-group group-id="ToolsMenu" anchor="first"/>
</action>
<!-- All of the following menu groups add the action PopupDialogAction to menus in different ways.
Note that even though these groups reuse the same action class, in each use the action ids are unique. -->
<!-- GroupedActions demonstrates declaring an action group using the default ActionGroup implementation provided by the
IntelliJ Platform framework. (Note the lack of a group "class" attribute.) GroupedActions gets inserted after PopupDialogAction
in the Tools menu. Because the group's implementation is default, it cannot impose enable/disable conditions. Instead it
must rely on the conditions imposed by the parent menu where it is inserted. It declares one action in the group. -->
<group id="org.intellij.sdk.action.GroupedActions" text="Static Grouped Actions" popup="true" icon="ActionBasicsIcons.Sdk_default_icon">
<add-to-group group-id="ToolsMenu" anchor="after" relative-to-action="org.intellij.sdk.action.PopupDialogAction"/>
<action class="org.intellij.sdk.action.PopupDialogAction" id="org.intellij.sdk.action.GroupPopDialogAction"
text="A Group Action" description="SDK Static Grouped Action Example" icon="ActionBasicsIcons.Sdk_default_icon">
</action>
</group>
<!-- CustomDefaultActionGroup demonstrates declaring an action group based on a ActionGroup class supplied by this plugin.
This group is to be inserted atop the Editor Popup Menu. It declares one action in the group. -->
<group id="org.intellij.sdk.action.CustomDefaultActionGroup" class="org.intellij.sdk.action.CustomDefaultActionGroup" popup="true"
text="Popup Grouped Actions" description="Custom DefaultActionGroup Demo" icon="ActionBasicsIcons.Sdk_default_icon">
<add-to-group group-id="EditorPopupMenu" anchor="first"/>
<action class="org.intellij.sdk.action.PopupDialogAction" id="org.intellij.sdk.action.CustomGroupedAction"
text="A Popup Action" description="SDK Popup Grouped Action Example" icon="ActionBasicsIcons.Sdk_default_icon"/>
</group>
<!-- DynamicActionGroup demonstrates declaring an action group without a static action declaration.
An action is added to the group programmatically in the DynamicActionGroup implementation. -->
<group id="org.intellij.sdk.action.DynamicActionGroup" class="org.intellij.sdk.action.DynamicActionGroup" popup="true"
text="Dynamically Grouped Actions" description="SDK Dynamically Grouped Action Example" icon="ActionBasicsIcons.Sdk_default_icon">
<add-to-group group-id="ToolsMenu" anchor="after" relative-to-action="org.intellij.sdk.action.GroupedActions"/>
</group>
</actions>
</idea-plugin>

View File

@ -1,58 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="81" height="80" viewBox="0 0 81 80">
<defs>
<linearGradient id="pluginsdk_80-a" x1="-.031%" x2="100.053%" y1="49.963%" y2="49.963%">
<stop offset="25.81%" stop-color="#F97A12"/>
<stop offset="45.91%" stop-color="#B07B58"/>
<stop offset="72.41%" stop-color="#577BAE"/>
<stop offset="91.05%" stop-color="#1E7CE5"/>
<stop offset="100%" stop-color="#087CFA"/>
</linearGradient>
<linearGradient id="pluginsdk_80-b" x1="27.55%" x2="82.223%" y1="34.514%" y2="77.605%">
<stop offset="0%" stop-color="#F97A12"/>
<stop offset="7.18%" stop-color="#CB7A3E"/>
<stop offset="15.41%" stop-color="#9E7B6A"/>
<stop offset="24.2%" stop-color="#757B91"/>
<stop offset="33.44%" stop-color="#537BB1"/>
<stop offset="43.24%" stop-color="#387CCC"/>
<stop offset="53.81%" stop-color="#237CE0"/>
<stop offset="65.52%" stop-color="#147CEF"/>
<stop offset="79.25%" stop-color="#0B7CF7"/>
<stop offset="100%" stop-color="#087CFA"/>
</linearGradient>
<linearGradient id="pluginsdk_80-c" x1="63.121%" x2="40.793%" y1="97.699%" y2="-6.587%">
<stop offset="0%" stop-color="#FE315D"/>
<stop offset="7.84%" stop-color="#CB417E"/>
<stop offset="16.01%" stop-color="#9E4E9B"/>
<stop offset="24.74%" stop-color="#755BB4"/>
<stop offset="33.92%" stop-color="#5365CA"/>
<stop offset="43.65%" stop-color="#386DDB"/>
<stop offset="54.14%" stop-color="#2374E9"/>
<stop offset="65.76%" stop-color="#1478F3"/>
<stop offset="79.4%" stop-color="#0B7BF8"/>
<stop offset="100%" stop-color="#087CFA"/>
</linearGradient>
<linearGradient id="pluginsdk_80-d" x1="25.331%" x2="93.854%" y1="24.119%" y2="132.621%">
<stop offset="0%" stop-color="#FE315D"/>
<stop offset="4.023%" stop-color="#F63462"/>
<stop offset="10.37%" stop-color="#DF3A71"/>
<stop offset="16.67%" stop-color="#C24383"/>
<stop offset="29.12%" stop-color="#AD4A91"/>
<stop offset="54.98%" stop-color="#755BB4"/>
<stop offset="91.75%" stop-color="#1D76ED"/>
<stop offset="100%" stop-color="#087CFA"/>
</linearGradient>
</defs>
<g fill="none" fill-rule="evenodd">
<g fill-rule="nonzero" transform="translate(8 8)">
<path fill="url(#pluginsdk_80-a)" d="M6.08754566,64 L2.66453526e-15,59.1000946 L0,26.7918961 L30,38.6703369 L10.1403967,64 L6.08754566,64 Z"/>
<path fill="url(#pluginsdk_80-b)" d="M20.9524706,64 L52.2740919,31.9159091 L37.6708832,0.460194805 L38.0580944,1.33226763e-15 L64,0 L64,64 L20.9524706,64 Z"/>
<path fill="url(#pluginsdk_80-c)" d="M34.4123783,0 L64,0 L64,28.0366227 L49.0078336,44 L34,0.44696173 L34.4123783,0 Z"/>
<path fill="url(#pluginsdk_80-d)" d="M30.3358775,64 L0,64 L0,49.9709549 L6.23437817,29.2830519 L0,27.1596093 L0,0 L39.4697238,0 L58,21.3844805 L30.5381317,63.9259091 L30.3358775,64 Z"/>
</g>
<g fill-rule="nonzero" transform="translate(12 12)">
<rect width="56" height="56" fill="#000"/>
<rect width="22" height="4" x="4" y="46" fill="#FFFEFE"/>
<path fill="#FFFEFE" d="M11.128,25.28 C8.584,25.28 6.016,24.392 4,22.592 L6.184,19.976 C7.696,21.224 9.28,22.016 11.2,22.016 C12.712,22.016 13.624,21.416 13.624,20.432 L13.624,20.384 C13.624,19.448 13.048,18.968 10.24,18.248 C6.856,17.384 4.672,16.448 4.672,13.112 L4.672,13.064 C4.672,10.016 7.12,8 10.552,8 C13,8 15.088,8.768 16.792,10.136 L14.872,12.92 C13.384,11.888 11.92,11.264 10.504,11.264 C9.088,11.264 8.344,11.912 8.344,12.728 L8.344,12.776 C8.344,13.88 9.064,14.24 11.968,14.984 C15.376,15.872 17.296,17.096 17.296,20.024 L17.296,20.072 C17.296,23.408 14.752,25.28 11.128,25.28 Z M19.512,25.04 L19.512,8.24 L26.064,8.24 C31.344,8.24 34.992,11.864 34.992,16.592 L34.992,16.64 C34.992,21.368 31.344,25.04 26.064,25.04 L19.512,25.04 Z M26.064,11.576 L23.208,11.576 L23.208,21.704 L26.064,21.704 C29.088,21.704 31.128,19.664 31.128,16.688 L31.128,16.64 C31.128,13.664 29.088,11.576 26.064,11.576 Z M37.28,25.04 L37.28,8.24 L40.976,8.24 L40.976,15.584 L47.744,8.24 L52.28,8.24 L45.416,15.368 L52.568,25.04 L48.128,25.04 L42.92,17.888 L40.976,19.904 L40.976,25.04 L37.28,25.04 Z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" transform="translate(1 1)">
<rect width="14" height="14" fill="#000"/>
<rect width="5" height="1" x="1" y="11" fill="#FFFEFE"/>
<path fill="#FFFEFE" d="M1,5.96113281 L1.85546875,5.96113281 C1.89648438,6.30390625 2.2421875,6.52363281 2.74023438,6.52363281 C3.20019531,6.52363281 3.52539063,6.30097656 3.52539063,5.98164062 C3.52539063,5.71210937 3.31445313,5.55683594 2.79589844,5.44550781 L2.24511719,5.32832031 C1.47460938,5.1671875 1.09667969,4.76582031 1.09667969,4.12128906 C1.09667969,3.32441406 1.73828125,2.8 2.71386719,2.8 C3.64550781,2.8 4.3046875,3.32148437 4.33105469,4.07441406 L3.49902344,4.07441406 C3.45800781,3.74042969 3.14746094,3.51777344 2.71972656,3.51777344 C2.27734375,3.51777344 1.984375,3.72285156 1.984375,4.04511719 C1.984375,4.30585937 2.18652344,4.45527344 2.68164063,4.56074219 L3.19140625,4.66914062 C4.04101563,4.84785156 4.40722656,5.2140625 4.40722656,5.8703125 C4.40722656,6.72285156 3.75390625,7.24433594 2.69335938,7.24433594 C1.68554688,7.24433594 1.03222656,6.74921875 1,5.96113281 Z M5.19603365,2.90546875 L6.86009615,2.90546875 C8.11693209,2.90546875 8.84349459,3.6671875 8.84349459,4.99140625 C8.84349459,6.36542969 8.12572115,7.1359375 6.86009615,7.1359375 L5.19603365,7.1359375 L5.19603365,2.90546875 Z M6.08079927,3.66132812 L6.08079927,6.38007812 L6.71947115,6.38007812 C7.50169771,6.38007812 7.94115084,5.89960937 7.94115084,5.00605469 C7.94115084,4.15058594 7.48704927,3.66132812 6.71947115,3.66132812 L6.08079927,3.66132812 Z M10.5170673,7.1359375 L9.63230167,7.1359375 L9.63230167,2.90839844 L10.5170673,2.90839844 L10.5170673,4.7921875 L10.5698017,4.7921875 L12.1313251,2.90839844 L13.1157001,2.90839844 L11.5746845,4.76289062 L13.2240985,7.1359375 L12.1635517,7.1359375 L10.9360126,5.36640625 L10.5170673,5.86152344 L10.5170673,7.1359375 Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,11 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PLUGIN_MODULE" version="4">
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/source/META-INF/plugin.xml" />
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/resources/META-INF/plugin.xml" />
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/source" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/testSource" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/testData" type="java-test-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />

View File

@ -0,0 +1,70 @@
<!-- Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<idea-plugin>
<!-- Unique id for this plugin. Must stay constant for the life of the plugin. -->
<id>org.intelliJ.sdk.codeInspection</id>
<!-- Text to display as name on Preferences/Settings | Plugin page -->
<name>SDK Comparing References Inspection Sample</name>
<!-- The version of this plugin -->
<version>1.1.0</version>
<!-- Compatible with the following versions of IntelliJ Platform -->
<idea-version since-build="173"/>
<!-- Text to display as description on Preferences/Settings | Plugin page -->
<description>
<![CDATA[
Demonstrates implementing a Local Inspection Tool.<br> Adds entries to <b>Preferences | Editor | Inspections | Java | Probable Bugs</b>.
]]>
</description>
<change-notes>
<![CDATA[
<ul>
<li><b>1.1.0</b> Refactor resources, register this inspection.</li>
<li><b>1.0.0</b> Release 2018.3 and earlier.</li>
</ul>
]]>
</change-notes>
<!-- Text to display as company information on Preferences/Settings | Plugin page -->
<vendor email="faux-email@jetbrains.com" url="https://plugins.jetbrains.com">IntelliJ Platform SDK</vendor>
<extensions defaultExtensionNs="com.intellij">
<!-- Extend the IntelliJ Platform local inspection type, and connect it to the implementation class
in this plugin.
<localInspection> type element is applied within the scope of a file under edit.
It is preferred over <inspectionToolProvider>
@see intellij.platform.resources.LangExtensionPoints
@see com.intellij.codeInspection.InspectionProfileEntry
Attributes:
language= Language ID
shortName= Not specified, will be computed by the underlying implementation classes.
displayName= The string to be shown in the Preferences | Editor | Inspections panel
The displayName gets registered to identify this inspection.
Can be localized using key= and bundle= attributes instead.
groupPath= Defines the outermost grouping for this inspection in
the Preferences | Editor | Inspections panel. Not localized.
groupBundle= Name of *.bundle file to translate groupKey.
In this case reuse an IntelliJ Platform bundle file from intellij.platform.resources.en
groupKey= Key to use for translation subgroup name using groupBundle file.
In this case reuse the IntelliJ Platform subcategory "Probable bugs"
enabledByDefault= Inspection state when Inspections panel is created.
level= The default level of error found by this inspection, e.g. INFO, ERROR, etc.
@see com.intellij.codeHighlighting.HighlightDisplayLevel
inplementationClass= FQN of inspection implementation
-->
<localInspection language="JAVA"
displayName="SDK: '==' or '!=' used instead of 'equals()'"
groupPath="Java"
groupBundle="messages.InspectionsBundle"
groupKey="group.names.probable.bugs"
enabledByDefault="true"
level="WARNING"
implementationClass="com.intellij.codeInspection.ComparingReferencesInspection"/>
</extensions>
</idea-plugin>

View File

@ -0,0 +1,7 @@
<html>
<body>
<b>SDK:</b> This inspection reports when the '==' or '!=' operator was used between expressions of
reference types. <br>
Classes to be inspected are controlled by a semi-colon separated <i>Options</i> list in the preferences panel for this inspection.
</body>
</html>

View File

@ -1,14 +0,0 @@
<idea-plugin>
<name>Comparing References Inspection</name>
<description>Inspection for (probably) inappropriate use of equality relation operation.</description>
<version>1.0</version>
<vendor>JetBrains</vendor>
<!--
<idea-version since-build="3000"/>
-->
<extensions defaultExtensionNs="com.intellij">
<inspectionToolProvider implementation="com.intellij.codeInspection.ComparingReferencesProvider"/>
</extensions>
</idea-plugin>

View File

@ -1,105 +1,167 @@
package com.intellij.codeInspection;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.ui.DocumentAdapter;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.util.StringTokenizer;
import static com.siyeh.ig.psiutils.ExpressionUtils.isNullLiteral;
/**
* @author max
* @author jhake
*/
public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspectionTool {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ComparingReferencesInspection");
private final LocalQuickFix myQuickFix = new MyQuickFix();
private final CriQuickFix myQuickFix = new CriQuickFix();
// Defines the text of the quick fix intention
public static final String QUICK_FIX_NAME = "SDK: " + InspectionsBundle.message("inspection.comparing.references.use.quickfix");
// This string holds a list of classes relevant to this inspection.
@SuppressWarnings({"WeakerAccess"})
@NonNls
public String CHECKED_CLASSES = "java.lang.String;java.util.Date";
@NonNls
private static final String DESCRIPTION_TEMPLATE =
InspectionsBundle.message("inspection.comparing.references.problem.descriptor");
@NotNull
public String getDisplayName() {
return "'==' or '!=' instead of 'equals()'";
/**
* This method is called to get the panel describing the inspection.
* It is called every time the user selects the inspection in preferences.
* The user has the option to edit the list of CHECKED_CLASSES.
* Adds a document listener to see if
*
* @return panel to display inspection information.
*/
@Override
public JComponent createOptionsPanel() {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
final JTextField checkedClasses = new JTextField(CHECKED_CLASSES);
checkedClasses.getDocument().addDocumentListener(new DocumentAdapter() {
public void textChanged(DocumentEvent event) {
CHECKED_CLASSES = checkedClasses.getText();
}
});
panel.add(checkedClasses);
return panel;
}
@NotNull
public String getGroupDisplayName() {
return GroupNames.BUGS_GROUP_NAME;
}
@NotNull
public String getShortName() {
return "ComparingReferences";
}
private boolean isCheckedType(PsiType type) {
if (!(type instanceof PsiClassType)) return false;
StringTokenizer tokenizer = new StringTokenizer(CHECKED_CLASSES, ";");
while (tokenizer.hasMoreTokens()) {
String className = tokenizer.nextToken();
if (type.equalsToText(className)) return true;
}
return false;
}
/**
* This method is overridden to provide a custom visitor
* that inspects expressions with relational operators '==' and '!='
* The visitor must not be recursive and must be thread-safe.
*
* @param holder object for visitor to register problems found.
* @param isOnTheFly true if inspection was run in non-batch mode
* @return non-null visitor for this inspection.
* @see JavaElementVisitor
*/
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new JavaElementVisitor() {
/**
* This string defines the short message shown to a user signaling the inspection
* found a problem. It reuses a string from the inspections bundle.
*/
@NonNls
private final String DESCRIPTION_TEMPLATE = "SDK " + InspectionsBundle.message("inspection.comparing.references.problem.descriptor");
/**
* Avoid defining visitors for both Reference and Binary expressions.
*
* @param psiReferenceExpression The expression to be evaluated.
*/
@Override
public void visitReferenceExpression(PsiReferenceExpression psiReferenceExpression) {
}
/**
* Evaluate binary psi expressions to see if they contain
* relational operators '==' and '!=', AND they contain
* classes contained in CHECKED_CLASSES. The evaluation
* ignores expressions comparing an object to null.
* IF this criteria is met, add the expression to the
* problems list.
*
* @param expression The binary expression to be evaluated.
*/
@Override
public void visitBinaryExpression(PsiBinaryExpression expression) {
super.visitBinaryExpression(expression);
IElementType opSign = expression.getOperationTokenType();
if (opSign == JavaTokenType.EQEQ || opSign == JavaTokenType.NE) {
// The binary expression is the correct type for this inspection
PsiExpression lOperand = expression.getLOperand();
PsiExpression rOperand = expression.getROperand();
if (rOperand == null || isNullLiteral(lOperand) || isNullLiteral(rOperand)) return;
if (rOperand == null || isNullLiteral(lOperand) || isNullLiteral(rOperand))
return;
// Nothing is compared to null, now check the types being compared
PsiType lType = lOperand.getType();
PsiType rType = rOperand.getType();
if (isCheckedType(lType) || isCheckedType(rType)) {
// Identified an expression with potential problems, add to list with fix object.
holder.registerProblem(expression,
DESCRIPTION_TEMPLATE, myQuickFix);
}
}
}
/**
* Verifies the input is the correct {@code PsiType} for this inspection.
*
* @param type The {@code PsiType} to be examined for a match
* @return {@code true} if input is {@code PsiClassType} and matches
* one of the classes in the CHECKED_CLASSES list.
*/
private boolean isCheckedType(PsiType type) {
if (!(type instanceof PsiClassType))
return false;
StringTokenizer tokenizer = new StringTokenizer(CHECKED_CLASSES, ";");
while (tokenizer.hasMoreTokens()) {
String className = tokenizer.nextToken();
if (type.equalsToText(className))
return true;
}
return false;
}
};
}
private static boolean isNullLiteral(PsiExpression expr) {
return expr instanceof PsiLiteralExpression && "null".equals(expr.getText());
}
private static class MyQuickFix implements LocalQuickFix {
/**
* This class provides a solution to inspection problem expressions by manipulating
* the PSI tree to use a.equals(b) instead of '==' or '!='
*/
private static class CriQuickFix implements LocalQuickFix {
/**
* Returns a partially localized string for the quick fix intention.
* Used by the test code for this plugin.
*
* @return Quick fix short name.
*/
@NotNull
@Override
public String getName() {
// The test (see the TestThisPlugin class) uses this string to identify the quick fix action.
return InspectionsBundle.message("inspection.comparing.references.use.quickfix");
return QUICK_FIX_NAME;
}
/**
* This method manipulates the PSI tree to replace 'a==b' with 'a.equals(b)
* or 'a!=b' with '!a.equals(b)'
*
* @param project The project that contains the file being edited.
* @param descriptor A problem found by this inspection.
*/
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
try {
PsiBinaryExpression binaryExpression = (PsiBinaryExpression) descriptor.getPsiElement();
@ -108,16 +170,16 @@ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspecti
PsiExpression rExpr = binaryExpression.getROperand();
if (rExpr == null)
return;
PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
PsiMethodCallExpression equalsCall =
(PsiMethodCallExpression) factory.createExpressionFromText("a.equals(b)", null);
(PsiMethodCallExpression) factory.createExpressionFromText("a.equals(b)", null);
equalsCall.getMethodExpression().getQualifierExpression().replace(lExpr);
equalsCall.getArgumentList().getExpressions()[0].replace(rExpr);
PsiExpression result = (PsiExpression) binaryExpression.replace(equalsCall);
if (opSign == JavaTokenType.NE) {
PsiPrefixExpression negation = (PsiPrefixExpression) factory.createExpressionFromText("!a", null);
negation.getOperand().replace(result);
@ -127,27 +189,11 @@ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspecti
LOG.error(e);
}
}
@NotNull
public String getFamilyName() {
return getName();
}
}
public JComponent createOptionsPanel() {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
final JTextField checkedClasses = new JTextField(CHECKED_CLASSES);
checkedClasses.getDocument().addDocumentListener(new DocumentAdapter() {
public void textChanged(DocumentEvent event) {
CHECKED_CLASSES = checkedClasses.getText();
}
});
panel.add(checkedClasses);
return panel;
}
public boolean isEnabledByDefault() {
return true;
}
}

View File

@ -1,10 +0,0 @@
package com.intellij.codeInspection;
/**
* @author max
*/
public class ComparingReferencesProvider implements InspectionToolProvider {
public Class[] getInspectionClasses() {
return new Class[]{ComparingReferencesInspection.class};
}
}

View File

@ -1,7 +0,0 @@
<html>
<body>
This inspection reports when the '==' or '!=' operator was used between expressions of
reference types. <br>
In the text field below, specify the semicolon separated list of classes to be considered as suspicious.
</body>
</html>

View File

@ -4,73 +4,84 @@ package testPlugin;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.ComparingReferencesInspection;
import com.intellij.codeInspection.InspectionToolProvider;
import com.intellij.testFramework.TestDataPath;
import com.intellij.openapi.application.PathManager;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.testFramework.fixtures.*;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @see JavaCodeInsightFixtureTestCase
* @see LightCodeInsightFixtureTestCase
*/
@TestDataPath("$CONTENT_ROOT/../testData")
public class TestThisPlugin extends UsefulTestCase {
protected CodeInsightTestFixture myFixture;
// TODO: Get path to module root, then add path to testData
// Specify path to your test data directory
// e.g. final String dataPath = "c:\\users\\john.doe\\idea\\community\\samples\\ComparingReferences/testData";
final String dataPath = "c:\\users\\John.Doe\\idea\\community\\samples\\comparingReferences/testData";
// Specify the path to the test data directory
final String dataPath = PathManager.getResourceRoot(TestThisPlugin.class, "/testPlugin/TestThisPlugin.class");
@Before
public void setUp() throws Exception {
final IdeaTestFixtureFactory fixtureFactory = IdeaTestFixtureFactory.getFixtureFactory();
final TestFixtureBuilder<IdeaProjectTestFixture> testFixtureBuilder =
fixtureFactory.createFixtureBuilder(getName());
fixtureFactory.createFixtureBuilder(getName());
myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(testFixtureBuilder.getFixture());
myFixture.setTestDataPath(dataPath);
final JavaModuleFixtureBuilder builder = testFixtureBuilder.addModule(JavaModuleFixtureBuilder.class);
builder.addContentRoot(myFixture.getTempDirPath()).addSourceRoot("");
builder.setMockJdkLevel(JavaModuleFixtureBuilder.MockJdkLevel.jdk15);
myFixture.setUp();
}
@After
public void tearDown() throws Exception {
myFixture.tearDown();
myFixture = null;
}
protected void doTest(String testName, String hint) throws Throwable {
myFixture.configureByFile(testName + ".java");
myFixture.enableInspections(ComparingReferencesInspection.class);
List<HighlightInfo> highlightInfos = myFixture.doHighlighting();
Assert.assertTrue(!highlightInfos.isEmpty());
final IntentionAction action = myFixture.findSingleIntention(hint);
Assert.assertNotNull(action);
myFixture.launchAction(action);
myFixture.checkResultByFile(testName + ".after.java");
}
// Test the "==" case
/**
* Test the "==" case
* Note the hint must match CriQuickFix#getName
*
* @throws Throwable
*/
@Test
public void test() throws Throwable {
doTest("before", "Use equals()");
// doTest("before", "Use equals()");
doTest("before", ComparingReferencesInspection.QUICK_FIX_NAME);
}
// Test the "!=" case
/**
* Test the "!=" case
* Note the hint must match CriQuickFix#getName
* @throws Throwable
*/
@Test
public void test1() throws Throwable {
doTest("before1", "Use equals()");
doTest("before1", ComparingReferencesInspection.QUICK_FIX_NAME);
}
}

View File

@ -1,27 +0,0 @@
<idea-plugin>
<name>Conditional Operator Converter</name>
<id>ConditionalOperatorConverter</id>
<description>Intention action that suggests to convert a conditional operator into
'if' block.
</description>
<version>1.3</version>
<vendor>JetBrains</vendor>
<!--
<idea-version since-build="2000"/>
-->
<extensions defaultExtensionNs="com.intellij">
<intentionAction>
<className>com.intellij.codeInsight.intention.ConditionalOperatorConvertor</className>
<category>Conditional Operator</category>
<descriptionDirectoryName>ConditionalOperatorConvertor</descriptionDirectoryName>
</intentionAction>
</extensions>
<project-components>
<component>
<implementation-class>com.intellij.codeInsight.intention.ConditionalOperatorConvertor</implementation-class>
</component>
</project-components>
</idea-plugin>

View File

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PLUGIN_MODULE" version="4">
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/META-INF/plugin.xml" />
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/resources/META-INF/plugin.xml" />
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/source" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/testSource" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/testData" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />

View File

@ -0,0 +1,46 @@
<!-- Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<idea-plugin>
<!-- Unique id for this plugin. Must stay constant for the life of the plugin. -->
<id>ConditionalOperatorConverter</id>
<!-- Text to display as name on Preferences/Settings | Plugin page -->
<name>SDK Conditional Operator Converter</name>
<!-- The version of this plugin -->
<version>1.4.0</version>
<!-- Compatible with the following versions of IntelliJ Platform -->
<idea-version since-build="191"/>
<!-- Text to display as description on Preferences/Settings | Plugin page -->
<description>
<![CDATA[
Intention action that suggests converting a ternary operator into an 'if' block.<br>Adds entry to <b>Preferences | Editor | Intentions | SDK Intentions<b>.
]]>
</description>
<change-notes>
<![CDATA[
<ul>
<li><b>1.4.0</b> Refactor resources, general cleanup.</li>
<li><b>1.3.0</b> Release 2018.3 and earlier.</li>
</ul>
]]>
</change-notes>
<!-- Text to display as company information on Preferences/Settings | Plugin page -->
<vendor email="faux-email@jetbrains.com" url="https://plugins.jetbrains.com">IntelliJ Platform SDK</vendor>
<extensions defaultExtensionNs="com.intellij">
<intentionAction>
<className>com.intellij.codeInsight.intention.ConditionalOperatorConvertor</className>
<category>SDK Intentions</category>
</intentionAction>
</extensions>
<project-components>
<component>
<implementation-class>com.intellij.codeInsight.intention.ConditionalOperatorConvertor</implementation-class>
</component>
</project-components>
</idea-plugin>

View File

@ -0,0 +1,7 @@
<!-- Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<html>
<body>
<b>SDK:</b> This intention converts a ternary operator to a corresponding if statement. <br>
</body>
</html>

View File

@ -1,6 +1,5 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.codeInsight.intention;
@ -26,21 +25,21 @@ public class ConditionalOperatorConvertor extends PsiElementBaseIntentionAction
*/
@NotNull
public String getText() {
return "Convert ternary operator to if statement";
return "SDK Convert ternary operator to if statement";
}
/**
* Returns text for name of this family of intentions. It is used to externalize
* "auto-show" state of intentions. Only one intention action is being provided,
* so the family name is the same text as the intention action list entry.
* "auto-show" state of intentions.
* It is also the directory name for the descriptions.
*
* @return the intention family name.
* @see ConditionalOperatorConvertor#getText()
* @see com.intellij.codeInsight.intention.IntentionManager#registerIntentionAndMetaData(IntentionAction, String...)
* @return the intention family name.
*/
@NotNull
public String getFamilyName() {
return getText();
return "ConditionalOperatorIntention";
}

View File

@ -1,5 +0,0 @@
<html>
<body>
This intention converts a ternary operator to a corresponding if statement. <br>
</body>
</html>

View File

@ -1,3 +1,5 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package testPlugin;
import com.intellij.codeInsight.intention.IntentionAction;
@ -52,7 +54,7 @@ public class YourTest extends UsefulTestCase {
@Test
public void test() {
doTest("before.template", "Convert ternary operator to if statement");
doTest("before.template", "SDK Convert ternary operator to if statement");
}
}

View File

@ -2,7 +2,7 @@
<id>org.jetbrains.plugins.sample.EditorBasics</id>
<name>Editor basics</name>
<version>1.0</version>
<vendor email="support@jetbrains.com" url="http://www.jetbrains.com">JetBrains</vendor>
<vendor email="support@jetbrains.com" url="https://www.jetbrains.com">JetBrains</vendor>
<description>Illustration of various basic Editor APIs</description>

View File

@ -1,7 +1,3 @@
plugins {
id "org.jetbrains.intellij" version "0.4.7"
id "org.jetbrains.intellij" version "0.4.8"
}
sourceCompatibility = 1.8

View File

@ -1,15 +1,65 @@
<!-- Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<idea-plugin>
<!-- Unique id for this plugin. Must stay constant for the life of the plugin. -->
<id>com.intellij.tutorials.inspection</id>
<name>Inspection Demo</name>
<version>1.0</version>
<vendor>JetBrains</vendor>
<description>Basic example of working with code inspections</description>
<!-- Text to display as name on Preferences/Settings | Plugin page -->
<name>SDK Inspection Demo</name>
<idea-version since-build="131"/>
<!-- The version of this plugin -->
<version>1.1.0</version>
<!-- Compatible with the following versions of IntelliJ Platform -->
<idea-version since-build="191"/>
<!-- Text to display as description on Preferences/Settings | Plugin page -->
<description>
<![CDATA[
Basic example of working with code inspections. Adds entry to <b>Preferences | Editor | Inspections | SDK | Example Tools</b>.
]]>
</description>
<change-notes>
<![CDATA[
<ul>
<li><b>1.1.0</b> Refactor resources, add "SDK" to description.</li>
<li><b>1.0.0</b> Release 2018.3 and earlier.</li>
</ul>
]]>
</change-notes>
<!-- Text to display as company information on Preferences/Settings | Plugin page -->
<vendor email="faux-email@jetbrains.com" url="https://plugins.jetbrains.com">IntelliJ Platform SDK</vendor>
<extensions defaultExtensionNs="com.intellij">
<inspectionToolProvider implementation="com.intellij.tutorials.inspection.DemoInspectionToolProvider"/>
<!-- Extend the IntelliJ Platform local inspection type, and connect it to the implementation class
in this plugin.
<localInspection> type element is applied within the scope of a file under edit.
It is preferred over <inspectionToolProvider>
@see intellij.platform.resources.LangExtensionPoints
@see com.intellij.codeInspection.InspectionProfileEntry
Attributes:
language= Language ID
shortName= Not specified, will be computed by the underlying implementation classes.
displayName= The string to be shown in the Preferences | Editor | Inspections panel
The displayName gets registered to identify this inspection.
Can be localized using key= and bundle= attributes instead.
groupPath= Defines the outermost grouping for this inspection in
the Preferences | Editor | Inspections panel. Not localized.
groupName= The subgroup containing this inspection. Not localized.
enabledByDefault= Inspection state when Inspections panel is created.
level= The default level of error found by this inspection, e.g. INFO, ERROR, etc.
@see com.intellij.codeHighlighting.HighlightDisplayLevel
implementationClass= FQN of inspection implementation
-->
<localInspection language="JAVA"
displayName="Demo Inspection"
groupName="Example Inspections"
groupPath="SDK"
enabledByDefault="true"
level="WARNING"
implementationClass="com.intellij.tutorials.inspection.DemoCodeInspection"/>
</extensions>
</idea-plugin>

View File

@ -0,0 +1,9 @@
<!-- Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<html>
<body>
<b>SDK:</b> Write your description here.<br>
<!-- tooltip end -->
Text after this comment will not be shown in tooltips.
</body>
</html>

View File

@ -1,19 +1,24 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.tutorials.inspection;
import com.intellij.codeInspection.*;
import org.jetbrains.annotations.*;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.ProblemsHolder;
import org.jetbrains.annotations.NotNull;
/**
* @author Anna Bulenkova
*/
public class DemoCodeInspection extends LocalInspectionTool {
@Nls
@NotNull
@Override
public String getDisplayName() {
return "Demo Inspection";
}
/**
* This method is overridden to provide a custom visitor
* The visitor must not be recursive and must be thread-safe.
*
* @param holder object for visitor to register problems found.
* @param isOnTheFly true if inspection was run in non-batch mode
* @return DemoInspectionVisitor.
*/
@NotNull
@Override
public DemoInspectionVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {

View File

@ -1,12 +0,0 @@
package com.intellij.tutorials.inspection;
import com.intellij.codeInspection.InspectionToolProvider;
/**
* @author Anna Bulenkova
*/
public class DemoInspectionToolProvider implements InspectionToolProvider {
public Class[] getInspectionClasses() {
return new Class[]{DemoCodeInspection.class};
}
}

View File

@ -1,3 +1,5 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.tutorials.inspection;
import com.intellij.psi.*;

View File

@ -1,7 +0,0 @@
<html>
<body>
Write your description here.
<!-- tooltip end -->
Text after this comment will not be shown in tooltips.
</body>
</html>

View File

@ -2,7 +2,7 @@
<id>org.jetbrains.plugins.sample.PluginSample</id>
<name>Basic plugin example</name>
<version>1.0</version>
<vendor email="support@jetbrains.com" url="http://www.jetbrains.com">JetBrains</vendor>
<vendor email="support@jetbrains.com" url="https://www.jetbrains.com">JetBrains</vendor>
<category>Samples</category>
<description><![CDATA[
Illustration of configuration options.<br>
@ -21,10 +21,6 @@
<!-- Optional dependency on another plugin. If the plugin with the "MySecondPlugin" ID is installed, the contents of mysecondplugin.xml (the format of this file conforms to the format of plugin.xml) will be loaded. -->
<!--<depends optional="true" config-file="custom-plugin.xml">CustomPlugin</depends>-->
<!-- Allows a plugin to integrate its help system (in JavaHelp format) with the IDEA help system. The "file" attribute specifies the name of the JAR file
in the "help" subdirectory of the plugin directory. The "path" attribute specifies the name of the helpset file within the JAR file.-->
<helpset file="plugin-help.jar" path="/Help.hs"/>
<!-- Minimum and maximum build of IDEA compatible with the plugin
see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html
-->

3
faq.md
View File

@ -67,12 +67,9 @@ This FAQ is a topical index of questions that have been asked (and answered) on
* [How do I report out-of-date files?](https://intellij-support.jetbrains.com/hc/en-us/community/posts/206791775-VCS-OpenAPI-what-to-do-with-files-detected-as-out-of-date-)
## Test Framework
* [How can I use the new test framework?](https://intellij-support.jetbrains.com/hc/en-us/community/posts/206143599-New-Testing-Framework)
* [How do I create a library dependency in my test module?](https://intellij-support.jetbrains.com/hc/en-us/community/posts/206791555-library-depndency-in-InspectionTestCase)
## Plugin Architecture
* [Why are the extension elements in my plugin.xml red?](https://intellij-support.jetbrains.com/hc/en-us/community/posts/206138949-plugin-dtd-and-fileEditorProvider-element)
* [How can I read the plugin descriptor of my plugin from code?](https://intellij-support.jetbrains.com/hc/en-us/community/posts/206796695-how-to-read-the-plugin-xml-file-from-within-plugin)
* [How do I provide a custom exception reporter for my plugin?](https://intellij-support.jetbrains.com/hc/en-us/community/posts/206793965-Custom-exception-reporting)
* [How can I add the help topics of my plugin to the IntelliJ Platform help system?](https://intellij-support.jetbrains.com/hc/en-us/community/posts/206760095-how-do-i-plug-into-the-main-idea-help-system-)
* [How do I get the version of IntelliJ Platform under which my plugin is running?](https://intellij-support.jetbrains.com/hc/en-us/community/posts/206800275-How-to-get-the-idea-version)

View File

@ -2,61 +2,44 @@
title: What is the IntelliJ Platform?
---
The _IntelliJ Platform_ is not a product in and of itself but provides a platform for building IDEs. It is used to power JetBrains products such as [IntelliJ IDEA](https://www.jetbrains.com/idea/). It is also Open Source and can be used by third parties to build IDEs, such as [Android Studio](https://developer.android.com/studio/index.html) from Google.
The _IntelliJ Platform_ is not a product in and of itself, but provides a platform for building IDEs. It is used to power JetBrains products such as [IntelliJ IDEA](https://www.jetbrains.com/idea/), [WebStorm](https://www.jetbrains.com/webstorm/), [RubyMine](https://www.jetbrains.com/ruby/), [DataGrip](https://www.jetbrains.com/datagrip/) and [Rider](https://www.jetbrains.com/rider/). It is also Open Source, and can be used by third parties to build IDEs, such as [Android Studio](https://developer.android.com/studio/index.html) from Google.
The IntelliJ Platform provides all of the infrastructure that these IDEs need to provide rich language tooling support. It provides a component driven, cross-platform JVM based application host with a high-level user interface toolkit for creating tool windows, tree views and lists (supporting fast search) as well as popup menus and dialogs.
The _IntelliJ Platform_ provides all of the infrastructure that these IDEs need to provide rich language tooling support. It provides a component driven, cross platform JVM based application host with a high level user interface toolkit for creating tool windows, tree views and lists (supporting fast search) as well as popup menus and dialogs.
It also includes an image editor as well as a full text editor, and provides abstract implementations of syntax highlighting, code folding, code completion, and other rich text editing features.
Furthermore, it includes open APIs to build common IDE functionality, such as a project model and a build system. It also provides infrastructure for a very rich debugging experience, with language agnostic advanced breakpoint support, call stacks, watch windows, and expression evaluation.
Furthermore, it includes pluggable APIs to build common IDE functionality, such as a project model and a build system. It also provides infrastructure for a very rich debugging experience, with language agnostic advanced breakpoint support, call stacks, watch windows and expression evaluation.
But the IntelliJ Platform's real power comes from the Program Structure Interface (PSI). This is a set of functionality that can be used to parse files and build rich syntactic and semantic models of the code, and to build indexes from this data. This powers a lot of functionality, from quick navigating to files, types and symbols, to the contents of code completion windows and find usages, code inspections and code rewriting, for quick fixes or refactorings, as well as many other features.
The IntelliJ Platform includes parsers and a PSI model for a number of languages, and its extensible nature means that it is possible to add support for other languages.
But the _IntelliJ Platform_'s real power comes from the Program Structure Interface (PSI). This is a set of functionality that can be used to parse files and build rich syntactic and semantic models of the code, and to build indexes from this data. This powers a lot of functionality, from quick navigating to files, types and symbols, to the contents of code completion windows and find usages, code inspections and code rewriting, for quick fixes or refactorings, as well as many other features.
The _IntelliJ Platform_ includes parsers and a PSI model for a number of languages, and its composable nature means that it is possible to add support for other languages.
## Plugins
Products built on the IntelliJ Platform are extensible applications, with the platform being responsible for the creation of components, and the injection of dependencies into classes. The IntelliJ Platform fully supports plugins, and JetBrains hosts a [plugin repository](https://plugins.jetbrains.com) that can be used to distribute plugins that support one or more of the products. It is also possible to host your own repositories, and distribute plugins separately.
Products built on the _IntelliJ Platform_ are composable applications, with the platform being responsible for the creation of components, and the injection of dependencies into classes. The _IntelliJ Platform_ fully supports plugins, and JetBrains hosts a [plugin repository](https://plugins.jetbrains.com) that can be used to distribute plugins that support one or more of the products. It is also possible to host your own repositories, and distribute plugins separately.
Plugins can extend the platform in lots of ways, from adding a simple menu item to adding support for a complete language, build system and debugger. A lot of the existing functionality in the IntelliJ Platform is written as plugins that can be included or excluded depending on the needs of the end product. See the [Quick Start Guide](/basics.md) for more details.
Plugins can extend the platform in lots of ways, from adding a simple menu item to adding support for a complete language, build system and debugger. A lot of the existing functionality in the _IntelliJ Platform_ is written as plugins that can be included or excluded depending on the needs of the end product. See the section on [Plugins](/basics.md) for more details.
The IntelliJ Platform is a JVM application, written mostly in Java and Kotlin. You should be experienced with these languages, large libraries written in them, their associated tooling, and large open source projects to write plugins for products based on the IntelliJ Platform. At this time, it's not possible to extend the IntelliJ Platform in non-JVM languages.
The _IntelliJ Platform_ is a JVM application, written mostly in Java and Kotlin. You should be familiar with these languages, and associated tooling, in order to write plugins for products based on the _IntelliJ Platform_. At this time, it's not possible to extend the _IntelliJ Platform_ in non-JVM languages.
## Open Source
The IntelliJ Platform is Open Source, under the [Apache license](upsource:///LICENSE.txt), and [hosted on GitHub](https://github.com/JetBrains/intellij-community).
The _IntelliJ Platform_ is Open Source, under the [Apache license](upsource:///LICENSE.txt), and [hosted on GitHub](https://github.com/JetBrains/intellij-community).
While this guide refers to the IntelliJ Platform as a separate entity, there is no "IntelliJ Platform" GitHub repo. Instead, the platform is considered to be an almost complete overlap with the IntelliJ IDEA Community Edition, which is a free and Open Source version of IntelliJ IDEA Ultimate (the GitHub repo linked above is the [JetBrains/intellij-community](https://github.com/JetBrains/intellij-community) repo).
While this guide refers to the _IntelliJ Platform_ as a separate entity, there is no "IntelliJ Platform" GitHub repo. Instead, the platform is considered to be an almost complete overlap with the IntelliJ IDEA Community Edition, which is a free and Open Source version of IntelliJ IDEA Ultimate (the GitHub repo linked above is the [JetBrains/intellij-community](https://github.com/JetBrains/intellij-community) repo).
The version of the IntelliJ Platform is defined by the version of the corresponding release of IntelliJ IDEA Community Edition.
For example, to build a plugin against IntelliJ IDEA (v2019.1.1,) build #191.6707.61, means specifying the same build number tag to get the correct Intellij Platform files from the `intellij-community` repo.
See the [build number ranges](/basics/getting_started/build_number_ranges.md) page for more information about build numbers corresponding to version numbering.
IntelliJ IDEA Ultimate is a superset of the IntelliJ IDEA Community Edition. It is based on the community edition, but includes closed source plugins ([see this feature comparison](https://www.jetbrains.com/idea/features/editions_comparison_matrix.html)). Similarly, other products such as WebStorm and DataGrip are based on the IntelliJ IDEA Community Edition, but with a different set of plugins included and excluding other default plugins.
Typically, an IDE that is based on the IntelliJ Platform will include the `intellij-community` repo as a Git submodule and provide configuration to describe which plugins from the `intellij-community`, and which custom plugins will make up the product. This is how the IDEA Ultimate team work, and they contribute code to both the custom plugins and the IntelliJ Platform itself.
This allows plugins to target multiple products, as each product will include base functionality and a selection of plugins from the IntelliJ IDEA Community Edition repo. This is what we call the _IntelliJ Platform_.
### IDEs Based on the IntelliJ Platform
The IntelliJ Platform underlies many JetBrains IDEs.
IntelliJ IDEA Ultimate is a superset of the IntelliJ IDEA Community Edition, but includes closed source plugins ([see this feature comparison](https://www.jetbrains.com/idea/features/editions_comparison_matrix.html)). Similarly, other products such as WebStorm and DataGrip are based on the IntelliJ IDEA Community Edition, but with a different set of plugins included and excluding other default plugins.
This allows plugins to target multiple products, as each product will include base functionality and a selection of plugins from the IntelliJ IDEA Community Edition repo.
Typically, an IDE that is based on the _IntelliJ Platform_ will include the `intellij-community` repo as a Git submodule and provide configuration to describe which plugins from the `intellij-community`, and which custom plugins will make up the product. This is how the IDEA Ultimate team work, and they contribute code to both the custom plugins and the _IntelliJ Platform_ itself.
The following IDEs are based on the IntelliJ Platform:
* JetBrains IDEs
* [AppCode](https://www.jetbrains.com/objc/)
* [CLion](https://www.jetbrains.com/clion/)
* [DataGrip](https://www.jetbrains.com/datagrip/)
* [GoLand](https://www.jetbrains.com/go/)
* [IntelliJ IDEA](https://www.jetbrains.com/idea/)
* [MPS](https://www.jetbrains.com/mps/)
* [PhpStorm](https://www.jetbrains.com/phpstorm/)
* [PyCharm](https://www.jetbrains.com/pycharm/)
* [RubyMine](https://www.jetbrains.com/ruby/)
* [WebStorm](https://www.jetbrains.com/webstorm/)
* [Android Studio](https://developer.android.com/studio/index.html) IDE from Google.
* [CUBA Studio](https://www.cuba-platform.com/)
Of course, because the _IntelliJ Platform_ is open source, we also accept [pull requests](https://github.com/JetBrains/intellij-community/pulls) to the platform itself, rather than just opening the source for view. Issue tracking is managed with [YouTrack (using the IDEA project)](https://youtrack.jetbrains.com/issues/IDEA), and if you wish to contribute to the platform, it is usually a good idea to open an issue describing the changes you wish to make before making the changes - this allows the team chance to give feedback and advice. More details can be found in the section on [Contributing to the IntelliJ Platform](/basics/platform_contributions.md).
JetBrains [Rider](https://www.jetbrains.com/rider/) uses the IntelliJ Platform differently than other IntelliJ based IDEs. It uses the IntelliJ Platform to provide the user interface for a C# and .NET IDE, with the standard IntelliJ editors, tool windows, debugging experience and so on. It also integrates into the standard Find Usages and Search Everywhere UI, and makes use of code completion, syntax highlighting, and so on.
## Rider
However, Rider doesn't create a full PSI (syntactic and semantic) model for C# files. Instead, it reuses [ReSharper](https://www.jetbrains.com/resharper/) to provide language functionality. All of the C# PSI model and all inspections and code rewriting, such as quick fixes and refactorings are run out of process, in a command line version of ReSharper. This means that creating a plugin for Rider involves two parts - a plugin that lives in the IntelliJ "front end" to show user interface, and a plugin that lives in the ReSharper "back end" to analyze and work with the C# PSI.
[Rider](https://www.jetbrains.com/rider/) uses the _IntelliJ Platform_ differently to other IntelliJ based IDEs. It uses the _IntelliJ Platform_ to provide the user interface for a C# and .NET IDE, with the standard IntelliJ editors, toolwindows, debugging experience and so on. It also integrates into the standard Find Usages and Search Everywhere UI, and makes use of code completion, syntax highlighting and so on.
However, it doesn't create a full PSI (syntactic and semantic) model for C# files. Instead, it reuses [ReSharper](https://www.jetbrains.com/resharper/) to provide language functionality. All of the C# PSI model, and all inspections and code rewriting, such as quick fixes and refactorings are run out of process, in a command line version of ReSharper. This means that creating a plugin for Rider involves two parts - a plugin that lives in the IntelliJ "front end" to show user interface, and a plugin that lives in the ReSharper "back end" to analyse and work with the C# PSI.
Fortunately, many plugins can simply work with the ReSharper backend - Rider takes care of displaying the results of inspections and code completion, and many plugins can be written that don't require an IntelliJ UI component. More details can be found in the Product Specific section.

View File

@ -8,15 +8,13 @@ The _IntelliJ Platform_ is very large, and very capable, and its size and scope
- [Getting Started](/basics/getting_started.md) with plugins.
- [Testing plugins](/basics/testing_plugins.md).
- [Architectural overview] - a brief tour of the different layers of the _IntelliJ Platform_.
- Component model - the _IntelliJ Platform_ is a component based application, and is responsible for creating components and injecting dependencies. Understanding this is necessary for building plugins.
- Extension points - how to register components with extension points, and how to find out what extension points are available.
- [Extension points](/basics/plugin_structure/plugin_extensions_and_extension_points.md) - how to register components with extension points, and how to find out what extension points are available.
- [Virtual files](/basics/architectural_overview/virtual_file.md) - all file access should go through the Virtual File System which abstracts and caches the file system. This means you can work with files that are on the local file system, in a zip file or are old versions from version control.
- [Extension points](/basics/plugin_structure/plugin_extensions_and_extension_points.md)
## Code model
The _IntelliJ Platform_'s code model is called the PSI - the Program Structure Interface. The PSI parses code, builds indexes and creates a semantic model.
The _IntelliJ Platform_'s code model is called the PSI - the [Program Structure Interface](/basics/architectural_overview/psi.md). The PSI parses code, builds indexes and creates a semantic model.
## Common extension points

View File

@ -31,7 +31,7 @@ Ultimately, the goal is to provide developers with roadmaps for implementing fun
Each roadmap should contain:
* Pointers to SDK documentation about the IntelliJ Platform APIs needed to implement the functionality.
* Pointers to relevant _basic_ SDK sample plugins.
* Pointers to related _advanced_ SDK sample plugins.
* Pointers to relevant _advanced_ SDK sample plugins.
## Naming Conventions for SDK Plugins
For _basic_ samples, the naming convention is focused on the IntelliJ Platform APIs being demonstrated.
@ -42,9 +42,7 @@ There is only one _basic_ sample per IntelliJ Platform API area.
For _advanced_ code samples, the name should reflect the complex functionality delivered by the plugin rather than the IntelliJ Platform APIs.
Advanced samples will be cross-referenced to the IntelliJ Platform APIs demonstrated in the sample.
Note that the naming convention relates to the `Artifact ID`, which is the Gradle property `rootProject.name`.
This is different than the `<name>` definition provided in the [`plugin.xml`](#pluginxml-conventions) file.
See the [Plugin Gradle Properties](/tutorials/build_system/prerequisites.md#plugin-gradle-properties-and-plugin-configuration-file-elements) section for more information about the distinction.
Regardless of basic or advanced, an SDK plugin name is also known as the `Artifact ID` in the Gradle plugin wizard.
## Plugin Copyright Statements
Use the standard intellij-community copyright notice in all sample plugins authored by JetBrains:
@ -54,11 +52,11 @@ Copyright 2000-$today.year JetBrains s.r.o. Use of this source code is governed
The copyright statement must appear in every source file with the `$today.year` [Velocity](https://www.jetbrains.com/help/idea/copyright-profiles.html) template resolved.
## Plugin ID Conventions
The `Group ID` for SDK plugins is always `org.intellij.sdk`.
In general, the plugin ID is the `Group ID` concatenated with the `Artifact ID`.
The plugin ID (`<id>` in `plugin.xml`) always begins with `org.intellij.sdk`.
The plugin ID is known as the `Group ID` in the Gradle plugin wizard.
For _basic_ code samples, it is not necessary to include "basic" in the plugin ID.
A plugin like `facet_basics` has the plugin ID `org.intellij.sdk.facet`.
A plugin like `facet_basics` has the ID `org.intellij.sdk.facet`.
## Plugin Package Names
Packages in plugins should begin with the plugin ID.
@ -66,7 +64,7 @@ If there is only one package in a plugin, then the package name is the same as t
## Plugin Directory Structure
SDK sample code should have a standard directory footprint.
Standardized structure not only makes the samples simpler to navigate and understand, but it builds on the default Gradle plugin project structure.
Standardized structure not only makes the samples easier to navigate and understand, but it builds on the default Gradle plugin project structure.
The following is the directory structure for a `foo_basics` plugin.
```text
code_samples/
@ -97,13 +95,11 @@ New SDK code samples should be developed [using Gradle](/tutorials/build_system.
As of this writing, the use of Gradle in SDK code samples still relies heavily on the `plugin.xml` for specifying the plugin configuration.
At a later, second phase, the SDK code samples will transition to rely more on the Gradle configuration.
The default contents of a `build.gradle` file are produced by the [New Project Wizard](/tutorials/build_system/prerequisites.md#creating-a-gradle-based-intellij-platform-plugin-with-new-project-wizard).
The default contents of a `build.gradle` file are produced by the [Gradle project wizard](/tutorials/build_system/prerequisites.md#create-a-plugin-project-from-scratch).
A consistent structure for an SDK code sample's `build.gradle` file is important for clarity and is based on the default produced by the project wizard.
Comments in SDK code sample `build.gradle` files should only draw attention to the parts of the Gradle configuration that are unique for a plugin.
For SDK code samples, a few alterations are needed to the default build.gradle file produced by the plugin wizard:
* Maintain the Gradle properties `version` (`project.version`) and `group` (`project.group`).
See the [Plugin Gradle Properties](/tutorials/build_system/prerequisites.md#plugin-gradle-properties-and-plugin-configuration-file-elements) section for how these Gradle properties relate to the elements in `plugin.xml`.
For SDK code samples a few alterations are needed to the default build.gradle file produced by the plugin wizard:
* Add the following statements to the [Setup DSL](https://github.com/JetBrains/gradle-intellij-plugin/blob/master/README.md#setup-dsl) (`intellij{}`) section:
```groovy
// Prevents patching <idea-version> attributes in plugin.xml
@ -128,7 +124,7 @@ The sequence of elements in an SDK code sample `plugin.xml` file is:
* `<id>` Use the fully qualified [Plugin ID](#plugin-id-conventions).
* `<name>` The name value does not have to match the [Plugin Name](#naming-conventions-for-sdk-plugins).
It might reflect the functionality of the plugin.
The name must start with "SDK: ".
The name must start with "SDK:".
* `<version>` The code sample's version in MAJOR.MINOR.FIX format.
* MAJOR corresponds to a significant upgrade in functionality.
* MINOR corresponds to minor refactoring and small improvements in functionality.
@ -141,7 +137,7 @@ The sequence of elements in an SDK code sample `plugin.xml` file is:
Add this attribute if a plugin sample is deprecated with a release of the IntelliJ Platform.
* `<depends>` Include at least one dependency with the module `com.intellij.modules.platform` to indicate basic plugin compatibility with IntelliJ Platform-based products.
Add `<depends>` elements containing module FQNs as needed to describe more specialized [Compatibility with Multiple Products](/basics/getting_started/plugin_compatibility.md), and any other [Plugin Dependencies](/basics/plugin_structure/plugin_dependencies.md).
* `<description>` is a concise explanation of what is being demonstrated and how a user would access the functionality.
* `<description>` is a succinct explanation of what is being demonstrated and how a user would access the functionality.
* `<change-notes>` is an ordered list by version numbers with a brief description of changes for each version.
* `<vendor>` Set the value to `IntelliJ Platform SDK`.
Set the attributes:

268
intro/sdk_style.md Normal file
View File

@ -0,0 +1,268 @@
---
title: Style Guide for SDK Documents
---
This document describes the writing style used in authoring open source IntelliJ Platform SDK documentation.
Before you begin, please read this page thoroughly as well as the [Code of Conduct](/CODE_OF_CONDUCT.md) and [License](https://github.com/JetBrains/intellij-sdk-docs/blob/master/LICENSE.txt) documents.
For information about contributing to the IntelliJ Platform itself, please visit [Contributing to the IntelliJ Platform](/basics/platform_contributions.md).
First and foremost, we should keep in mind our audience and their objectives:
_Someone reading technical content is usually looking to answer a specific question.
That question might be broad or narrowly-focused, but either way, our goal is to provide answers without distraction._
The style of the _Intellij Platform SDK_ documentation is captured by using a markup language named [_Markdown_](https://github.github.com/gfm/).
The following sections describe the SDK documentation style in terms of the Markdown formats:
* [Documentation Markup Style](#documentation-markup-style)
* [Page Format](#page-format)
* [Redirects](#redirects)
* [Table of Contents for a Page](#table-of-contents-for-a-page)
* [Text Format Conventions](#text-format-conventions)
* [Liquid tags and filters](#liquid-tags-and-filters)
* [Syntax highlighting](#syntax-highlighting)
* [Tables](#tables)
* [Links](#links)
* [Callouts](#notes-and-callouts)
* [Images](#images)
* [_SUMMARY.md Site Table of Contents](#summary-site-table-of-contents)
* [Repository Submodules](#repository-submodules)
## Documentation Markup Style
By default, when building the site, all files are copied to the destination `_site` folder.
Some files are excluded in the `_config.yml` and `sdkdocs-template/jekyll/_config-defaults.yml` files.
The documentation files themselves are [Markdown](https://github.github.com/gfm/) files (`*.md`) that get automatically converted to HTML when the site is built.
### Page Format
Only Markdown files beginning with a [YAML](https://yaml.org) header are converted to HTML.
If the Markdown file doesn't contain a header, it won't be converted.
In other words, to convert a `.md` file to HTML, it should look like this:
```yaml
---
---
Lorem ipsum...
```
The two lines at the top of the file are the markers of the YAML _front matter_.
Fields can be added in between these markers, and are used when generating the HTML.
Typically, this header is empty, although it is required by Jekyll (if omitted, the file isn't converted).
The YAML header can contain data that is used when generating the site.
For example, the page title can be specified as a simple piece of Markdown - `# Title`, or it can be specified in the YAML, and the page template displays it appropriately:
```yaml
---
title: The Title Of The Page
---
Lorem ipsum...
```
The YAML header can also include [redirect](#redirects) information.
Line spacing around headings in Markdown files generally doesn't affect the HTML conversion, but it does make MD pages more readable for authors:
* No space between a heading and the first content below it.
* One space before a heading if it is the same level or a sub-heading of the previous section.
* Two spaces before a heading that is higher-level than the heading of the previous section.
### Redirects
The documentation site is set up to include the [jekyll-redirect-from](https://github.com/jekyll/jekyll-redirect-from) plugin, which will generate "dummy" pages that automatically redirect to a given page.
For example, to specify that the `index.html` page be generated to redirect to `README.md`, the `README.md` file should include the following in the YAML header:
```yaml
---
redirect_from:
- /index.html
---
Lorem ipsum...
```
The redirect will create an `index.html` file that will automatically redirect to the generated `README.html` file.
Redirects enable the site URL to automatically show the `README.html` file - `http://localhost:4001/foo-test/` will try to load `index.html`, which will automatically redirect to `README.html`.
It is also useful to redirect when renaming or moving files.
Multiple redirects can be added to the YAML header.
### Table of Contents for a Page
The site is configured to use the [Kramdown Markdown converter](http://kramdown.gettalong.org), which adds some extra features over traditional Markdown.
For example, "attribute lists" that can apply attributes to the generated elements.
One useful attribute is `{:toc}`, which can be applied to a list item, which will get replaced with a list of links to header items.
E.g. the following list item will be replaced by links to all of the header items in the page:
```md
* Dummy list item
{:toc}
```
Further Kramdown features are described on the [converter page](https://kramdown.gettalong.org/converter/html.html), and attribute lists are described on the [syntax page](http://kramdown.gettalong.org/syntax.html).
Note that source code formatting is configured to use [GitHub Flavoured Mardown](https://help.github.com/articles/github-flavored-markdown/) and "code fences", see below.
### Liquid tags and filters
Jekyll uses the [Liquid](https://shopify.github.io/liquid/) templating language to process files.
This process means standard Liquid tags and filters are available.
There should be little need to use them, however, as the Markdown format is already quite rich.
See the [Jekyll site](https://jekyllrb.com/docs/liquid/) for more details.
### Text Format Conventions
Consistent text styles are used to standardize references and keywords:
* Menu paths are formatted as bold with pipe characters separating each level: \*\*Preferences \\\| Editor\*\* (**Preferences \| Editor**)
* Keywords and quotations are formatted as italic: \_UI Theme\_ (_UI Theme_)
* File names and paths, in-paragraph code fragments, and language keywords are formatted as code: \`interface\` (`interface`),
* File formats are shown as all capital letters: PNG and XML.
* File name extensions are not capitalized when part of a full file name, path, or URL: `filename.ext`.
* [Links](#links) have a particular format depending on the type of link.
Consistent terminology helps the reader grasp new concepts more quickly:
* The open source code in the GitHub repository `intellij-community` is known as the _IntelliJ Platform_.
Use the full phrase in SDK documentation.
* IDEs based on the IntelliJ Platform are described as _IntelliJ Platform-based IDEs_.
Once that term is used on a page, after that authors may use IDEs
* When referring to JetBrains products always use the full name such as _IntelliJ IDEA_.
### Syntax highlighting
Source code can be represented by using [GitHub Flavoured Markdown](https://help.github.com/articles/github-flavored-markdown/) code fences, which are three backticks:
```
// Source code goes here...
```
Syntax highlighting can be applied by specifying the language after the first set of ticks:
```csharp
// Some C# code
```
```java
// Some Java code
```
Here is the list of [supported languages](https://github.com/jneen/rouge/wiki/List-of-supported-languages-and-lexers), and also [Kotlin](https://kotlinlang.org), of course.
Please keep code samples concise and avoid any unnecessary "surrounding" code or import statements.
<!-- //TODO: Not currently supported by rouge, or by the site's CSS
The site is also configured to highlight a range of files in the source code, by specifying `{start-end}` which is the start and end line of the highlighting:
```java{2-3}
// Not highlighted
// Highlighted
// Highlighted
// Not highlighted
```
-->
### Tables
The Kramdown parser also supports tables.
The syntax is to use the pipe (`|`) and minus symbols:
```md
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Blah | Blah | Blah |
```
### Links
Links are handled as normal Markdown links and can be anchored to external sites, pages within the sites, or headings in the sites.
When a Markdown header is converted to an HTML header, it is assigned an ID so that it can be linked.
For example, `## Introduction` will get the ID of `introduction`, and can be linked either in the same page or cross-page as described below.
Links to files in the IntelliJ Platform (`intellij-community`) repository use `upsource:///` instead of the full URL to the repository.
The `upsource:///` URI effectively points to the root of the `intellij-community` repository.
* `[README.md](upsource:///README.md)` for links to general files in the repository.
* `[`\`AnAction\``](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java)` for links to source code files for interfaces and classes.
Note the use of \`\` characters surrounding the class name in the link.
General links have one of the following formats:
* `[External site](https://example.org)` links to an external site.
* Linking to pages in the SDK documentation:
* `[SDK doc page in current directory](Page2.md)` links to an SDK doc page in the same directory as the current page.
Note that the extension is `.md`, _NOT_ `.html`.
* `[SDK page in another folder](/Folder2/Page2.md)` links to a page in another folder.
Note that the URL is navigating from the project root - this works even if the site is hosted in a sub-folder (e.g. this link will work for `http://localhost:4000/devguide/Folder2/Page2.html`).
Relative links also work (`../Folder2/Page2.md`).
* Linking to specific _sections_ on pages in the SDK documentation.
The anchor name will be all lower case, and spaces are replaced with `-`, e.g. `## Page setup` becomes `#page-setup`.
* `[Link to a section on the current page](#another-section)` links to a heading on the current page.
* `[Link to the section on another page](Page2.md#another-section)` links to a heading on another page.
### Notes and callouts
Notes and callouts can be specified using the blockquote syntax.
The converter looks at the first following word to see if it is bold.
If so, it applies a callout style.
The example below will be displayed as a callout, styled as a "note":
> **NOTE** This is a note
> **NOTE** This is a note
The styles available for callouts are:
* TODO - Generally not used in SDK documentation.
Embed `<--! //TODO: explanation... -->` instead, which is not visible in published documentation.
* TIP - Information that makes the reader more productive.
* NOTE - Information that is important for the reader to understand.
This callout is reserved for key points and concepts.
* WARNING - Information critical to the user.
Use this callout for information that prevents failures or errors.
### Images
Images can be included by adding the file directly to the `intellij-sdk-docs` repository.
Each subject directory typically has an `img` subdirectory.
Keep images close to the corresponding documentation file in the repository directory structure.
Images in this documentation are generally screenshots.
The preferred image format is PNG at 144 DPI resolution.
A resolution of 72 DPI is acceptable but may look blurry on high-resolution monitors.
It is important to reduce the size of image files to prevent bloating the repository and impacting the performance of the documentation site.
Resize an image to be nearly the desired width on a documentation page.
Reducing an image's dimensions is the most effective way to reduce image file size.
Also optimize the image files using a tool such as the [PNG optimizer](https://plugins.jetbrains.com/plugin/7942-png-optimizer).
Images are embedded in a document by adding a Markdown link to the image like so:
![Alt text](path-to-img.png)
If the width of an image needs to be adjusted, use Kramdown markup:
![Alt text](path-to-img.png){:width="42px"}
## _SUMMARY Site Table of Contents
The table of contents for the site is displayed in the tree view on the left-hand side of the site, and it is generated from the `_SUMMARY.md` file.
It is a simple Markdown list, with each item in the list being a link to another Markdown page, either in the root folder, or sub-folders.
The list can have nested items, which are displayed as child items in the table of contents.
> ***WARNING*** Every Markdown (`*.md`) document within the SDK repository (`intellij-sdk-docs`) must have an entry in `_SUMMARY.md`.
```md
# Summary
* [Introduction](README.md)
* [About This Guide](Intro/About.md)
* [Key Topics](Intro/KeyTopics.md)
```
The contents can be split into "parts" by separating the list into several lists, each new list starting with a level 2 heading (`##`).
```md
# Summary
* [Introduction](README.md)
* [About This Guide](Intro/About.md)
* [Key Topics](Intro/KeyTopics.md)
## Part I - Extending the Platform
* [Getting Started](Docs/GettingStarted.md)
* ...
```
If a node doesn't have a link but is just plain text, it will still appear in the table of contents but will be greyed out and not clickable.
It acts as a placeholder for a documentation item.
A placeholder is useful to keep track of what should be documented, but hasn't yet, and can be useful to show readers that the topic exists, but isn't yet documented (Pull Requests always welcome!).

View File

@ -20,9 +20,12 @@ easier for the analysis, or ask JetBrains to manually add any missed feature typ
## File Type
A plugin can support specific file types (file extensions). When there is a file with a specific extension open in an IDE, a hint will be shown to users prompting them to install your plugin.
You should extend [FileTypeFactory](upsource:///platform/platform-api/src/com/intellij/openapi/fileTypes/FileTypeFactory.java)
and feed supported file extensions in `createFileTypes(FileTypeConsumer)`. Values of `FileTypeConsumer` are analyzed by the `feature extractor`.
A plugin can [support specific file types](/reference_guide/custom_language_support/registering_file_type.md) (file extensions). When there is a file with a specific extension open in an IDE, a hint will be shown to users prompting them to install your plugin.
Both variants are supported by the `feature extractor`:
- Extend [FileTypeFactory](upsource:///platform/platform-api/src/com/intellij/openapi/fileTypes/FileTypeFactory.java)
and feed supported file extensions in `createFileTypes(FileTypeConsumer)`, values of `FileTypeConsumer` are analyzed.
- Register `com.intellij.fileType` extension point (available in 2019.2+), `extensions` attribute is analyzed.
A suggestion to install plugins which support the _\*.d_ Extension Type:

View File

@ -6,11 +6,16 @@ title: Incompatible Changes in IntelliJ Platform and Plugins API 2016.*
See the note on how to document new problems on the main page reference_guide/api_changes_list.md
-->
# 2016.3
## Changes in IntelliJ Platform 2016.3
[`com.intellij.openapi.application.ApplicationListener.afterWriteActionFinished`](upsource:///platform/core-api/src/com/intellij/openapi/application/ApplicationListener.java?nav=1481:1505:focused&line=45) abstract method added
: Implement this method or extend [`com.intellij.openapi.application.ApplicationAdapter`](upsource:////platform/core-api/src/com/intellij/openapi/application/ApplicationAdapter.java) class instead of implementing the interface.
# 2016.2
## Changes in IntelliJ Platform 2016.2
`com.intellij.util.net.HttpConfigurable.PROXY_LOGIN` field removed

View File

@ -6,6 +6,8 @@ title: Incompatible Changes in IntelliJ Platform and Plugins API 2017.*
See the note on how to document new problems on the main page reference_guide/api_changes_list.md
-->
# 2017.3
## Changes in IntelliJ Platform 2017.3
`com.intellij.internal.statistic.AbstractApplicationUsagesCollector` class removed

View File

@ -10,6 +10,8 @@ See the note on how to document new problems on the main page reference_guide/ap
-->
# 2018.3
## Changes in IntelliJ Platform 2018.3
`com.intellij.openapi.externalSystem.action.ExternalSystemAction.isEnabled` method `AnActionEvent` parameter marked `@NotNull`
@ -37,6 +39,8 @@ See the note on how to document new problems on the main page reference_guide/ap
: Use `com.intellij.psi.meta.PsiMetaData.getDependencies` instead.
# 2018.2
## Changes in IntelliJ Platform 2018.2
`com.intellij.util.Query.forEach` method parameter type changed from `Processor<Result>` to `Processor<? super Result>`
@ -64,6 +68,8 @@ See the note on how to document new problems on the main page reference_guide/ap
: Update `InterpreterFactory` implementations accordingly.
# 2018.1
## Changes in IntelliJ Platform 2018.1
`com.google.common.base.Objects.ToStringHelper` class removed

View File

@ -10,9 +10,17 @@ See the note on how to document new problems on the main page reference_guide/ap
-->
# 2019.2
## Changes in IntelliJ Platform 2019.2
`com.intellij.openapi.components.BaseState.map$default(BaseState, Map, int, Object)` method removed
: Use `com.intellij.openapi.components.BaseState.map()` instead.
`org.nustaq` package removed
: [fast-serialization](https://github.com/RuedigerMoeller/fast-serialization) library was removed, please use `com.intellij.serialization.ObjectSerializer` instead.
`java.org.java_websocket` package removed
: [Java-WebSocket Library](https://github.com/TooTallNate/Java-WebSocket) was removed, bundle it with your plugin instead.
: [Java-WebSocket](https://github.com/TooTallNate/Java-WebSocket) library was removed, bundle it with your plugin instead.
`com.intellij.ui.layout.Cell.invoke$default(Cell, JComponent, CCFlags[], int, GrowPolicy, String, int, Object)` method parameter type changed
: Signature of this function has been seriously changed without possibility to keep the old function. Change invocations and overriding of that function according to new parameters and recompile the code.
@ -23,6 +31,14 @@ See the note on how to document new problems on the main page reference_guide/ap
`org.jetbrains.intellij.build.ProductProperties`: fields `yourkitAgentBinariesDirectoryPath` and `enableYourkitAgentInEAP` have been removed
: Please bundle [performanceTesting plugin](https://plugins.jetbrains.com/plugin/7819-performance-testing) in case you would like to bundle YourKit profiler within your IDE.
`com.intellij.extapi.psi.PsiElementBase` class removed
: Please use `com.intellij.psi.impl.PsiElementBase` or one of its descendants as a base class for PSI elements, e.g. `com.intellij.extapi.psi.ASTWrapperPsiElement`, as suggested in [Custom Language Support Tutorial](../../tutorials/custom_language_support/grammar_and_parser.md).
`com.intellij.extapi.psi.MetadataPsiElementBase` class removed
: Please use different base class for PSI elements.
# 2019.1
## Changes in IntelliJ Platform 2019.1
`kotlinx.coroutines.experimental` package removed

View File

@ -2,6 +2,8 @@
title: Notable Changes in IntelliJ Platform and Plugins API 2018.*
---
# 2018.3
## Notable Changes in IntelliJ Platform 2018.3
ASM Library 7.0
@ -13,6 +15,8 @@ Extendable Registry keys
Editor: content between text lines
: Ability to add arbitrary content (preview, debugger information, etc.). [Issue](https://youtrack.jetbrains.com/issue/IDEA-183815)
# 2018.2
## Notable Changes in IntelliJ Platform 2018.2
_Run Anything_ (**Double CTRL**)

View File

@ -2,11 +2,37 @@
title: Notable Changes in IntelliJ Platform and Plugins API 2019.*
---
# 2019.2
## Notable Changes in IntelliJ Platform 2019.2
`com.intellij.openapi.startup.StartupActivity` background variant
: Use new dedicated extension point `com.intellij.backgroundPostStartupActivity` (see Javadoc for `StartupActivity#BACKGROUND_POST_STARTUP_ACTIVITY`).
`com.intellij.codeHighlighting.TextEditorHighlightingPassFactory` registration
: Use new dedicated extension point `com.intellij.highlightingPassFactory`.
`com.intellij.openapi.fileTypes.FileTypeFactory` deprecated
: When registering file type via file extension or exact file name matching, use extension point `com.intellij.fileType` instead (see [Sample](/tutorials/custom_language_support/language_and_filetype.md#b-register-file-type-20192-or-later)).
Unbundled plugins in IntelliJ IDEA
: Several plugins for no longer actively maintained technology have been moved to a [separate repository](https://github.com/JetBrains/intellij-obsolete-plugins/). If your plugin depends on them, users will need to install them from the [JetBrains plugin repository](https://plugins.jetbrains.com).
`@org.jetbrains.annotations.ApiStatus.NonExtendable`
: Indicates that the annotated API class, interface or method must not be extended, implemented or overridden by external plugins but can be only obtained or instantiated (for classes and interfaces), or called (for methods).
`@org.jetbrains.annotations.ApiStatus.OverrideOnly`
: Indicates that the annotated method is part of SPI (Service Provider Interface), which is intended to be only implemented or overridden but never called by external plugins.
`com.intellij.util.Query.forEach`
: Defaults to thread-safe to prevent problems with clients using unsynchronized collections.
`com.intellij.openapi.projectRoots.SdkType#getInvalidHomeMessage`
: Returns dedicated message when invalid SDK path was chosen (e.g., JRE instead of JDK).
# 2019.1
## Notable Changes in IntelliJ Platform 2019.1
`@org.jetbrains.annotations.ApiStatus.AvailableSince`
@ -15,8 +41,11 @@ title: Notable Changes in IntelliJ Platform and Plugins API 2019.*
`@org.jetbrains.annotations.ApiStatus.ScheduledForRemoval`
: External annotations for IntelliJ Platform are generated and attached to plugin projects automatically. This allows highlighting of API which has been removed in newer platform versions.
`@org.jetbrains.annotations.ApiStatus.Internal`
: Indicates that the annotated element must not be considered as a public API. Do not use outside of IntelliJ Platform. [Issue](https://youtrack.jetbrains.com/issue/IDEA-211175)
`PsiReferenceProvider` assert underlying element
: Assert references are created for the given underlying `PsiElement`. [Issue](https://youtrack.jetbrains.com/issue/IDEA-203954)
`CachedValue` more strict assertions
: Enabled in tests and EAP/internal mode, see `CachedValueStabilityChecker` Javadoc.
: Enabled in tests and EAP/internal mode, see `CachedValueStabilityChecker` Javadoc.

View File

@ -55,15 +55,11 @@ Enabling `--charat` option passes the source data for lexing as a
and not as an array of characters.
For developing lexers using JFlex, the
[JFlex Support](https://plugins.jetbrains.com/plugin/263-jflex-support)
plugin can be useful.
For developing lexers using JFlex, the [GrammarKit plugin](https://plugins.jetbrains.com/plugin/6606-grammar-kit) can be useful.
It provides syntax highlighting and other useful features for editing JFlex files.
[GrammarKit plugin](https://plugins.jetbrains.com/plugin/6606-grammar-kit)
also has builtin JFlex support.
There is also an (older) [JFlex Support](https://plugins.jetbrains.com/plugin/263-jflex-support) plugin available.
**Note:**
Lexers, and in particular JFlex-based lexers, need to be created in such a way that they always match the entire contents of the file, without any gaps between tokens, and generate special tokens for characters which are not valid at their location.
> **NOTE** Lexers, and in particular JFlex-based lexers, need to be created in such a way that they always match the entire contents of the file, without any gaps between tokens, and generate special tokens for characters which are not valid at their location.
Lexers must never abort prematurely because of an invalid character.
**Example**:

View File

@ -48,15 +48,14 @@ the base implementation of
[PsiElement](upsource:///platform/core-api/src/com/intellij/psi/PsiElement.java),
are provided by *IntelliJ Platform*.
There is currently no ready way to reuse existing language grammars, for example, from ANTLR, for creating custom language parsers.
The parsers need to be coded manually.
Custom language parser and PSI classes can be generated from grammars using
While coding parser manually is quite possible, we highly recommend generating parser and corresponding PSI classes from grammars using
[Grammar-Kit](https://plugins.jetbrains.com/plugin/6606-grammar-kit) plugin.
Besides code generation it provides various features for editing grammar files: syntax highlighting, quick navigation, refactorings and more.
The Grammar-Kit plugin is built using its own engine and its source code can be found on
Besides code generation, it provides various features for editing grammar files: syntax highlighting, quick navigation, refactorings, and more.
The Grammar-Kit plugin is built using its own engine; its source code can be found on
[GitHub](https://github.com/JetBrains/Grammar-Kit).
For re-using existing ANTLRv4 grammars, see [antlr4-intellij-adaptor](https://github.com/antlr/antlr4-intellij-adaptor) library.
The language plugin provides the parser implementation as an implementation of the
[PsiParser](upsource:///platform/core-api/src/com/intellij/lang/PsiParser.java)
interface, returned from

View File

@ -12,7 +12,8 @@ which passes a
subclass to its base class constructor.
To register a file type, the plugin developer provides a subclass of
[FileTypeFactory](upsource:///platform/platform-api/src/com/intellij/openapi/fileTypes/FileTypeFactory.java), which is registered via the `com.intellij.fileTypeFactory`
[platform extension point](upsource:///platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml).
[platform extension point](upsource:///platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml).
> **NOTE** When targeting 2019.2 or later only, using `com.intellij.fileType` extension point is preferred to using dedicated `FileTypeFactory`.
**Example**:
[LanguageFileType](upsource:///platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java)

View File

@ -8,7 +8,7 @@ This page provides high-level overview of *External System* sub-system.
# Rationale
There are multiple project management systems ([maven](https://maven.apache.org/), [gradle](http://www.gradle.org/), [sbt](http://www.scala-sbt.org/) etc) and it's good to support them at the IDE. Luckily, they all provide a similar set of facilities from the integration point of view:
There are multiple project management systems ([maven](https://maven.apache.org/), [gradle](https://www.gradle.org/), [sbt](https://www.scala-sbt.org/) etc) and it's good to support them at the IDE. Luckily, they all provide a similar set of facilities from the integration point of view:
* build IDE project from external system config (pom.xml, build.gradle etc);
* provide a list of available tasks;

View File

@ -10,6 +10,8 @@ To develop plugins you will need to use _IntelliJ IDEA Ultimate Edition_ version
### Setting up IntelliJ Platform SDK
> **NOTE** This applies to [Plugin DevKit](/basics/getting_started/using_dev_kit.md) projects only. For [Gradle](/tutorials/build_system.md) projects, simply add dependency to bundled Spring plugin `com.intellij.spring`.
##### New SDK
Please create an IntelliJ Platform SDK to include all minimum required files.
Then add `$IDEA_HOME$/plugins/Spring/lib/spring.jar` to its _classpath_ (_not_ to your plugin module's dependencies).

View File

@ -10,7 +10,7 @@ title: XML DOM API
This article is intended for plugin writers who create custom web server integrations, or some UI for easy XML editing. It describes the *Document Object Model* (DOM) in IntelliJ Platform --- an easy way to work with DTD or Schema-based XML models.
The following topics will be covered: working with DOM itself (reading/writing tags content, attributes, and subtags) and easy XML editing in the UI by connecting UI to DOM.
It's assumed that the reader is familiar with Java 5, Swing, IntelliJ Platform XML PSI (classes [`XmlTag`](upsource:///xml/xml-psi-api/src/com/intellij/psi/xml/XmlTag.java), [`XmlFile`](upsource:///xml/xml-psi-api/src/com/intellij/psi/xml/XmlFile.java), [`XmlTagValue`](upsource:///xml/xml-psi-api/src/com/intellij/psi/xml/XmlTagValue.java), etc.), IntelliJ Platform plugin development basics (application and project components, file editors).
It's assumed that the reader is familiar with Java, Swing, IntelliJ Platform XML PSI (classes [`XmlTag`](upsource:///xml/xml-psi-api/src/com/intellij/psi/xml/XmlTag.java), [`XmlFile`](upsource:///xml/xml-psi-api/src/com/intellij/psi/xml/XmlFile.java), [`XmlTagValue`](upsource:///xml/xml-psi-api/src/com/intellij/psi/xml/XmlTagValue.java), etc.), IntelliJ Platform plugin development basics (application and project components, file editors).
## Introduction
@ -533,9 +533,9 @@ Thank you for your time and attention. We hope you've found this article really
### Further Material
The following bundled open source plugins make (heavy) use of DOM:
- [Android](http://git.jetbrains.org/?p=idea/android.git;a=tree;f=android;;hb=HEAD)
- [Android](https://github.com/JetBrains/android)
- [Ant](upsource:///plugins/ant)
- [Plugin DevKit](upsource:///plugins/devkit)
- [Plugin DevKit](upsource:///plugins/devkit/devkit-core)
- [Maven](upsource:///plugins/maven)
- [Struts 2](https://github.com/JetBrains/intellij-plugins/tree/master/struts2) (Ultimate Edition)

View File

@ -2,6 +2,8 @@
title: IntelliJ Platform Artifacts Repositories
---
> **WARNING** When using additional repositories, make sure to use HTTPS always.
JetBrains maintains public repositories that host artifacts related to the IntelliJ Platform, such as binaries and source code. These
repositories make artifacts more accessible for plugin developers.
@ -11,7 +13,7 @@ The IntelliJ Platform artifacts repositories are:
Both the Releases and Snapshots repositories have two types of content:
* Binary and source code artifacts for cross-platform, ZIP distributions of IntelliJ Platform-based IDEs, such as IntelliJ IDEA, CLion, Rider, and MPS.
These artifacts are not intended to be accessed directly from a plugin project's `build.gradle` file.
These artifacts are _not intended_ to be accessed directly from a plugin project's `build.gradle` file.
The `gradle-intellij-plugin` will access them as-needed for a plugin project.
* Artifacts for individual modules from the IntelliJ Platform.
These may be downloaded, or accessed directly from a `build.gradle` file, as explained below.
@ -29,17 +31,17 @@ To setup dependencies on a module there are two types of information needed:
### Specify the Repository URL
The URL for the desired artifact needs to be added to a Maven or Gradle script:
* For release or EAP versions, use https://www.jetbrains.com/intellij-repository/releases
* For EAP candidate snapshots, use https://www.jetbrains.com/intellij-repository/snapshots
* For dependencies on individual modules from the IntelliJ Platform, also use https://jetbrains.bintray.com/intellij-third-party-dependencies
* For release or EAP versions, use `https://www.jetbrains.com/intellij-repository/releases`
* For EAP candidate snapshots, use `https://www.jetbrains.com/intellij-repository/snapshots`
* For dependencies on individual modules from the IntelliJ Platform, also use `https://jetbrains.bintray.com/intellij-third-party-dependencies`
### Specify the Artifact
Describing a desired IntelliJ Platform module artifact is done with Maven coordinates.
For example, to specify the `jps-model-serialization` module:
* groupId = com.jetbrains.intellij.platform
* artifactId = jps-model-serialization
* classifier = ""
* packaging = jar
* _groupId_ = `com.jetbrains.intellij.platform`
* _artifactId_ = `jps-model-serialization`
* _classifier_ = `""`
* _packaging_ = `jar`
For each artifact [at the Repository URLs](#specify-the-repository-url) there are multiple versions available. The version can be specified in one of several ways:
* A branch build is specified as _BRANCH.BUILD[.FIX]_. For example, a branch build such as `141.233`, or a branch build with a fix such as `139.555.1`

View File

@ -82,13 +82,13 @@ The `editorScheme` section will be addressed in [Adding a Custom Editor Scheme](
The `ui` section will be addressed in [Customizing UI Control Colors](themes_customize.md#customizing-ui-controls).
The Wizard also creates a `themeProvider` declaration in the `<extensions>` section of the plugin's `plugin.xml` file.
This declaration binds the Theme description file to a theme provider extension `id`.
This declaration binds the Theme description file to a theme provider extension using a generated unique `id`.
```xml
<extensions defaultExtensionNs="com.intellij">
<themeProvider id="eb9b7461-397b-4b98-a422-224fc0a74564" path="/theme_basics.theme.json"/>
</extensions>
```
> **WARNING** Do not change the value of the `themeProvider` `id` attribute.
> **WARNING** Do not modify or re-use an existing value of the generated `id` attribute.
At this point, the UI Theme `theme_basics` is a valid UI Theme.
Its plugin can be built and tested in IntelliJ Platform-based IDEs, giving the user the opportunity to select _theme_basics_ in the [Theme](https://www.jetbrains.com/help/idea/settings-appearance.html) _Preferences_ dropdown.

View File

@ -61,6 +61,8 @@ The following minimal sample demonstrates all details required when exposing UI
> **TIP** It is highly recommended to always provide a `description` entry, so Theme authors can understand usages.
> **TIP** Do not remove existing keys, but deprecate them instead to help Theme authors upgrade their existing themes.
Color keys can be used via `JBColor#namedColor` providing defaults for Light and Dark theme:
```java
private static final Color SECTION_HEADER_FOREGROUND =

View File

@ -2,21 +2,13 @@
title: Building plugins with Gradle
---
The [gradle-intellij-plugin](https://github.com/JetBrains/gradle-intellij-plugin) Gradle plugin is the recommended
solution for building IntelliJ plugins. The plugin takes care of the dependencies of your plugin project - both the
base IDE and other plugin dependencies.
It also provides tasks to run the IDE with your plugin and to publish your plugin to the [JetBrains plugins repository](/plugin_repository/index.md). To make sure that your plugin is not affected by [API changes](/reference_guide/api_changes_list.md)
which may happen between major releases of the platform, you can easily build your plugin against many versions
of the base IDE.
> **WARNING** When adding additional repositories to your Gradle build script, make sure to always use HTTPS protocol.
> **Note** Please make sure to always upgrade to the latest version of `gradle-intellij-plugin`.
Follow releases on [GitHub](https://github.com/JetBrains/gradle-intellij-plugin/releases).
The [gradle-intellij-plugin](https://github.com/JetBrains/gradle-intellij-plugin) Gradle plugin is the recommended solution for building IntelliJ plugins.
The plugin takes care of the dependencies of your plugin project - both the base IDE and the other plugins that your plugin may depend on.
It also provides tasks to run the IDE with your plugin and to publish your plugin to the [JetBrains plugins repository](/plugin_repository/index.md).
To make sure that your plugin is not affected by [API changes](/reference_guide/api_changes_list.md) which may happen between major releases of the platform, you can easily build your plugin against many versions of the base IDE.
The following tutorial refers to materials that can be found in the included [gradle_plugin_demo](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/gradle_plugin_demo) project.
Below are a series of guides to developing and deploying Gradle-based IntelliJ Platform Plugins:
* [1. Getting Started with Gradle-Based Plugins](build_system/prerequisites.md)
* [2. Configuring Gradle-Based Plugins](build_system/gradle_guide.md)
* [3. Deploying a Plugin with Gradle](build_system/deployment.md)
Below are a series of guides to configuring Gradle support.
* [1. Getting Started](build_system/prerequisites.md)
* [2. Deploying a plugin](build_system/deployment.md)

View File

@ -2,10 +2,9 @@
title: Publishing Plugins with Gradle
---
Once you have configured Gradle support, you can automatically build and deploy your plugin to the [JetBrains Plugin Repository](https://plugins.jetbrains.com). To do so, you
will need to have already published the plugin to the plugin repository. For detailed information, please see the guide to [publishing a plugin](../../basics/getting_started/publishing_plugin.md).
> **WARNING** When adding additional repositories to your Gradle build script, make sure to always use HTTPS protocol.
Once you have configured Gradle support, you can automatically build and deploy your plugin to the [JetBrains Plugin Repository](https://plugins.jetbrains.com).
To do so, you will need to have already published the plugin to the plugin repository.
For detailed information, please see the guide to [publishing a plugin](../../basics/getting_started/publishing_plugin.md).
### 2.0 Add your account credentials
@ -13,7 +12,8 @@ In order to deploy a plugin to the plugin repository, you will first need to sup
We will describe three options to do so: using only the Gradle properties, using environment variables and using arguments to the Gradle task.
#### Using the Gradle properties file
You can store the credentials in the [Gradle properties](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties). It is crucial that you do not check these credentials into source control.
You can store the credentials in the [Gradle properties](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties).
It is crucial that you do not check these credentials into source control.
To do this, place the following information inside a file called `gradle.properties` under your project's root directory, or inside `GRADLE_HOME/gradle.properties`.
@ -31,7 +31,8 @@ publishPlugin {
}
```
If you place a `gradle.properties` file in your project's root directory, please ensure that this file is ignored by your version control tool. For example in Git, you can add the following line to your `.gitignore` file:
If you place a `gradle.properties` file in your project's root directory, please ensure that this file is ignored by your version control tool.
For example in Git, you can add the following line to your `.gitignore` file:
```
gradle.properties
@ -55,7 +56,9 @@ Note that also in this case you still need to put some default values in your Gr
### 2.1 Configure your plugin
The gradle-intellij-plugin provides a number of [configuration options](https://github.com/JetBrains/gradle-intellij-plugin#configuration) for customizing how Gradle builds your plugin. One of the most important is the `version`. By default, if you modify the `version` in your build script, the Gradle plugin will automatically update the `<version>` in your `plugin.xml` file.
The gradle-intellij-plugin provides a number of [configuration options](https://github.com/JetBrains/gradle-intellij-plugin#configuration) for customizing how Gradle builds your plugin.
One of the most important is the `version`.
By default, if you modify the `version` in your build script, the Gradle plugin will automatically update the `<version>` in your `plugin.xml` file.
The Gradle plugin will also update the `<idea-version since-build=.../>` values within the `plugin.xml` file to match the `intellij.version`, valid until the last release in the current major version, however you can disable this feature by setting the `intellij.updateSinceUntilBuild` option to `false`.
@ -63,7 +66,7 @@ The gradle-intellij-plugin provides a number of [configuration options](https://
plugins {
// Make sure to check for the latest version at https://plugins.gradle.org/plugin/org.jetbrains.intellij
// You can also subscribe to releases at https://github.com/JetBrains/gradle-intellij-plugin/releases
id 'org.jetbrains.intellij' version '0.4.7'
id 'org.jetbrains.intellij' version '0.4.9'
}
intellij {
@ -76,19 +79,23 @@ group 'com.jetbrains'
version '1.2' // Update me!
```
When you run `gradle runIde` with a build script containing the above snippet, Gradle will download the appropriate version of IntelliJ IDEA from either a [Snapshot](https://www.jetbrains.com/intellij-repository/snapshots) (time-based) or [Release](https://www.jetbrains.com/intellij-repository/releases) (version based) repository, configure the plugin sandbox, install your plugin, and launch a new instance of the IDE. This task can be run directly from the command line, without any prior tooling assistance.
When you run `gradle runIde` with a build script containing the above snippet, Gradle will download the appropriate version of IntelliJ IDEA from either a [Snapshot](https://www.jetbrains.com/intellij-repository/snapshots) (time-based) or [Release](https://www.jetbrains.com/intellij-repository/releases) (version based) repository, configure the plugin sandbox, install your plugin, and launch a new instance of the IDE.
This task can be run directly from the command line, without any prior tooling assistance.
### 2.3 Deploy your plugin
The first step when deploying a plugin is to confirm that it works correctly. You may wish to verify this by [installing your plugin from disk](https://www.jetbrains.com/help/idea/managing-plugins.html) on a fresh instance of your target IDE(s). Once you are confident the plugin works as intended, make sure the plugin version is updated, as the JetBrains Plugin repository will not accept multiple artifacts with the same version. To deploy a new version of your plugin to the JetBrains plugin repository, execute the following Gradle command:
The first step when deploying a plugin is to confirm that it works correctly.
You may wish to verify this by [installing your plugin from disk](https://www.jetbrains.com/help/idea/managing-plugins.html) on a fresh instance of your target IDE(s). Once you are confident the plugin works as intended, make sure the plugin version is updated, as the JetBrains Plugin repository will not accept multiple artifacts with the same version. To deploy a new version of your plugin to the JetBrains plugin repository, execute the following Gradle command:
```bash
gradle publishPlugin
```
Now check that the most recent version of your plugin appears on the [Plugin Repository](https://plugins.jetbrains.com/). If successfully deployed, any users who currently have your plugin installed on an eligible version of the IntelliJ Platform will be notified of a new update available on the following restart.
Now check that the most recent version of your plugin appears on the [Plugin Repository](https://plugins.jetbrains.com/).
If successfully deployed, any users who currently have your plugin installed on an eligible version of the IntelliJ Platform will be notified of a new update available on the following restart.
You may also deploy plugins to a release channel of your choosing, by configuring the `publishPlugin.channels` property. For example:
You may also deploy plugins to a release channel of your choosing, by configuring the `publishPlugin.channels` property.
For example:
```groovy
publishPlugin {
@ -96,7 +103,12 @@ publishPlugin {
}
```
When empty, this will use the default plugin repository, available to all [JetBrains plugin repository](https://plugins.jetbrains.com/) users. However, you can publish to an arbitrarily-named channel. These non-default release channels are treated as separate repositories for all intents and purposes. When using a non-default release channel, users will need to add a new [custom plugin repository](https://www.jetbrains.com/help/idea/managing-plugins.html#repos) to install your plugin. For example, if you specify `publishPlugin.channels 'canary'`, then users will need to add the `https://plugins.jetbrains.com/plugins/canary/list` repository to install the plugin and receive updates. Popular channel names include:
When empty, this will use the default plugin repository, available to all [JetBrains plugin repository](https://plugins.jetbrains.com/) users.
However, you can publish to an arbitrarily-named channel.
These non-default release channels are treated as separate repositories for all intents and purposes.
When using a non-default release channel, users will need to add a new [custom plugin repository](https://www.jetbrains.com/help/idea/managing-plugins.html#repos) to install your plugin.
For example, if you specify `publishPlugin.channels 'canary'`, then users will need to add the `https://plugins.jetbrains.com/plugins/canary/list` repository to install the plugin and receive updates.
Popular channel names include:
* `alpha`: https://plugins.jetbrains.com/plugins/alpha/list
* `beta`: https://plugins.jetbrains.com/plugins/beta/list

View File

@ -1,159 +0,0 @@
---
title: Configuring Gradle for IntelliJ Platform Plugins
---
This page serves as a guide to Gradle-based plugin configuration for _IntelliJ Platform_ projects.
The IntelliJ IDEA Ultimate and Community editions bundle the Gradle and Plugin DevKit plugins to support Gradle-based development.
The [Getting Started with Gradle](prerequisites.md) page provides a tutorial for creating Gradle-based IntelliJ Platform plugins.
It may be useful to review the IntelliJ Platform page, particularly the description of versioning in the [Open Source](/intro/intellij_platform.md#open-source) section.
> **WARNING** When adding additional repositories to your Gradle build script, make sure to always use HTTPS protocol.
* bullet list
{:toc}
## Overview of the IntelliJ IDEA Gradle Plugin
The IntelliJ IDEA Gradle plugin is built from the open-source project `gradle-intellij-plugin`.
The plugin adds Gradle tasks for the `build.gradle` file that enable developing IntelliJ Platform plugins.
The [README](https://github.com/JetBrains/gradle-intellij-plugin/blob/master/README.md) file for the `gradle-intellij-plugin` project is the reference for configuring these tasks.
When getting started, there are several items to note on the README page:
* At the top of the page, the [latest production version](https://github.com/jetbrains/gradle-intellij-plugin#the-latest-version) of the IntelliJ IDEA Gradle plugin is listed.
* Also at the top is the minimum version of Gradle required to support the IntelliJ IDEA Gradle plugin.
* The table of extended Gradle [Tasks](https://github.com/jetbrains/gradle-intellij-plugin#tasks) has a succinct description for each task added by the plugin.
This documentation will focus on the configuration and use four of those tasks:
* [Setup DSL](https://github.com/jetbrains/gradle-intellij-plugin#setup-dsl) - `intellij { ... }`.
* [Running DSL](https://github.com/jetbrains/gradle-intellij-plugin#running-dsl) - `runIde { ... }`
* [Patching DSL](https://github.com/jetbrains/gradle-intellij-plugin#patching-dsl) - `patchPluginXml { ... }`
* [Publishing DSL](https://github.com/jetbrains/gradle-intellij-plugin#publishing-dsl) - `publishPlugin { ... }`
* Examples are always a helpful resource, and at the bottom of the page are links to [example](https://github.com/jetbrains/gradle-intellij-plugin#examples) open source IntelliJ Platform plugin projects based on Gradle.
* Almost every Gradle plugin attribute has a default value that will work to get started on a Gradle-based IntelliJ Platform plugin project.
## Guide to Configuring Gradle Plugin Functionality
This section presents a guided tour of Gradle plugin attributes to achieve commonly desired functionality.
### Configuring the Gradle Plugin for Building IntelliJ Platform Plugin Projects
By default, the Gradle plugin will build a plugin project against the IntelliJ Platform defined by the latest EAP snapshot of the IntelliJ IDEA Community Edition.
If a matching version of the specified IntelliJ Platform is not available on the local machine, the Gradle plugin downloads the correct version and type.
IntelliJ IDEA then indexes the build and any associated source code and JetBrains Java Runtime.
#### IntelliJ Platform Configuration
Explicitly setting the [Setup DSL](https://github.com/jetbrains/gradle-intellij-plugin#setup-dsl) attributes `intellij.version` and `intellij.type` tells the Gradle plugin to use that configuration of the IntelliJ Platform to build the plugin project.
If a local installation of IntelliJ IDEA is the desired type and version of the IntelliJ Platform, use `intellij.localPath` to point to that installation.
If the `intellij.localPath` attribute is set, do not set the `intellij.version` and `intellij.type` attributes as this could result in undefined behavior.
#### Plugin Dependencies
IntelliJ Platform plugin projects may depend on either bundled or third-party plugins.
In that case, a project should build against a version of those plugins that match the IntelliJ Platform version used to build the plugin project.
The Gradle plugin will fetch any plugins in the list defined by `intellij.plugins`.
See the Gradle plugin [README](https://github.com/jetbrains/gradle-intellij-plugin#setup-dsl) for information about specifying the plugin and version.
Note that this attribute describes a dependency so the Gradle plugin can fetch the required artifacts.
The IntelliJ Platform plugin project is still required to declare these dependencies in its [Plugin Configuration](/basics/plugin_structure/plugin_configuration_file.md) (`plugin.xml`) file.
### Configuring the Gradle Plugin for Running IntelliJ Platform Plugin Projects
By default, the Gradle plugin will use the same version of the IntelliJ Platform for the IDE Development Instance as was used for building the plugin.
Using the corresponding JetBrains Runtime is also the default, so for this use case no further configuration is required.
#### Running Against Alternate Versions and Types of IntelliJ Platform-Based IDEs
The IntelliJ Platform IDE used for the Development Instance can be different from that used to build the plugin project.
Setting the [Running DSL](https://github.com/jetbrains/gradle-intellij-plugin#running-dsl) attribute `runIde.ideaDirectory` will define an IDE to be used for the Development Instance in that single `runIde` task.
This attribute is commonly used when running or debugging a plugin in an [alternate IntelliJ Platform-based IDE](/intro/intellij_platform.md#ides-based-on-the-intellij-platform).
#### Running Against Alternate Versions of the JetBrains Runtime
Every version of the IntelliJ Platform has a corresponding version of the [JetBrains Runtime](/basics/ide_development_instance.md#using-a-jetbrains-runtime-for-the-development-instance).
A different version of the runtime can be used by specifying the `runIde.jbrVersion` attribute, describing a version of the JetBrains Runtime that should be used by the IDE Development Instance.
The Gradle plugin will fetch the specified JetBrains Runtime as needed.
### Managing Directories used by the Gradle Plugin
There are several attributes to control where the Gradle plugin places directories for downloads and for use by the IDE Development Instance.
The location of the [sandbox home](/basics/ide_development_instance.md#sandbox-home-location-for-gradle-based-plugin-projects) directory and its subdirectories can be controlled with Gradle plugin attributes.
The `intellij.sandboxDirectory` attribute is used to set the path for the sandbox directory to be used while running the plugin in an IDE Development Instance.
Locations of the sandbox [subdirectories](/basics/ide_development_instance.md#development-instance-settings-caches-logs-and-plugins) can be controlled using the `runIde.configDirectory`, `runIde.pluginsDirectory`, and `runIde.systemDirectory` attributes.
If the `intellij.sandboxDirectory` path is explicitly set, the subdirectory attributes default to the new sandbox directory.
The storage location of downloaded IDE versions and components defaults to the Gradle cache directory.
However, it can be controlled by setting the `intellij.ideaDependencyCachePath` attribute.
### Controlling Downloads by the Gradle Plugin
As mentioned in the section about [configuring the intellij platform](#configuring-the-gradle-plugin-for-building-intellij-platform-plugin-projects) used for building plugin projects, the Gradle plugin will fetch the version of the IntelliJ Platform specified by the default or by the `intellij` attributes.
Standardizing the versions of the Gradle plugin and Gradle system across projects will minimize the time spent downloading versions.
There are controls for managing the IntelliJ IDEA Gradle plugin version, and the version of Gradle itself.
The Gradle plugin version is defined in the `plugins {}` section of a project's `build.gradle` file.
The Gradle version is in defined in a project's `gradle-wrapper.properties`.
### Patching the Plugin Configuration File
A plugin project's `plugin.xml` file has element values that are "patched" at build time from the attributes of the `patchPluginXml` ([Patching DSL](https://github.com/jetbrains/gradle-intellij-plugin#patching-dsl)) task.
As many as possible of the attributes in the Patching DSL will be substituted into the corresponding element values in a plugin project's `plugin.xml` file:
* If a `patchPluginXml` attribute default value is defined, the attribute value will be patched in plugin.xml _regardless of whether the `patchPluginXml` task appears in the `build.gradle` file_.
* For example, the default values for the attributes `patchPluginXml.sinceBuild` and `patchPluginXml.untilBuild` are defined based on the declared (or default) value of `intellij.version`.
So by default `patchPluginXml.sinceBuild` and `patchPluginXml.untilBuild` are substituted into the `<idea-version>` element's `since-build` and `until-build` attributes in the `plugin.xml` file.
* If a `patchPluginXml` attribute value is explicitly defined, the attribute value will be substituted in `plugin.xml`.
* If both `patchPluginXml.sinceBuild` and `patchPluginXml.untilBuild` attributes are explicitly set, both are substituted in `plugin.xml`.
* If one attribute is explicitly set (e.g. `patchPluginXml.sinceBuild`) and one is not (e.g. `patchPluginXml.untilBuild` has default value,) both attributes are patched at their respective (explicit and default) values.
A best practice to avoid confusion is to replace the elements in `plugin.xml` that will be patched by the Gradle plugin with a comment.
That way the values for these parameters do not appear in two places in the source code.
The Gradle plugin will add the necessary elements as part of the patching process.
For those `patchPluginXml` attributes that contain descriptions such as `changeNotes` and `pluginDescription`, a `CDATA` block is not necessary when using HTML elements.
As discussed in [Components of a Wizard-Generated Gradle IntelliJ Platform Plugin](prerequisites.md#components-of-a-wizard-generated-gradle-intellij-platform-plugin), the Gradle properties `project.version`, `project.group`, and `rootProject.name` are all generated based on the input to the Wizard.
However, the IntelliJ IDEA Gradle plugin does not combine and substitute those Gradle properties for the default `<id>` and `<name>` elements in the `plugin.xml` file.
### Publishing with the Gradle Plugin
Please review the [Publishing Plugins with Gradle](deployment.md) page before using the [Publishing DSL](https://github.com/jetbrains/gradle-intellij-plugin#publishing-dsl) attributes.
That documentation explains three different ways to use Gradle for plugin uploads without exposing account credentials.
## Common Gradle Plugin Configurations for Development
Different combinations of Gradle plugin attributes are needed to create the desired build or IDE Development Instance environment.
This section reviews some of the more common configurations.
### Plugins Targeting IntelliJ IDEA
IntelliJ Platform plugins targeting IntelliJ IDEA have the most straightforward Gradle plugin configuration.
* Determine the version of [IntelliJ IDEA to use for building the plugin project](#configuring-the-gradle-plugin-for-building-intellij-platform-plugin-projects); this is the desired version of the IntelliJ Platform.
This can be EAP (default) or determined from the [build number ranges](/basics/getting_started/build_number_ranges.md).
* If a production version of IntelliJ IDEA is the desired target, set the `intellij` [version attributes](#intellij-platform-configuration) accordingly.
* Set the necessary [plugin dependencies](#plugin-dependencies), if any.
* If the plugin project should be run or debugged in an IDE Development Instance based on the same IntelliJ IDEA version, no further attributes need to be set for the IDE Development Instance.
This is the default behavior and is the most common use case.
* If the plugin project should be run or debugged in an IDE Development Instance based on a different version or type of IntelliJ IDEA, set the [Running or Setup](#running-against-alternate-versions-and-types-of-intellij-platform-based-ides) DSL attributes accordingly.
For projects with only one `runIde` task, use the Running DSL attribute `runIde.ideaDirectory`.
* If the plugin project should be run using a JetBrains Runtime other than the default for the IDE Development Instance, specify the [JetBrains Runtime version](#running-against-alternate-versions-of-the-jetbrains-runtime).
* Set the appropriate attributes for [patching the `plugin.xml` file](#patching-the-plugin-configuration-file).
### Plugins Targeting Alternate IntelliJ Platform-Based IDEs
The Gradle plugin can also be configured for developing plugins to run in IDEs that are based on the IntelliJ Platform but are not IntelliJ IDEA.
This example focuses on the details of developing a plugin for PhpStorm.
It will be helpful to review the [PhpStorm Plugin Development](/products/phpstorm/phpstorm.md) section.
* The Gradle plugin attributes describing the configuration of the [IntelliJ Platform used to build the plugin project](#configuring-the-gradle-plugin-for-building-intellij-platform-plugin-projects) must be explicitly set.
The type will be "IC" because the IntelliJ Platform is defined by the IntelliJ IDEA Community Edition.
The BRANCH.BUILD number of the IntelliJ Platform (IntelliJ IDEA CE) is the same as for the PhpStorm target.
Although the FIX (tertiary) number may differ between the same versions of the applications, it won't affect the match of the IntelliJ Platform.
* All PhpStorm plugin projects have a dependency on the PhpStorm OpenAPI Library.
Any plugin targeting PhpStorm must list a dependency on the PHP plugin, and its version must be compatible with the target version of PhpStorm.
The plugin dependency must be declared using the Gradle plugin `intellij.plugins` attribute, which lists the `id` and `version` of the plugin dependency.
* The best practice is to use the target version of PhpStorm as the IDE Development Instance.
That enables running and debugging the plugin in the target (e.g., PhpStorm) application.
The choice of application to use for the IDE Development Instance is configured using the Gradle plugin attribute `intellij.alternativeIdePath`.
The snippet below is an example of configuring the Setup and Running DSLs in a `build.gradle` file to develop a plugin targeted at PhpStorm.
The configuration uses IntelliJ IDEA Community Edition v2019.1.2 (build 191.7141.44) as the IntelliJ Platform against which the plugin project is built.
It uses PhpStorm v2019.1.2 (build 191.7141.52) as the IDE Development Instance in which the plugin project is run and debugged.
```groovy
intellij {
// Define IntelliJ Platform against which to build the plugin project.
version '191.7141.44' // Same version (2019.1.2) as target PhpStorm
type 'IC' // Use IntelliJ IDEA CE as basis of IntelliJ Platform
// Require the Php plugin, must be compatible with target v2019.1.2
plugins 'com.jetbrains.php:191.6707.66'
}
runIde {
// Path to installed v2019.1.2 PhpStorm to use as IDE Development Instance
ideaDirectory '/Applications/apps/PhpStorm/ch-0/191.7141.52/PhpStorm.app/Contents'
}
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

View File

@ -1,17 +1,22 @@
---
title: Getting Started with Gradle
---
<!--
// TODO:
1. Alexander's comments when available.
-->
Gradle is the preferred solution for creating IntelliJ Platform plugins.
The IntelliJ IDEA Ultimate and Community editions bundle the necessary plugins to support Gradle-based development.
These IntelliJ IDEA plugins are _Gradle_ and _Plugin DevKit_, which are enabled by default.
To verify these plugins are installed and enabled, see the help section about [Managing Plugins](https://www.jetbrains.com/help/idea/managing-plugins.html).
> **WARNING** When adding additional repositories to your Gradle build script, make sure to always use HTTPS protocol.
* bullet list
{:toc}
> **WARNING** When adding additional repositories to your Gradle build script, make sure to use HTTPS always.
## Creating a Gradle-Based IntelliJ Platform Plugin with New Project Wizard
IntelliJ IDEA supports creating new Gradle-based IntelliJ Platform plugin projects using the [New Project Wizard](https://www.jetbrains.com/help/idea/gradle.html#project_create_gradle).
The Wizard creates all the necessary project files based on a few template inputs.
@ -34,12 +39,12 @@ On the first screen, the type of project is configured:
### Project Naming Screen
On this, the second screen of the Wizard, specify a [Group ID, Artifact ID, and plugin Version](https://www.jetbrains.com/help/idea/gradle.html#project_create_gradle) using [Maven naming](https://maven.apache.org/guides/mini/guide-naming-conventions.html) conventions.
* _Group ID_ is typically a Java package name, and it is used for the Gradle property `project.group` value in the project's `build.gradle` file.
* _Group ID_ is typically a Java package name, and it is used for the `project.group` value in the project's `build.gradle` file.
For this example, enter "com.your.company".
* _Artifact ID_ is the default name of the project JAR file (without version).
It is also used for the Gradle property `rootProject.name` value in the project's `settings.gradle` file.
It is also used for the `rootProject.name` value in the project's `settings.gradle` file.
For this example, enter "my_gradle_plugin".
* _Version_ is used for the Gradle property `project.version` value in the `build.gradle` file.
* _Version_ is used for the `project.version` value in the `build.gradle` file.
For this example, enter "1.0".
Click _Next_ to continue.
@ -130,13 +135,6 @@ The New Project Wizard produces the `my_gradle_plugin` project `build.gradle` fi
}
```
#### Plugin Gradle Properties and Plugin Configuration File Elements
The Gradle properties `rootProject.name` and `project.group` will not, in general, match the respective `plugin.xml` elements `<name>` and `<id>`.
There is no IntelliJ Platform-related reason they should as they serve different functions.
The `<name>` element is often similar to the content root, but is more explanatory than the `rootProject.name`.
The `<id>` is a unique identifier over all plugins, typically a concatenation of the Maven `groupId` and `artifactId`; the default Gradle `project.group` property is only the `groupId`.
## Adding Gradle Support to an Existing DevKit-Based IntelliJ Platform Plugin
Converting a DevKit-based plugin project to a Gradle-based plugin project can be done using the New Project Wizard to create a Gradle-based project around the existing DevKit-based project:
* Ensure the directory containing the DevKit-based IntelliJ Platform plugin project can be fully recovered if necessary.
@ -150,13 +148,14 @@ Converting a DevKit-based plugin project to a Gradle-based plugin project can be
* GroupID to the existing package in the initial source set.
* ArtifactID to the name of the existing plugin.
* Version to the same as the existing plugin.
* On the [Project Name and Location Screen](#project-name-and-location-screen) set the values to:
* On the [Project Name and Location Screen](#project-project-name-and-location-screen) set the values to:
* _Project name_ to the name of the existing plugin.
(It should be pre-filled from the _ArtifactID_)
* Set the _Project location_ to the directory of the existing plugin.
* Click _Finish_ to create the new Gradle-based plugin.
* [Add more modules](https://www.jetbrains.com/help/idea/gradle.html#gradle_add_module) using Gradle [_Source Sets_](https://www.jetbrains.com/help/idea/gradle.html#gradle_source_sets) as needed.
## Running a Simple Gradle-Based IntelliJ Platform Plugin
Before running [`my_gradle_project`](#components-of-a-wizard-generated-gradle-intellij-platform-plugin), some code needs to be added to provide simple functionality.
* Using the code below, add a `HelloAction.java` class to the `src/main/java/` folder.
@ -198,3 +197,17 @@ Before running [`my_gradle_project`](#components-of-a-wizard-generated-gradle-in
See the IntelliJ IDEA help for more information about [Working with Gradle tasks](https://www.jetbrains.com/help/idea/gradle.html#96bba6c3).
Finally, when `my_gradle_plugin` launches in the IDE development instance, there should be a new **Greeting** main menu to the right of the **Help** menu.
## Configuring a Gradle-Based IntelliJ Platform Plugin Project
See the [Gradle plugin README](https://github.com/JetBrains/gradle-intellij-plugin/blob/master/README.md#gradle) for more information about configuring IntelliJ Platform Plugin Projects.
> **Note** Please make sure to always upgrade to the latest version of `gradle-intellij-plugin`.
Follow releases on [GitHub](https://github.com/JetBrains/gradle-intellij-plugin/releases).
For example, to configure the **Sandbox Home** directory's location include the following in the project's `build.gradle` file:
```groovy
intellij {
sandboxDirectory = "$project.buildDir/myCustom-sandbox"
}
```
See the [IDE Development Instances](/basics/ide_development_instance.md) page for more information about default Sandbox Home directory locations and contents.

View File

@ -2,71 +2,188 @@
title: Code Inspections
---
This topic describes the [comparing_references_inspection](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/comparing_references_inspection), a sample plugin that creates a custom [inspection](https://www.jetbrains.com/idea/webhelp/code-inspection.html) for Java code. In addition, the sample plugin contains a JUnit-based test.
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.
Examples of the plugin approach are the IntelliJ Platform SDK code samples [inspection](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/inspection) and [comparing_references_inspection](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/comparing_references_inspection).
In addition, the comparing_references_inspection code sample demonstrates implementing a unit test.
## About Code Inspections
You can also create custom inspections through the IntelliJ IDEA user interface.
See [Code Inspection](https://www.jetbrains.com/idea/webhelp/code-inspection.html) and [Creating Custom Inspections](https://www.jetbrains.com/idea/help/creating-custom-inspections.html) for more information.
The **IntelliJ Platform** provides tools designed for static code analysis (so called _code inspections_) that help you maintain and clean up your code without actually executing it. For more information, refer to [Code Inspection](https://www.jetbrains.com/idea/webhelp/code-inspection.html) in the **IntelliJ IDEA** Web Help. In **IntelliJ IDEA** you will find a set of built-in inspections that are grouped by their goals and sense.
## Creating an Inspection Plugin
You can create custom inspections through the **IntelliJ IDEA** interface (see [Creating Custom Inspections](https://www.jetbrains.com/idea/help/creating-custom-inspections.html)). Alternatively, you can develop a plugin to implement a custom inspection.
The [comparing_references_inspection](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/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.
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.
* Creating a [visitor](#visitor-implementation-class) to traverse the `PsiTree` 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 `PsiTree` as needed.
Quick fixes are displayed to the user like [intentions](code_intentions.md).
* Implementing an [inspection preferences panel](#inspection-preferences-panel) to display information about the inspection.
* Writing an HTML [description](#inspection-description) of the inspection for display in the inspection preferences panel.
* Optionally, create a [unit test](#inspection-unit-test) for the plugin.
## Techniques Used
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.
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`.
* 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 Java implementation file where it 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 Java implementation file.
The [comparing_references_inspection](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/comparing_references_inspection) sample plugin illustrates the use of the following techniques:
## Creating an Inspection
The [comparing_references_inspection](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/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)`.
The details of the `comparing_references_inspection` implementation illustrate the components of an inspection plugin.
- How to analyze a [PSI tree](/basics/architectural_overview/psi_files.md).
- How to find a Java token of interest in the PSI tree.
- How to inspect Java code in the **IntelliJ IDEA** editor using the [BaseJavaLocalInspectionTool](upsource:///java/java-analysis-api/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java) class.
- How to create a JUnit test for this plugin using the [IdeaTestFixtureFactory](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/IdeaTestFixtureFactory.java) class.
### Plugin Configuration File
The `comparing_references_inspection` is described as a `<localInspection>` type within the `<extensions>` elements in the `comparing_references_inspection` plugin configuration ([plugin.xml](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/comparing_references_inspection/resources/META-INF/plugin.xml)) file.
Under the hood, inspection types are described as an `<extensionPoint>` in [LangExtensionPoints.xml](upsource:///platform/platform-resources/src/META-INF/LangExtensionPoints.xml):
* The `localInspection` type is used for inspections that operate on one file at a time, and also operate as the user edits the file.
* The `globalInspection` type is used for inspections that operate across multiple files, and the associated fix might, for example, refactor code between files.
* The `inspectionToolProvider` type is not deprecated but `localInspection` is preferred.
## Sample Plugin
The minimum inspection description must contain the `implementationClass` attribute.
As shown in the `comparing_references_inspection` plugin configuration file, other attributes can be defined in the `localInspection` element, either with or without localization.
In most cases, it is simplest to define the attributes in the plugin configuration file because the underlying parent classes handle most of the class responsibilities based on the configuration file description.
Note that some attributes are not displayed to the user, so they are never localized.
The **comparingReferences** sample plugin is available in the `<%IntelliJ SDK Docs project%>/code_samples/comparing_references_inspection` directory. When launched, this plugin adds the **'==' or '!=' instead of 'equals()'** item to the **Probable bugs** node in the [Inspections list](https://www.jetbrains.com/help/idea/inspections-settings.html).
As an alternative, inspections can define all of the attribute information (except `implementationClass`) by overriding methods in the inspection implementation class.
#### Running the Plugin
### Inspection Implementation Java Class
Inspection implementations for Java files, like [`ComparingReferencesInspection`](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/comparing_references_inspection/source/com/intellij/codeInspection/ComparingReferencesInspection.java), are often based on the Java class [AbstractBaseJavaLocalInspectionTool](upsource:///java/java-analysis-api/src/com/intellij/codeInspection/AbstractBaseJavaLocalInspectionTool.java).
The `AbstractBaseJavaLocalInspectionTool` implementation class offers methods to inspect Java classes, fields, and methods.
**To run the sample plugin**
More generally, `localInspection` types are based on the class [`LocalInspectionTool`](upsource:///platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java).
Examining the class hierarchy for `LocalInspectionTool` shows that the IntelliJ Platform provides many child inspection classes for a variety of languages and frameworks.
One of these classes is a good basis for a new inspection implementation, but a bespoke implementation can also be based directly on `LocalInspectionTool`.
1. Start **IntelliJ IDEA** and open the **comparingReferences** plugin project saved into the `<%IntelliJ SDK Docs project%>/code_samples/comparing_references_inspection` directory.
2. 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.
3. If necessary, modify the [Run/Debug Configurations](https://www.jetbrains.com/idea/webhelp/run-debug-configuration-plugin.html) and Run the plugin by choosing the **Run | Run** on the main menu.
The primary responsibilities of the inspection implementation class are to provide:
* A `PsiElementVisitor` object to traverse the `PsiTree` 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.
#### Configuring the Plugin
Note that if an inspection's description in the plugin configuration file defines only the implementation class, then the other attribute information has to be supplied by overriding methods in the Java implementation.
Once the plugin is launched, you can set the plugin options. You can specify the Java classes to be participated in the code inspection and the severity level of the found probable bugs.
The `ComparingReferencesInspection` class defines two `String` fields:
* `QUICK_FIX_NAME` defines the string users see when prompted to apply the quick fix.
* `CHECKED_CLASSES` holds a list of class names of interest to the inspection.
**To configure the sample plugin**
The overridden `ComparingReferencesInspection` methods are discussed in the sections below.
1. On the IDEA main menu, choose **File | Settings**, and then under **Project Settings**, click **Inspections**.
2. In the list of the IntelliJ IDEA inspections, expand the **Probable bugs** node, and then click **'==' or '!=' instead of 'equals()'**.
### Visitor Implementation Class
The visitor class evaluates whether elements of the file's `PsiTree` are of interest to an inspection.
The `ComparingReferencesInspection.createOptionsPanel()` method creates an anonymous visitor class based on [`JavaElementVisitor`](upsource:///java/java-psi-api/src/com/intellij/psi/JavaElementVisitor.java) to traverse the `PsiTree` of the Java file being edited, inspecting for suspect syntax.
The anonymous class overrides three methods in particular.
* `visitReferenceExpression()` to prevent any duplicate visitation of reference-type expressions.
* `visitBinaryExpression()`, which does all the heavy lifting.
It is called to evaluate a `PsiBinaryExpression`, and it checks to see if the operands are `==` or `!=`, and if the operands are classes relevant to this inspection.
* `isCheckedType()` evaluates the `PsiType` of the operands to determine if they are of interest to this inspection.
### Quick Fix Implementation
The quick fix class acts much like an intention, allowing the user to change the portion of `PsiTree` highlighted by the inspection.
A quick fix is invoked when the inspection highlights a `PsiElement` of interest and the user elects to make a change.
The `ComparingReferencesInspection` implementation uses the nested class `CriQuickFix` to implement a quick fix based on [`LocalQuickFix`](upsource:///platform/analysis-api/src/com/intellij/codeInspection/LocalQuickFix.java).
The `CriQuickFix` class gives a user the option to change the use of `a == b` and `a != b` expression to `a.equals(b)` and `!a.equals(b)` respectively.
The heavy lifting is done in `CriQuickFix.applyFix()`, which manipulates the `PsiTree` to convert the expressions.
The change to the `PsiTree` is accomplished by the usual approach to modification:
* Getting a `PsiElementFactory`.
* Creating a new `PsiMethodCallExpression`.
* Substituting the original left and right operands into the new `PsiMethodCallExpression`.
* Replacing the original binary expression with the `PsiMethodCallExpression`.
### Inspection Preferences Panel
The inspection preferences panel is used to display information about 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.
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.
### 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.
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 `<plugin root dir>/resources/inspectionDescriptions/`.
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.
If a short name is not provided by the plugin, the IntelliJ Platform computes one.
### Inspection Unit Test
The `comparing_references_inspection` code sample provides a unit test for the inspection.
See the [Testing Plugins](/basics/testing_plugins.md) section for general information about plugin testing.
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>/testSource/testPlugin/` contains the test source code and must be marked as a "Tests" folder.
If it is not, a DevKit project cannot find the source code.
By convention, the folder `<project root>/testData/` contains the test files and must be marked as a "Test Resources" folder.
The folder contains pairs of files for each test using the name convention `*.java` and `*.after.java`.
In the case of `comparing_references_inspection` the test files are `before.java` and `before.after.java`, and `before1.java` and `before1.after.java`.
The choice of `before` and `before1` is arbitrary.
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.
## Running the Comparing References Inspection Code Sample
The [comparing_references_inspection](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/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.
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-docs/tree/master/code_samples/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.
### 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 IDEA 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()'_.
![](img/comparingReferences_options.png)
3. Under **Options**, you can specify the following plugin settings:
- From the **Severity** list, select the severity level of probable bugs the plugin will find (such as Warning, Info, etc.)
- In the text box under **Severity**, specify the semicolon separated list of Java classes to be participated in this code inspection.
4. When finished, click **OK**.
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**.
#### How does it work?
### How does it work?
The plugin inspects your code opened in the **IntelliJ IDEA** editor or the code you are typing. 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()**:
The plugin inspects your code opened in the IntelliJ IDEA editor or the code you are typing.
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()`:
![](img/comparingReferences.png)
In this example, the **s1** and **s2** are variables of the String type. Clicking **Use equals()** replaces
In this example, the `str1` and `str2` are variables of the String type.
Clicking _SDK: Use equals()_ replaces:
```java
return (s1==s2);
return (str1==str2);
```
with the code:
```java
return (s1.equals(s2));
return (str1.equals(str2));
```
#### Testing the Plugin
The sample plugin contains the `TestThisPlugin` Java class in the `testSource/testPlugin` package and the test data in the `testData` directory. This test adds two test cases to this plugin project. To run test cases, run the `YourTest.test()` or `YourTest.test1()` method, respectively.
For detailed information about testing and all related procedures, refer to [Testing](https://www.jetbrains.com/help/idea/performing-tests.html) in the **IntelliJ IDEA** Web Help.

View File

@ -2,11 +2,14 @@
title: Code Intentions
---
This topic describes the [conditional_operator_intention](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/conditional_operator_intention), a sample plugin that adds a new [intention action](https://www.jetbrains.com/help/idea/intention-actions.html) to the IntelliJ Platform Intentions list. In addition, the sample plugin contains a JUnit-based test.
This topic describes the [conditional_operator_intention](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/conditional_operator_intention), a sample plugin that adds a new [intention action](https://www.jetbrains.com/help/idea/intention-actions.html) to the IntelliJ Platform Intentions list.
In addition, the sample plugin contains a JUnit-based test.
## About Intention Actions
The **IntelliJ Platform** analyzes your code and helps handle situations that may result in errors. When a possible problem is suspected, the IDE suggests an appropriate intention action, denoted with special icons. For more information, refer to [Intention Actions](https://www.jetbrains.com/help/idea/intention-actions.html) in the **IntelliJ IDEA** Web Help.
The **IntelliJ Platform** analyzes your code and helps handle situations that may result in errors.
When a possible problem is suspected, the IDE suggests an appropriate intention action, denoted with special icons.
For more information, refer to [Intention Actions](https://www.jetbrains.com/help/idea/intention-actions.html) in the **IntelliJ IDEA** Web Help.
You can view a list of all available intention actions using the [Intention List](https://www.jetbrains.com/help/idea/intention-actions.html#intention-settings) provided by the IDE.
@ -28,7 +31,8 @@ The [conditional_operator_intention](https://github.com/JetBrains/intellij-sdk-
## Sample Plugin
The **ConditionalOperatorConverter** sample plugin is available in the `<%IntelliJ SDK Docs project%>/code_samples/conditional_operator_intention` directory. When launched, this plugin adds the **Convert ternary operator if statement** item to the **Conditional Operator** node in the IDEA Intentions list:
The **ConditionalOperatorConverter** sample plugin is available in the `<%IntelliJ SDK Docs project%>/code_samples/conditional_operator_intention` directory.
When launched, this plugin adds the **Convert ternary operator if statement** item to the **Conditional Operator** node in the IDEA Intentions list:
![](img/IntentionsList.png)
@ -42,7 +46,8 @@ The **ConditionalOperatorConverter** sample plugin is available in the `<%Inte
#### How does it work?
The plugin analyzes symbols under the cursor in your code opened in the IDEA editor. If the cursor is positioned on the "?" conditional operator, **IntelliJ IDEA** proposes to replace this conditional (ternary) operator with the "if-then-else" statement:
The plugin analyzes symbols under the cursor in your code opened in the IDEA editor.
If the cursor is positioned on the "?" conditional operator, **IntelliJ IDEA** proposes to replace this conditional (ternary) operator with the "if-then-else" statement:
![](img/TernaryOperator.png)
@ -64,6 +69,7 @@ if ((n>=0)) {
##### Testing the Plugin
The sample plugin contains the `YourTest` Java class in the `testSource/testPlugin/` package and the test data in the `testData/` directory. To perform the plugin test, run the `YourTest.test()` method.
The sample plugin contains the `YourTest` Java class in the `testSource/testPlugin/` package and the test data in the `testData/` directory.
To perform the plugin test, run the `YourTest.test()` method.
For detailed information about testing and all related procedures, refer to [Testing](https://www.jetbrains.com/help/idea/performing-tests.html) in the **IntelliJ IDEA** Web Help.

View File

@ -35,7 +35,7 @@ public class SimpleAnnotator implements Annotator {
List<SimpleProperty> properties = SimpleUtil.findProperties(project, key);
if (properties.size() == 1) {
TextRange range = new TextRange(element.getTextRange().getStartOffset() + 7,
element.getTextRange().getStartOffset() + 7);
element.getTextRange().getEndOffset());
Annotation annotation = holder.createInfoAnnotation(range, null);
annotation.setTextAttributes(DefaultLanguageHighlighterColors.LINE_COMMENT);
} else if (properties.size() == 0) {

Some files were not shown because too many files have changed in this diff Show More