Reports TokenSet field declarations referencing non-platform element types in ParserDefinition classes.

All languages ParserDefinition are created on the application startup. Declaring a TokenSet referencing non-platform language element types may cause creating and registering all the language element types in the holder class of the referenced type, even if a project doesn't contain any files in this language.

Example:


// element types holder:
public interface MyLangTokenTypes {
  IElementType COMMENT = new MyLangTokenType("COMMENT");
  IElementType TYPE1 = new MyLangTokenType("TYPE1");
  IElementType TYPE2 = new MyLangTokenType("TYPE2");
  // more types...
}


// bad:

public class MyLangParserDefinition implements ParserDefinition {
  // this field causes initializing and registering all the types from MyLangTokenTypes:
  private static final TokenSet COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT);

  @NotNull
  @Override
  public TokenSet getCommentTokens() {
    return COMMENTS;
  }
  ...
}


// good:

public final class MyLangTokenSets {
  public static final TokenSet COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT);
}

public class MyLangParserDefinition implements ParserDefinition {
  @NotNull
  @Override
  public TokenSet getCommentTokens() {
    // types are referenced and registered only when this method is called:
    return MyLangTokenSets.COMMENTS;
  }
  ...
}

// good (Kotlin):

// top-level declaration is not loaded until getCommentTokens() method is called:
private val COMMENTS = TokenSet.create(MyLangTokenTypes.COMMENT);

class MyLangParserDefinition : ParserDefinition {
  override getCommentTokens(): TokenSet {
    return COMMENTS;
  }
  ...
}

// good:

public class MyLangParserDefinition implements ParserDefinition {
  // allowed platform TokenSet:
  private static final TokenSet COMMENTS1 = TokenSet.EMPTY;
  // allowed platform TokenType:
  private static final TokenSet COMMENTS2 = TokenSet.create(TokenType.WHITE_SPACE);

  @NotNull
  @Override
  public TokenSet getCommentTokens() {
    ...
  }
  ...
}

New in 2023.2