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

Camelcade / Perl5-IDEA / #525521660

24 Aug 2025 01:28PM UTC coverage: 75.89% (-6.3%) from 82.227%
#525521660

push

github

hurricup
Migrated coverage reporting to https://github.com/nbaztec/coveralls-jacoco-gradle-plugin

See: https://github.com/kt3k/coveralls-gradle-plugin/issues/119

14751 of 22639 branches covered (65.16%)

Branch coverage included in aggregate %.

31091 of 37767 relevant lines covered (82.32%)

0.82 hits per line

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

82.83
/plugin/common/src/main/java/com/perl5/lang/perl/parser/elementTypes/PerlStringContentTokenType.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.parser.elementTypes;
18

19
import com.intellij.lang.ASTNode;
20
import com.intellij.openapi.util.TextRange;
21
import com.intellij.openapi.util.text.StringUtil;
22
import com.intellij.psi.PsiElement;
23
import com.intellij.psi.TokenType;
24
import com.intellij.psi.impl.source.tree.TreeUtil;
25
import com.intellij.psi.tree.IElementType;
26
import com.intellij.psi.tree.TokenSet;
27
import com.intellij.psi.util.PsiUtilCore;
28
import com.perl5.lang.perl.lexer.PerlTokenSets;
29
import com.perl5.lang.perl.psi.utils.PerlPsiUtil;
30
import org.jetbrains.annotations.NotNull;
31
import org.jetbrains.annotations.Nullable;
32

33
import static com.perl5.lang.perl.parser.PerlElementTypesGenerated.*;
34

35
public class PerlStringContentTokenType extends PerlReparseableTokenType {
36
  private static final TokenSet CONTAINERS_TO_RELEX_WITH_GRANDPARENT = TokenSet.create(
1✔
37
    TR_SEARCHLIST, TR_REPLACEMENTLIST, REGEX_REPLACEMENT
38
  );
39

40
  public PerlStringContentTokenType(@NotNull String debugName) {
41
    super(debugName);
1✔
42
  }
1✔
43

44
  @Override
45
  protected @NotNull TextRange getLexerConfirmationRange(@NotNull ASTNode leaf) {
46
    ASTNode parent = leaf.getTreeParent();
1✔
47
    IElementType parentType = PsiUtilCore.getElementType(parent);
1✔
48

49
    if (parentType == STRING_BARE) {
1✔
50
      ASTNode grandParent = parent.getTreeParent();
1✔
51
      IElementType grandParentType = PsiUtilCore.getElementType(grandParent);
1✔
52
      if (grandParentType == STRING_LIST) {
1✔
53
        return grandParent.getTextRange();
1!
54
      }
55
      if (grandParentType == COMMA_SEQUENCE_EXPR) {
1✔
56
        // we need to include =>
57
        PsiElement nextSibling = PerlPsiUtil.getNextSignificantSibling(parent.getPsi());
1✔
58
        int endOffset = nextSibling == null ? grandParent.getTextRange().getEndOffset() :
1!
59
                        nextSibling.getTextRange().getEndOffset();
1✔
60

61
        return TextRange.create(parent.getTextRange().getStartOffset(), endOffset);
1!
62
      }
63
      if (grandParentType == HASH_INDEX) {
1✔
64
        ASTNode hashIndexOwner = grandParent.getTreeParent();
1✔
65
        if (hashIndexOwner != null) {
1!
66
          return TextRange.create(hashIndexOwner.getTextRange().getStartOffset(),
1!
67
                                  grandParent.getTextRange().getEndOffset());
1✔
68
        }
69
      }
70
    }
1✔
71
    else if (PerlTokenSets.QUOTED_STRINGS.contains(parentType)) {
1✔
72
      if (PsiUtilCore.getElementType(parent.getTreeParent()) != HEREDOC_OPENER) {
1✔
73
        return parent.getTextRange();
1!
74
      }
75
    }
76
    else if (CONTAINERS_TO_RELEX_WITH_GRANDPARENT.contains(parentType)) {
1✔
77
      ASTNode grandParent = parent.getTreeParent();
1✔
78
      if (grandParent != null) {
1!
79
        return grandParent.getTextRange();
1!
80
      }
81
    }
×
82
    else if (PerlTokenSets.HEREDOC_BODIES_TOKENSET.contains(parentType)) {
1✔
83
      ASTNode heredocOperator = findHeredocOperator(parent);
1✔
84
      if (heredocOperator != null) {
1!
85
        return TextRange.create(heredocOperator.getStartOffset(), leaf.getTextRange().getEndOffset());
1!
86
      }
87
    }
×
88
    else if (parentType == ATTRIBUTE) {
1✔
89
      return PerlAttributeIdentifierTokenType.getAttributeConfirmationRange(leaf, parent);
1!
90
    }
91
    return TextRange.EMPTY_RANGE;
1!
92
  }
93

94
  private static @Nullable ASTNode findHeredocOperator(@NotNull ASTNode heredocBody) {
95
    ASTNode run = TreeUtil.prevLeaf(heredocBody);
1✔
96
    if (PsiUtilCore.getElementType(run) != TokenType.WHITE_SPACE || !StringUtil.containsLineBreak(run.getChars())) {
1!
97
      return null;
×
98
    }
99

100
    ASTNode firstOpener = null;
1✔
101
    while (true) {
102
      run = TreeUtil.prevLeaf(run);
1✔
103
      if (PsiUtilCore.getElementType(run) == OPERATOR_HEREDOC) {
1✔
104
        firstOpener = run;
1✔
105
      }
106
      else if (run == null || StringUtil.containsLineBreak(run.getChars())) {
1✔
107
        break;
1✔
108
      }
109
    }
110
    return firstOpener;
1✔
111
  }
112
}
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