magical-l 3ed72d718e
Update annotator.md
若startOffset不+1,则会包含“website”左侧的冒号;若endOffset不-1,则会包含“website”右侧的引号,两种情况都怪怪的。
if we don't +1 for the 'startOffset', then the colon at the left side of "website" will be included; if we don't -1 for the 'endOffset', then the quote mark at the right side of "website" will be included, and both of them are strange.
--------
另,github仓库的源码(https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/simple_language_plugin/src/com/simpleplugin/SimpleAnnotator.java)有误,如下:
btw,the source code in the repository in github(https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/simple_language_plugin/src/com/simpleplugin/SimpleAnnotator.java) is wrong as below:

```
if (properties.size() == 1) {
          TextRange range = new TextRange(element.getTextRange().getStartOffset() + 7,
                                          element.getTextRange().getStartOffset() + 7);
//new TextRange时endOffset跟startOffset相同。
//endOffset is the same as startOffset while new TextRange.
```
2019-10-01 15:27:37 +08:00

2.5 KiB

title
7. Annotator

Annotator helps highlight and annotate any code based on specific rules.

7.1. Define an annotator

In this tutorial we will annotate usages of our properties within Java code. Let's consider a literal which starts with "simple:" as a usage of our property.

package com.simpleplugin;

import com.intellij.lang.annotation.*;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.simpleplugin.psi.SimpleProperty;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class SimpleAnnotator implements Annotator {
  @Override
  public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) {
    if (element instanceof PsiLiteralExpression) {
      PsiLiteralExpression literalExpression = (PsiLiteralExpression) element;
      String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null;

      if (value != null && value.startsWith("simple" + ":")) {
        Project project = element.getProject();
        String key = value.substring(7);
        List<SimpleProperty> properties = SimpleUtil.findProperties(project, key);
        if (properties.size() == 1) {
          TextRange range = new TextRange(element.getTextRange().getStartOffset() + 8,
                                          element.getTextRange().getEndOffset() - 1);
          Annotation annotation = holder.createInfoAnnotation(range, null);
          annotation.setTextAttributes(DefaultLanguageHighlighterColors.LINE_COMMENT);
        } else if (properties.size() == 0) {
          TextRange range = new TextRange(element.getTextRange().getStartOffset() + 8,
                                          element.getTextRange().getEndOffset() - 1);
          holder.createErrorAnnotation(range, "Unresolved property");
        }
      }
    }
  }
}

7.2. Register the annotator

<annotator language="JAVA" implementationClass="com.simpleplugin.SimpleAnnotator"/>

7.3. Run the project

Let's define the following Java file and check if the IDE resolves a property.

public class Test {
    public static void main(String[] args) {
        System.out.println("simple:website");
    }
}

Annotator

If we type an undefined property name, it will annotate the code with a error.

Unresolved property