2016-01-14 19:38:06 -08:00

342 lines
33 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>10. Reference Contributor / IntelliJ Platform SDK DevGuide</title>
<link rel="stylesheet" href="/intellij/sdk/docs/app/css/styles.min.css">
<!-- non-retina iPad pre iOS 7 -->
<link rel="apple-touch-icon" href="/intellij/sdk/docs/apple-touch-icon-72x72.png" sizes="72x72">
<!-- retina iPhone pre iOS 7 -->
<link rel="apple-touch-icon" href="/intellij/sdk/docs/apple-touch-icon-114x114.png" sizes="114x114">
<!-- retina iPad pre iOS 7 -->
<link rel="apple-touch-icon" href="/intellij/sdk/docs/apple-touch-icon-144x144.png" sizes="144x144">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/intellij/sdk/docs/apple-touch-icon-precomposed.png">
<!-- normal favicon -->
<link rel="shortcut icon" type="image/x-icon" href="/intellij/sdk/docs/favicon.ico">
<link rel="icon" type="image/png" href="/intellij/sdk/docs/favicon.png">
<link rel="stylesheet" href="/intellij/sdk/docs/styles/styles.css"></head>
<body data-id="tutorials/custom_language_support/reference_contributor">
<div class="wrapper">
<section class="panel _nav">
<header class="panel__header">
<div class="container">
<form class="search-box">
<label for="search-box__input" class="search-box__label">
<input type="text" class="search-box__input" id="search-box__input" placeholder="Search IntelliJ Platform SDK DevGuide">
</label>
<div class="search-box__clear" title="Clear"></div>
</form>
</div>
</header>
<nav class="panel__content">
<div class="container _nav">
<menu class="nav-tree"></menu>
</div>
<div class="container _footer panel__footer">
<p><a href="https://youtrack.jetbrains.com/issues/IJSDK">Send feedback</a></p>
<p>&copy; 2000&ndash;2016 <a href="//www.jetbrains.com">JetBrains</a> s.r.o.<br>
All rights reserved.</p>
</div>
</nav>
</section>
<main class="panel _main" role="main">
<header class="panel__header">
<div class="container">
<h3>IntelliJ Platform SDK DevGuide</h3>
<div class="shortcuts-switcher"><label for="switch-shortcuts">Keymap:</label><select id="switch-shortcuts" class="select _shortcuts" height="1">
<option data-group="primary" value="default" selected>Default</option>
<option data-group="primary" value="default_for_gnome">GNOME</option>
<option data-group="primary" value="default_for_kde">KDE</option>
<option data-group="primary" value="default_for_xwin">XWindow</option>
<option data-group="primary" value="emacs">Emacs</option>
<option data-group="primary" value="jbuilder">JBuilder</option>
<option data-group="primary" value="visual_studio">Visual Studio</option>
<option data-group="primary" value="netbeans_6.5">NetBeans 6.5</option>
<option data-group="primary" value="eclipse">Eclipse</option>
<option data-group="secondary" value="mac_os_x_10.5_">OS X 10.5+</option>
<option data-group="secondary" value="mac_os_x">OS X</option>
<option data-group="secondary" value="eclipse_mac_os_x">OS X Eclipse</option></select>
</div>
<div class="panel-trigger"></div>
</div>
</header>
<section class="panel__content">
<div class="container">
<article class="article" data-shortcut-switcher="false">
<h1>10. Reference Contributor</h1>
<p>References is one of the most important and tricky parts in the implementation of a custom language support.
Resolving references means the ability to go from the usage of an element to the declaration of the element, completion, rename refactoring, find usages, etc.</p>
<p><strong>Every element which can be renamed or referenced needs to implement <em>com.intellij.psi.PsiNamedElement</em> interface.</strong></p>
<a name="define-a-base-named-element-class" class="elem-anchor"></a>
<h3>10.1. Define a base named element class<a href="#define-a-base-named-element-class" class="anchor-link"><span></span></a></h3>
<pre><code class="code-block__wrapper code-block _highlighted lang_java"><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">simpleplugin</span><span class="o">.</span><span class="na">psi</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.psi.PsiNameIdentifierOwner</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">SimpleNamedElement</span> <span class="kd">extends</span> <span class="n">PsiNameIdentifierOwner</span> <span class="o">{</span>
<span class="o">}</span>
</code></pre>
<pre><code class="code-block__wrapper code-block _highlighted lang_java"><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">simpleplugin</span><span class="o">.</span><span class="na">psi</span><span class="o">.</span><span class="na">impl</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.extapi.psi.ASTWrapperPsiElement</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.lang.ASTNode</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.simpleplugin.psi.SimpleNamedElement</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.jetbrains.annotations.NotNull</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">SimpleNamedElementImpl</span> <span class="kd">extends</span> <span class="n">ASTWrapperPsiElement</span> <span class="kd">implements</span> <span class="n">SimpleNamedElement</span> <span class="o">{</span>
<span class="kd">public</span> <span class="nf">SimpleNamedElementImpl</span><span class="o">(</span><span class="nd">@NotNull</span> <span class="n">ASTNode</span> <span class="n">node</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="n">node</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
<a name="define-helper-methods-for-generated-psi-elements" class="elem-anchor"></a>
<h3>10.2. Define helper methods for generated PSI elements<a href="#define-helper-methods-for-generated-psi-elements" class="anchor-link"><span></span></a></h3>
<p>Since we need to implement new methods in PSI class, we should define them in our utility.</p>
<pre><code class="code-block__wrapper code-block _highlighted lang_java"><span class="kd">public</span> <span class="kd">static</span> <span class="n">String</span> <span class="nf">getName</span><span class="o">(</span><span class="n">SimpleProperty</span> <span class="n">element</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="nf">getKey</span><span class="o">(</span><span class="n">element</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="n">PsiElement</span> <span class="nf">setName</span><span class="o">(</span><span class="n">SimpleProperty</span> <span class="n">element</span><span class="o">,</span> <span class="n">String</span> <span class="n">newName</span><span class="o">)</span> <span class="o">{</span>
<span class="n">ASTNode</span> <span class="n">keyNode</span> <span class="o">=</span> <span class="n">element</span><span class="o">.</span><span class="na">getNode</span><span class="o">().</span><span class="na">findChildByType</span><span class="o">(</span><span class="n">SimpleTypes</span><span class="o">.</span><span class="na">KEY</span><span class="o">);</span>
<span class="k">if</span> <span class="o">(</span><span class="n">keyNode</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="n">SimpleProperty</span> <span class="n">property</span> <span class="o">=</span> <span class="n">SimpleElementFactory</span><span class="o">.</span><span class="na">createProperty</span><span class="o">(</span><span class="n">element</span><span class="o">.</span><span class="na">getProject</span><span class="o">(),</span> <span class="n">newName</span><span class="o">);</span>
<span class="n">ASTNode</span> <span class="n">newKeyNode</span> <span class="o">=</span> <span class="n">property</span><span class="o">.</span><span class="na">getFirstChild</span><span class="o">().</span><span class="na">getNode</span><span class="o">();</span>
<span class="n">element</span><span class="o">.</span><span class="na">getNode</span><span class="o">().</span><span class="na">replaceChild</span><span class="o">(</span><span class="n">keyNode</span><span class="o">,</span> <span class="n">newKeyNode</span><span class="o">);</span>
<span class="o">}</span>
<span class="k">return</span> <span class="n">element</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="n">PsiElement</span> <span class="nf">getNameIdentifier</span><span class="o">(</span><span class="n">SimpleProperty</span> <span class="n">element</span><span class="o">)</span> <span class="o">{</span>
<span class="n">ASTNode</span> <span class="n">keyNode</span> <span class="o">=</span> <span class="n">element</span><span class="o">.</span><span class="na">getNode</span><span class="o">().</span><span class="na">findChildByType</span><span class="o">(</span><span class="n">SimpleTypes</span><span class="o">.</span><span class="na">KEY</span><span class="o">);</span>
<span class="k">if</span> <span class="o">(</span><span class="n">keyNode</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">keyNode</span><span class="o">.</span><span class="na">getPsi</span><span class="o">();</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
<a name="define-an-element-factory" class="elem-anchor"></a>
<h3>10.3. Define an element factory<a href="#define-an-element-factory" class="anchor-link"><span></span></a></h3>
<pre><code class="code-block__wrapper code-block _highlighted lang_java"><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">simpleplugin</span><span class="o">.</span><span class="na">psi</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.openapi.project.Project</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.psi.PsiFileFactory</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.simpleplugin.SimpleFileType</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SimpleElementFactory</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="n">SimpleProperty</span> <span class="nf">createProperty</span><span class="o">(</span><span class="n">Project</span> <span class="n">project</span><span class="o">,</span> <span class="n">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">final</span> <span class="n">SimpleFile</span> <span class="n">file</span> <span class="o">=</span> <span class="n">createFile</span><span class="o">(</span><span class="n">project</span><span class="o">,</span> <span class="n">name</span><span class="o">);</span>
<span class="k">return</span> <span class="o">(</span><span class="n">SimpleProperty</span><span class="o">)</span> <span class="n">file</span><span class="o">.</span><span class="na">getFirstChild</span><span class="o">();</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="n">SimpleFile</span> <span class="nf">createFile</span><span class="o">(</span><span class="n">Project</span> <span class="n">project</span><span class="o">,</span> <span class="n">String</span> <span class="n">text</span><span class="o">)</span> <span class="o">{</span>
<span class="n">String</span> <span class="n">name</span> <span class="o">=</span> <span class="s">"dummy.simple"</span><span class="o">;</span>
<span class="k">return</span> <span class="o">(</span><span class="n">SimpleFile</span><span class="o">)</span> <span class="n">PsiFileFactory</span><span class="o">.</span><span class="na">getInstance</span><span class="o">(</span><span class="n">project</span><span class="o">).</span>
<span class="n">createFileFromText</span><span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">SimpleFileType</span><span class="o">.</span><span class="na">INSTANCE</span><span class="o">,</span> <span class="n">text</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
<a name="update-grammar-and-regenerate-the-parser" class="elem-anchor"></a>
<h3>10.4. Update grammar and regenerate the parser<a href="#update-grammar-and-regenerate-the-parser" class="anchor-link"><span></span></a></h3>
<p>Now we need to make corresponding changes to the grammar file and regenerate parser and PSI classes.</p>
<pre><code class="code-block__wrapper code-block _highlighted lang_java"><span class="n">property</span> <span class="o">::=</span> <span class="o">(</span><span class="n">KEY</span><span class="o">?</span> <span class="n">SEPARATOR</span> <span class="n">VALUE</span><span class="o">?)</span> <span class="o">|</span> <span class="n">KEY</span> <span class="o">{</span><span class="n">mixin</span><span class="o">=</span><span class="s">"com.simpleplugin.psi.impl.SimpleNamedElementImpl"</span>
<span class="kd">implements</span><span class="o">=</span><span class="s">"com.simpleplugin.psi.SimpleNamedElement"</span> <span class="n">methods</span><span class="o">=[</span><span class="n">getKey</span> <span class="n">getValue</span> <span class="n">getName</span> <span class="n">setName</span> <span class="n">getNameIdentifier</span><span class="o">]}</span>
</code></pre>
<a name="define-a-reference" class="elem-anchor"></a>
<h3>10.5. Define a reference<a href="#define-a-reference" class="anchor-link"><span></span></a></h3>
<p>Now we need to define a reference class to resolve a property from its usage.</p>
<pre><code class="code-block__wrapper code-block _highlighted lang_java"><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">simpleplugin</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.codeInsight.lookup.LookupElement</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.codeInsight.lookup.LookupElementBuilder</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.openapi.project.Project</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.openapi.util.TextRange</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.psi.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.simpleplugin.psi.SimpleProperty</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.jetbrains.annotations.NotNull</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.jetbrains.annotations.Nullable</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.ArrayList</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.List</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SimpleReference</span> <span class="kd">extends</span> <span class="n">PsiReferenceBase</span><span class="o">&lt;</span><span class="n">PsiElement</span><span class="o">&gt;</span> <span class="kd">implements</span> <span class="n">PsiPolyVariantReference</span> <span class="o">{</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">key</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">SimpleReference</span><span class="o">(</span><span class="nd">@NotNull</span> <span class="n">PsiElement</span> <span class="n">element</span><span class="o">,</span> <span class="n">TextRange</span> <span class="n">textRange</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="n">element</span><span class="o">,</span> <span class="n">textRange</span><span class="o">);</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">element</span><span class="o">.</span><span class="na">getText</span><span class="o">().</span><span class="na">substring</span><span class="o">(</span><span class="n">textRange</span><span class="o">.</span><span class="na">getStartOffset</span><span class="o">(),</span> <span class="n">textRange</span><span class="o">.</span><span class="na">getEndOffset</span><span class="o">());</span>
<span class="o">}</span>
<span class="nd">@NotNull</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">ResolveResult</span><span class="o">[]</span> <span class="nf">multiResolve</span><span class="o">(</span><span class="kt">boolean</span> <span class="n">incompleteCode</span><span class="o">)</span> <span class="o">{</span>
<span class="n">Project</span> <span class="n">project</span> <span class="o">=</span> <span class="n">myElement</span><span class="o">.</span><span class="na">getProject</span><span class="o">();</span>
<span class="kd">final</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">SimpleProperty</span><span class="o">&gt;</span> <span class="n">properties</span> <span class="o">=</span> <span class="n">SimpleUtil</span><span class="o">.</span><span class="na">findProperties</span><span class="o">(</span><span class="n">project</span><span class="o">,</span> <span class="n">key</span><span class="o">);</span>
<span class="n">List</span><span class="o">&lt;</span><span class="n">ResolveResult</span><span class="o">&gt;</span> <span class="n">results</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o">&lt;</span><span class="n">ResolveResult</span><span class="o">&gt;();</span>
<span class="k">for</span> <span class="o">(</span><span class="n">SimpleProperty</span> <span class="n">property</span> <span class="o">:</span> <span class="n">properties</span><span class="o">)</span> <span class="o">{</span>
<span class="n">results</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">PsiElementResolveResult</span><span class="o">(</span><span class="n">property</span><span class="o">));</span>
<span class="o">}</span>
<span class="k">return</span> <span class="n">results</span><span class="o">.</span><span class="na">toArray</span><span class="o">(</span><span class="k">new</span> <span class="n">ResolveResult</span><span class="o">[</span><span class="n">results</span><span class="o">.</span><span class="na">size</span><span class="o">()]);</span>
<span class="o">}</span>
<span class="nd">@Nullable</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">PsiElement</span> <span class="nf">resolve</span><span class="o">()</span> <span class="o">{</span>
<span class="n">ResolveResult</span><span class="o">[]</span> <span class="n">resolveResults</span> <span class="o">=</span> <span class="n">multiResolve</span><span class="o">(</span><span class="kc">false</span><span class="o">);</span>
<span class="k">return</span> <span class="n">resolveResults</span><span class="o">.</span><span class="na">length</span> <span class="o">==</span> <span class="mi">1</span> <span class="o">?</span> <span class="n">resolveResults</span><span class="o">[</span><span class="mi">0</span><span class="o">].</span><span class="na">getElement</span><span class="o">()</span> <span class="o">:</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@NotNull</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Object</span><span class="o">[]</span> <span class="nf">getVariants</span><span class="o">()</span> <span class="o">{</span>
<span class="n">Project</span> <span class="n">project</span> <span class="o">=</span> <span class="n">myElement</span><span class="o">.</span><span class="na">getProject</span><span class="o">();</span>
<span class="n">List</span><span class="o">&lt;</span><span class="n">SimpleProperty</span><span class="o">&gt;</span> <span class="n">properties</span> <span class="o">=</span> <span class="n">SimpleUtil</span><span class="o">.</span><span class="na">findProperties</span><span class="o">(</span><span class="n">project</span><span class="o">);</span>
<span class="n">List</span><span class="o">&lt;</span><span class="n">LookupElement</span><span class="o">&gt;</span> <span class="n">variants</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o">&lt;</span><span class="n">LookupElement</span><span class="o">&gt;();</span>
<span class="k">for</span> <span class="o">(</span><span class="kd">final</span> <span class="n">SimpleProperty</span> <span class="n">property</span> <span class="o">:</span> <span class="n">properties</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">property</span><span class="o">.</span><span class="na">getKey</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="n">property</span><span class="o">.</span><span class="na">getKey</span><span class="o">().</span><span class="na">length</span><span class="o">()</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
<span class="n">variants</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">LookupElementBuilder</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">property</span><span class="o">).</span>
<span class="n">withIcon</span><span class="o">(</span><span class="n">SimpleIcons</span><span class="o">.</span><span class="na">FILE</span><span class="o">).</span>
<span class="n">withTypeText</span><span class="o">(</span><span class="n">property</span><span class="o">.</span><span class="na">getContainingFile</span><span class="o">().</span><span class="na">getName</span><span class="o">())</span>
<span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">return</span> <span class="n">variants</span><span class="o">.</span><span class="na">toArray</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
<a name="define-a-reference-contributor" class="elem-anchor"></a>
<h3>10.6. Define a reference contributor<a href="#define-a-reference-contributor" class="anchor-link"><span></span></a></h3>
<p>A reference contributor allows you to provide references from elements in other languages such as Java to elements in your language.
Lets contribute a reference to each usage of a property.</p>
<pre><code class="code-block__wrapper code-block _highlighted lang_java"><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">simpleplugin</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.openapi.util.TextRange</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.patterns.PlatformPatterns</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.psi.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.util.ProcessingContext</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.jetbrains.annotations.NotNull</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SimpleReferenceContributor</span> <span class="kd">extends</span> <span class="n">PsiReferenceContributor</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">registerReferenceProviders</span><span class="o">(</span><span class="nd">@NotNull</span> <span class="n">PsiReferenceRegistrar</span> <span class="n">registrar</span><span class="o">)</span> <span class="o">{</span>
<span class="n">registrar</span><span class="o">.</span><span class="na">registerReferenceProvider</span><span class="o">(</span><span class="n">PlatformPatterns</span><span class="o">.</span><span class="na">psiElement</span><span class="o">(</span><span class="n">PsiLiteralExpression</span><span class="o">.</span><span class="na">class</span><span class="o">),</span>
<span class="k">new</span> <span class="nf">PsiReferenceProvider</span><span class="o">()</span> <span class="o">{</span>
<span class="nd">@NotNull</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">PsiReference</span><span class="o">[]</span> <span class="nf">getReferencesByElement</span><span class="o">(</span><span class="nd">@NotNull</span> <span class="n">PsiElement</span> <span class="n">element</span><span class="o">,</span> <span class="nd">@NotNull</span> <span class="n">ProcessingContext</span> <span class="n">context</span><span class="o">)</span> <span class="o">{</span>
<span class="n">PsiLiteralExpression</span> <span class="n">literalExpression</span> <span class="o">=</span> <span class="o">(</span><span class="n">PsiLiteralExpression</span><span class="o">)</span> <span class="n">element</span><span class="o">;</span>
<span class="n">String</span> <span class="n">value</span> <span class="o">=</span> <span class="n">literalExpression</span><span class="o">.</span><span class="na">getValue</span><span class="o">()</span> <span class="k">instanceof</span> <span class="n">String</span> <span class="o">?</span> <span class="o">(</span><span class="n">String</span><span class="o">)</span><span class="n">literalExpression</span><span class="o">.</span><span class="na">getValue</span><span class="o">()</span> <span class="o">:</span> <span class="kc">null</span><span class="o">;</span>
<span class="k">if</span> <span class="o">(</span><span class="n">value</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="n">value</span><span class="o">.</span><span class="na">startsWith</span><span class="o">(</span><span class="s">"simple"</span><span class="o">+</span><span class="s">":"</span><span class="o">))</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="n">PsiReference</span><span class="o">[]{</span><span class="k">new</span> <span class="n">SimpleReference</span><span class="o">(</span><span class="n">element</span><span class="o">,</span> <span class="k">new</span> <span class="n">TextRange</span><span class="o">(</span><span class="mi">8</span><span class="o">,</span> <span class="n">value</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o">+</span> <span class="mi">1</span><span class="o">))};</span>
<span class="o">}</span>
<span class="k">return</span> <span class="n">PsiReference</span><span class="o">.</span><span class="na">EMPTY_ARRAY</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">});</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
<a name="register-the-reference-contributor" class="elem-anchor"></a>
<h3>10.7. Register the reference contributor<a href="#register-the-reference-contributor" class="anchor-link"><span></span></a></h3>
<pre><code class="code-block__wrapper code-block _highlighted lang_xml"><span class="nt">&lt;psi.referenceContributor</span> <span class="na">implementation=</span><span class="s">"com.simpleplugin.SimpleReferenceContributor"</span><span class="nt">/&gt;</span>
</code></pre>
<a name="run-the-project" class="elem-anchor"></a>
<h3>10.8. Run the project<a href="#run-the-project" class="anchor-link"><span></span></a></h3>
<p>As you see the IDE now resolves the property and provides completion.</p>
<p><img src="img/reference_contributor.png" alt="Reference Contributor" /></p>
<p><em>Rename</em> refactoring available from definition and usages.</p>
<p><img src="img/rename.png" alt="Rename" /></p>
<a name="define-a-refactoring-support-provider" class="elem-anchor"></a>
<h3>10.9. Define a refactoring support provider<a href="#define-a-refactoring-support-provider" class="anchor-link"><span></span></a></h3>
<p>To allow in-place refactoring we should specify it explicitly in a refactoring support provider.</p>
<pre><code class="code-block__wrapper code-block _highlighted lang_java"><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">simpleplugin</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.lang.refactoring.RefactoringSupportProvider</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.intellij.psi.PsiElement</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.simpleplugin.psi.SimpleProperty</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SimpleRefactoringSupportProvider</span> <span class="kd">extends</span> <span class="n">RefactoringSupportProvider</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isMemberInplaceRenameAvailable</span><span class="o">(</span><span class="n">PsiElement</span> <span class="n">element</span><span class="o">,</span> <span class="n">PsiElement</span> <span class="n">context</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">element</span> <span class="k">instanceof</span> <span class="n">SimpleProperty</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
<a name="register-the-refactoring-support-provider" class="elem-anchor"></a>
<h3>10.10. Register the refactoring support provider<a href="#register-the-refactoring-support-provider" class="anchor-link"><span></span></a></h3>
<pre><code class="code-block__wrapper code-block _highlighted lang_xml"><span class="nt">&lt;lang.refactoringSupport</span> <span class="na">language=</span><span class="s">"Simple"</span> <span class="na">implementationClass=</span><span class="s">"com.simpleplugin.SimpleRefactoringSupportProvider"</span><span class="nt">/&gt;</span>
</code></pre>
<a name="run-the-project-1" class="elem-anchor"></a>
<h3>10.11. Run the project<a href="#run-the-project-1" class="anchor-link"><span></span></a></h3>
<p><img src="img/in_place_rename.png" alt="In Place Rename" /></p>
<p><a href="completion_contributor.html"><span>Previous</span></a>
<a href="/intellij/sdk/docs/tutorials/custom_language_support_tutorial.html"><span>Top</span></a>
<a href="find_usages_provider.html"><span>Next</span></a></p>
<div class="last-modified">
Last modified: 28 December 2015
</div>
</article>
<section class="disqus">
<div id="disqus_thread"></div>
</section>
</div>
</section>
</main>
</div>
<script data-main="/intellij/sdk/docs/app/js/main.build" data-baseurl="/intellij/sdk/docs/" src="/intellij/sdk/docs/app/js/vendor/requirejs/require.js"></script>
</body>
</html>