• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Camelcade / Perl5-IDEA / #525521851

22 May 2026 05:53AM UTC coverage: 76.208% (+0.01%) from 76.196%
#525521851

push

github

hurricup
Build 2026.2-EAP.6228.19

14772 of 22542 branches covered (65.53%)

Branch coverage included in aggregate %.

31144 of 37709 relevant lines covered (82.59%)

0.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

56.25
/plugin/common/src/main/java/com/perl5/lang/perl/idea/editor/PerlBraceMatcher.java
1
/*
2
 * Copyright 2015-2025 Alexandr Evstigneev
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 * http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package com.perl5.lang.perl.idea.editor;
18

19
import com.intellij.lang.BracePair;
20
import com.intellij.lang.PairedBraceMatcher;
21
import com.intellij.psi.PsiComment;
22
import com.intellij.psi.PsiElement;
23
import com.intellij.psi.PsiFile;
24
import com.intellij.psi.PsiWhiteSpace;
25
import com.intellij.psi.tree.IElementType;
26
import com.perl5.lang.perl.psi.PerlSubDefinitionElement;
27
import com.perl5.lang.perl.psi.PsiPerlBlock;
28
import com.perl5.lang.perl.psi.PsiPerlConditionalBlock;
29
import com.perl5.lang.perl.psi.PsiPerlForCompound;
30
import com.perl5.lang.perl.psi.impl.PsiPerlIfCompoundImpl;
31
import org.jetbrains.annotations.NotNull;
32
import org.jetbrains.annotations.Nullable;
33

34
import java.util.Map;
35
import java.util.stream.Collectors;
36

37
import static com.perl5.lang.perl.parser.PerlElementTypesGenerated.*;
38

39

40
public class PerlBraceMatcher implements PairedBraceMatcher {
1✔
41
  public static final Map<IElementType, IElementType> PERL_BRACES_MAP = Map.of(
1✔
42
    LEFT_BRACE, RIGHT_BRACE,
43
    LEFT_BRACKET, RIGHT_BRACKET,
44
    LEFT_PAREN, RIGHT_PAREN,
45
    LEFT_ANGLE, RIGHT_ANGLE,
46
    LEFT_BRACE_SCALAR, RIGHT_BRACE_SCALAR,
47
    LEFT_BRACE_ARRAY, RIGHT_BRACE_ARRAY,
48
    LEFT_BRACE_HASH, RIGHT_BRACE_HASH,
49
    LEFT_BRACE_CODE, RIGHT_BRACE_CODE,
50
    LEFT_BRACE_GLOB, RIGHT_BRACE_GLOB
51
  );
52

53
  public static final Map<IElementType, IElementType> PERL_BRACES_MAP_REVERSED = PERL_BRACES_MAP.entrySet().stream()
1✔
54
    .collect(Collectors.toUnmodifiableMap(Map.Entry::getValue, Map.Entry::getKey));
1✔
55

56
  private static final BracePair[] PAIRS = new BracePair[]{
1✔
57
    new BracePair(REGEX_QUOTE_OPEN, REGEX_QUOTE_CLOSE, false),
58
    new BracePair(REGEX_QUOTE_OPEN_E, REGEX_QUOTE_CLOSE, false),
59
    new BracePair(QUOTE_DOUBLE_OPEN, QUOTE_DOUBLE_CLOSE, false),
60
    new BracePair(QUOTE_SINGLE_OPEN, QUOTE_SINGLE_CLOSE, false),
61
    new BracePair(QUOTE_TICK_OPEN, QUOTE_TICK_CLOSE, false),
62
    new BracePair(LEFT_PAREN, RIGHT_PAREN, false),
63
    new BracePair(LEFT_BRACKET, RIGHT_BRACKET, false),
64
    new BracePair(LEFT_ANGLE, RIGHT_ANGLE, false),
65
    new BracePair(LEFT_BRACE, RIGHT_BRACE, true),
66
    new BracePair(LEFT_BRACE_SCALAR, RIGHT_BRACE_SCALAR, true),
67
    new BracePair(LEFT_BRACE_ARRAY, RIGHT_BRACE_ARRAY, true),
68
    new BracePair(LEFT_BRACE_HASH, RIGHT_BRACE_HASH, true),
69
    new BracePair(LEFT_BRACE_CODE, RIGHT_BRACE_CODE, true),
70
    new BracePair(LEFT_BRACE_GLOB, RIGHT_BRACE_GLOB, true),
71
    new BracePair(STRING_SPECIAL_LEFT_BRACE, STRING_SPECIAL_RIGHT_BRACE, false),
72
  };
73

74
  @Override
75
  public BracePair @NotNull [] getPairs() {
76
    return PAIRS;
1!
77
  }
78

79
  @Override
80
  public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType lbraceType, @Nullable IElementType contextType) {
81
    return true;
1✔
82
  }
83

84
  @Override
85
  public int getCodeConstructStart(PsiFile file, int openingBraceOffset) {
86
    PsiElement element = file.findElementAt(openingBraceOffset);
1✔
87
    if (element == null || element instanceof PsiFile) {
1!
88
      return openingBraceOffset;
×
89
    }
90
    PsiElement codeBlock = element.getParent();
1✔
91

92
    if (!(codeBlock instanceof PsiPerlBlock)) {
1✔
93
      return openingBraceOffset;
1✔
94
    }
95
    PsiElement blockContainer = codeBlock.getParent();
1✔
96

97
    if (blockContainer == null) {
1!
98
      return openingBraceOffset;
×
99
    }
100
    if (blockContainer instanceof PerlSubDefinitionElement || blockContainer instanceof PsiPerlForCompound) {
1!
101
      return blockContainer.getTextOffset();
×
102
    }
103

104
    if (!(blockContainer instanceof PsiPerlConditionalBlock) && !(blockContainer instanceof PsiPerlIfCompoundImpl)) {
1!
105
      return openingBraceOffset;
1✔
106
    }
107

108
    PsiElement keyword = blockContainer.getPrevSibling();
×
109

110
    while ((keyword instanceof PsiWhiteSpace || keyword instanceof PsiComment)) {
×
111
      keyword = keyword.getPrevSibling();
×
112
    }
113

114
    return keyword != null ? keyword.getTextOffset() : openingBraceOffset;
×
115
  }
116
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc