Skip to content

Latest commit

 

History

History
88 lines (63 loc) · 2.76 KB

psi_helper_and_utilities.md

File metadata and controls

88 lines (63 loc) · 2.76 KB
title
6. PSI Helpers and Utilities

6.1. Define helper methods for generated PSI elements

If we want to have custom methods in PSI classes we need to define them separately and ask Grammar-Kit to embed them into generated code.

Let's define a utility class with these helper methods.

package com.intellij.sdk.language.psi.impl;

import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.*;
import com.simpleplugin.SimpleIcons;
import com.simpleplugin.psi.*;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;

public class SimplePsiImplUtil {
  public static String getKey(SimpleProperty element) {
    ASTNode keyNode = element.getNode().findChildByType(SimpleTypes.KEY);
    if (keyNode != null) {
      // IMPORTANT: Convert embedded escaped spaces to simple spaces
      return keyNode.getText().replaceAll("\\\\ ", " ");
    } else {
      return null;
    }
  }

  public static String getValue(SimpleProperty element) {
    ASTNode valueNode = element.getNode().findChildByType(SimpleTypes.VALUE);
    if (valueNode != null) {
      return valueNode.getText();
    } else {
      return null;
    }
  }
}

Note that the SimpleProperty interface referenced in the code above is generated by the parser. Also note that the element.getKey method used in getPresentableText will not be defined - it's a method generated by the parser, which we'll fix below.

6.2. Update grammar and regenerate the parser

Now we tell to use this utility class in the grammar file via psiImplUtilClass attribute.

To tell which methods for which PSI classes must be used we specify methods for particular rule.

{
  parserClass="com.intellij.sdk.language.parser.SimpleParser"

  extends="com.intellij.extapi.psi.ASTWrapperPsiElement"

  psiClassPrefix="Simple"
  psiImplClassSuffix="Impl"
  psiPackage="com.intellij.sdk.language.psi"
  psiImplPackage="com.intellij.sdk.language.psi.impl"

  elementTypeHolderClass="com.intellij.sdk.language.psi.SimpleTypes"
  elementTypeClass="com.intellij.sdk.language.psi.SimpleElementType"
  tokenTypeClass="com.intellij.sdk.language.psi.SimpleTokenType"

  psiImplUtilClass="com.intellij.sdk.language.psi.impl.SimplePsiImplUtil"
}

simpleFile ::= item_*

private item_ ::= (property|COMMENT|CRLF)

property ::= (KEY? SEPARATOR VALUE?) | KEY {methods=[getKey getValue]}

After we made our changes to the grammar we can regenerate the parser and PSI classes.

6.3. Define a utility to search properties

Now we need a utility class to search PSI elements for defined properties over the project. We will use this utility later when implementing code assistance.

{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleUtil.java %}