1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.highlighting;
import com.intellij.lang.BracePair;
import com.intellij.lang.Language;
import com.intellij.lang.PairedBraceMatcher;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
public abstract class PairedBraceAndAnglesMatcher extends PairedBraceMatcherAdapter {
private final TokenSet myTokenSetAllowedInsideAngleBrackets;
private final LanguageFileType myFileType;
public PairedBraceAndAnglesMatcher(@NotNull PairedBraceMatcher matcher,
@NotNull Language language,
@NotNull LanguageFileType fileType,
@NotNull TokenSet tokenSetAllowedInsideAngleBrackets) {
super(matcher, language);
myTokenSetAllowedInsideAngleBrackets = tokenSetAllowedInsideAngleBrackets;
myFileType = fileType;
}
@Override
public boolean isLBraceToken(@NotNull HighlighterIterator iterator, @NotNull CharSequence fileText, @NotNull FileType fileType) {
return isBrace(iterator, fileText, fileType, true);
}
@Override
public boolean isRBraceToken(@NotNull HighlighterIterator iterator, @NotNull CharSequence fileText, @NotNull FileType fileType) {
return isBrace(iterator, fileText, fileType, false);
}
public abstract @NotNull IElementType lt();
public abstract @NotNull IElementType gt();
private boolean isBrace(HighlighterIterator iterator,
CharSequence fileText,
FileType fileType,
boolean left) {
final BracePair pair = findPair(left, iterator, fileText, fileType);
if (pair == null) return false;
final IElementType opposite = left ? gt() : lt();
if ((left ? pair.getRightBraceType() : pair.getLeftBraceType()) != opposite) return true;
if (fileType != myFileType) return false;
final IElementType braceElementType = left ? lt() : gt();
int count = 0;
try {
int paired = 1;
while (true) {
count++;
if (left) {
iterator.advance();
}
else {
iterator.retreat();
}
if (iterator.atEnd()) break;
final IElementType tokenType = iterator.getTokenType();
if (tokenType == opposite) {
paired--;
if (paired == 0) return true;
continue;
}
if (tokenType == braceElementType) {
paired++;
continue;
}
if (!myTokenSetAllowedInsideAngleBrackets.contains(tokenType)) {
return false;
}
}
return false;
}
finally {
while (count-- > 0) {
if (left) {
iterator.retreat();
}
else {
iterator.advance();
}
}
}
}
}
|