Найти токен по индексу для сопоставления скобок - PullRequest
0 голосов
/ 28 апреля 2020

Я расширяю пример ANTLR-плагина , чтобы добавить подсветку скобок, поэтому я реализовал класс PairedBraceMatcher из intellij sdk, но не могу найти способ получить PsiElement из индекса, это то, что я пытался доказать:

public class SampleBraceMather implements PairedBraceMatcher {
    private static final BracePair[] PAIRS = {
            new BracePair(TokenIElementType.find((short) 327), TokenIElementType.find((short) 328), true)
    };


    @NotNull
    @Override
    public BracePair[] getPairs() {
        return PAIRS;
    }

    @Override
    public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType lbraceType, @Nullable IElementType contextType) {
        return true;
    }

    @Override
    public int getCodeConstructStart(PsiFile file, int openingBraceOffset) {
        return openingBraceOffset;
    }
}

, и это действительно работает, но я бы не хотел жестко кодировать индекс токенов (так как они часто меняются), все Пока у меня есть SampleLanguageParser.LBRACE и SampleLanguageParser.RBRACE, которые являются индексами токенов ANTLR (11 и 12).

Индексы токенов (327 и 328) определены только в (сгенерированном) файле SampleLanguageLexer.interop в категории ATN, но я не знаю, как получить эти значения оттуда.

1 Ответ

0 голосов
/ 28 апреля 2020

Я нашел это как решение

    private static IElementType LBRACE;
    private static IElementType RBRACE;
    private static IElementType LBRACKET;
    private static IElementType RBRACKET;
    private static IElementType LPARENTHESIS;
    private static IElementType RPARENTHESIS;

    static {
        TokenIElementType.enumerate(type -> {
            if (type instanceof TokenIElementType) {
                TokenIElementType antlrToken = (TokenIElementType) type;
                switch (antlrToken.getANTLRTokenType()) {
                    case SampleLanguageParser.LBRACE:
                        LBRACE = type;
                        break;
                    case SampleLanguageParser.RBRACE:
                        RBRACE = type;
                        break;
                    case SampleLanguageParser.LBRACK:
                        LBRACKET = type;
                        break;
                    case SampleLanguageParser.RBRACK:
                        RBRACKET = type;
                        break;
                    case SampleLanguageParser.LPAREN:
                        LPARENTHESIS = type;
                        break;
                    case SampleLanguageParser.RPAREN:
                        RPARENTHESIS = type;
                        break;
                }
            }
            return false; //Doesnt matter
        });
    }

    private static final BracePair[] PAIRS = {
            new BracePair(LBRACE, RBRACE, true), // {}
            new BracePair(LBRACKET, RBRACKET, false), // []
            new BracePair(LPARENTHESIS, RPARENTHESIS, false), // ()
    };

, но оно кажется очень многословным, любые другие решения приветствуются.

...