documentation_provider.md: cleanup

This commit is contained in:
Karol Lewandowski 2022-03-11 14:33:28 +01:00
parent 968b2dabed
commit 8023d025e5

View File

@ -6,19 +6,17 @@
A [`DocumentationProvider`](upsource:///platform/analysis-api/src/com/intellij/lang/documentation/DocumentationProvider.java)
helps users by showing documentation for symbols like method calls inside the editor.
For the custom language tutorial, were implementing a version of this EP for the Simple Language that shows the key/value,
For the custom language tutorial, we're implementing a version of this extension point (EP) for the Simple Language that shows the key/value,
the file where it is defined, and any related documentation comment.
**Reference:** [](documentation.md)
## Implement DocumentationProvider and Register the EP
In the first step, we create an empty class that extends
[`AbstractDocumentationProvider`](upsource:///platform/analysis-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java)
and registers it in the <path>plugin.xml</path>.
```java
public class SimpleDocumentationProvider extends AbstractDocumentationProvider { }
```
@ -29,11 +27,10 @@ Make sure the class is registered in the <path>plugin.xml</path> between the `ex
<extensions defaultExtensionNs="com.intellij">
<!-- Other extensions… -->
<lang.documentationProvider language="Simple"
implementationClass="org.intellij.sdk.language.SimpleDocumentationProvider"/>
implementationClass="org.intellij.sdk.language.SimpleDocumentationProvider"/>
</extensions>
```
## Ensure That the Correct PSI Element Is Used
For the Simple Language, we consider two use-cases:
@ -47,8 +44,9 @@ we create a dummy implementation of `generateDoc()`:
```java
@Override
public @Nullable String generateDoc(PsiElement element, @Nullable PsiElement originalElement) {
return super.generateDoc(element, originalElement);
public @Nullable String generateDoc(PsiElement element,
@Nullable PsiElement originalElement) {
return super.generateDoc(element, originalElement);
}
```
@ -65,7 +63,6 @@ Inside a Simple file, the situation is similar, and calling <menupath>View | Qui
Please refer to the Addendum below, which explains how to improve on this situation by additionally overriding `getCustomDocumentationElement()` method.
## Extract Documentation Comments from Key/Value Definitions
While `SimpleProperty` elements will provide us with their key and value, we have no direct access to a possible comment that is preceding the key/value definition.
@ -73,14 +70,14 @@ Since we would like to show this comment in the documentation as well, we need a
This function will reside in the `SimpleUtil` class and will find for instance the comment preceding `apikey` in the following short example:
```text
#An application programming interface key (API key) is a unique identifier used
#to authenticate a user, developer, or calling program to an API.
#An application programming interface key (API key) is a unique identifier
#used to authenticate a user, developer, or calling program to an API.
apikey=ph342m91337h4xX0r5k!11Zz!
```
The following implementation will check if there is any comment preceding a `SimpleProperty`, and if there is,
it will collect all comment lines until it reaches either the previous key/value definition or the beginning of the file.
One caveat is that since were collecting the comment lines backwards, we need to reverse the list before joining them into a single string.
One caveat is that since we're collecting the comment lines backwards, we need to reverse the list before joining them into a single string.
A simple regex is used to remove the leading hash characters and whitespaces from each line.
```java
@ -120,7 +117,7 @@ After implementing all the steps above, the IDE will show the rendered documenta
We can provide implementations for additional functionality that comes with a `DocumentationProvider`.
For instance, when simply hovering the mouse over the code, it also shows documentation after a short delay.
Its not necessary that this popup show the exact same information as when calling _Quick Documentation_, but for the purpose of this tutorial, well do just that.
It's not necessary that this popup show the exact same information as when calling _Quick Documentation_, but for the purpose of this tutorial, we'll do just that.
```java
```
@ -141,7 +138,6 @@ In that case, language developers need to ensure that the correct PSI element fo
In the case of Simple Language, the lookup element is already a `SimpleProperty` and no additional work needs to be done.
In other circumstances, you can override `getDocumentationElementForLookupItem() `and return the correct PSI element.
## Addendum: Choosing a Better Target Element
To be able to call <menupath>View | Quick Documentation</menupath> for Simple properties in all places of a Java string literal, two steps are required:
@ -156,29 +152,37 @@ This allows getting documentation for a Simple property no matter where it was c
```java
@Override
public @Nullable PsiElement getCustomDocumentationElement(@NotNull Editor editor, @NotNull PsiFile file, @Nullable PsiElement contextElement, int targetOffset) {
if (contextElement != null) {
// In this part the SimpleProperty element is extracted from inside a Java string
if (contextElement instanceof PsiJavaToken && ((PsiJavaToken) contextElement).getTokenType().equals(JavaTokenType.STRING_LITERAL)) {
final PsiElement parent = contextElement.getParent();
final PsiReference[] references = parent.getReferences();
for (PsiReference ref : references) {
if (ref instanceof SimpleReference) {
final PsiElement property = ref.resolve();
if (property instanceof SimpleProperty) {
return property;
}
}
}
}
// In this part the SimpleProperty element is extracted when inside a .simple file
else if (contextElement.getLanguage() == SimpleLanguage.INSTANCE) {
final PsiElement property = PsiTreeUtil.getParentOfType(contextElement, SimpleProperty.class);
if (property != null) {
return property;
}
}
}
return super.getCustomDocumentationElement(editor, file, contextElement, targetOffset);
public @Nullable PsiElement getCustomDocumentationElement(@NotNull Editor editor,
@NotNull PsiFile file,
@Nullable PsiElement context,
int targetOffset) {
if (context != null) {
// In this part the SimpleProperty element
// is extracted from inside a Java string
if (context instanceof PsiJavaToken &&
((PsiJavaToken) context).getTokenType().equals(JavaTokenType.STRING_LITERAL)) {
PsiElement parent = context.getParent();
PsiReference[] references = parent.getReferences();
for (PsiReference ref : references) {
if (ref instanceof SimpleReference) {
PsiElement property = ref.resolve();
if (property instanceof SimpleProperty) {
return property;
}
}
}
}
// In this part the SimpleProperty element is extracted
// when inside of a .simple file
else if (context.getLanguage() == SimpleLanguage.INSTANCE) {
PsiElement property =
PsiTreeUtil.getParentOfType(context, SimpleProperty.class);
if (property != null) {
return property;
}
}
}
return super.getCustomDocumentationElement(
editor, file, context, targetOffset);
}
```