• 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.86
/plugin/backend/src/main/java/com/perl5/lang/pod/idea/livetemplates/PodTemplateContextType.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.pod.idea.livetemplates;
18

19
import com.intellij.codeInsight.template.TemplateActionContext;
20
import com.intellij.codeInsight.template.TemplateContextType;
21
import com.intellij.openapi.util.NlsContexts;
22
import com.intellij.openapi.util.text.StringUtil;
23
import com.intellij.psi.FileViewProvider;
24
import com.intellij.psi.PsiElement;
25
import com.intellij.psi.PsiFile;
26
import com.intellij.psi.PsiWhiteSpace;
27
import com.intellij.psi.tree.IElementType;
28
import com.intellij.psi.util.PsiTreeUtil;
29
import com.intellij.psi.util.PsiUtilCore;
30
import com.perl5.PerlBundle;
31
import com.perl5.lang.pod.PodLanguage;
32
import com.perl5.lang.pod.parser.psi.mixin.PodOverSectionContent;
33
import com.perl5.lang.pod.parser.psi.mixin.PodSectionItem;
34
import org.jetbrains.annotations.NotNull;
35
import org.jetbrains.annotations.Nullable;
36

37
import static com.perl5.lang.pod.lexer.PodElementTypes.POD_OUTER;
38
import static com.perl5.lang.pod.parser.PodElementTypesGenerated.POD_CODE;
39
import static com.perl5.lang.pod.parser.PodElementTypesGenerated.POD_NEWLINE;
40

41
public abstract class PodTemplateContextType extends TemplateContextType {
42

43
  public PodTemplateContextType(@NlsContexts.Label @NotNull String presentableName) {
44
    super(presentableName);
1✔
45
  }
1✔
46

47
  @Override
48
  public boolean isInContext(@NotNull TemplateActionContext templateActionContext) {
49
    var psiFile = templateActionContext.getFile();
1✔
50
    var startOffset = templateActionContext.getStartOffset();
1✔
51
    PsiFile podFile = psiFile.getViewProvider().getPsi(PodLanguage.INSTANCE);
1✔
52

53
    if (podFile == null) {
1✔
54
      return false;
1✔
55
    }
56

57
    PsiElement element = podFile.findElementAt(startOffset);
1✔
58

59
    if (element == null) {
1!
60
      element = podFile.findElementAt(startOffset - 1);
×
61
    }
62

63
    if (element == null) {
1!
64
      return false;
×
65
    }
66

67
    return isInContext(element);
1✔
68
  }
69

70
  protected abstract boolean isInContext(PsiElement element);
71

72
  public static class Generic extends PodTemplateContextType {
73
    public Generic() {
74
      this(PodLanguage.NAME);
1✔
75
    }
1✔
76

77
    public Generic(@NlsContexts.Label String presentableName) {
78
      super(presentableName);
1✔
79
    }
1✔
80

81
    @Override
82
    protected boolean isInContext(PsiElement element) {
83
      return false;
1✔
84
    }
85
  }
86

87
  public static class CommandPosition extends PodTemplateContextType.Generic {
88
    public CommandPosition() {
89
      this(PerlBundle.message("label.command.position"));
1✔
90
    }
1✔
91

92
    public CommandPosition(@NlsContexts.Label String presentableName) {
93
      super(presentableName);
1✔
94
    }
1✔
95

96
    @Override
97
    protected boolean isInContext(PsiElement element) {
98
      int startOffset = element.getNode().getStartOffset();
1✔
99

100
      if (startOffset == 0) {
1✔
101
        return true;
1✔
102
      }
103
      else {
104
        FileViewProvider viewProvider = element.getContainingFile().getViewProvider();
1✔
105

106
        PsiElement currentElement = viewProvider.findElementAt(startOffset, PodLanguage.INSTANCE);
1✔
107
        if (currentElement != null && currentElement.getNode().getElementType() == POD_CODE) {
1!
108
          return false;
×
109
        }
110

111
        PsiElement prevElement = viewProvider.findElementAt(startOffset - 1, PodLanguage.INSTANCE);
1✔
112
        IElementType prevElementType = PsiUtilCore.getElementType(prevElement);
1✔
113

114
        if (prevElementType == POD_NEWLINE || prevElementType == POD_OUTER) {
1!
115
          return true;
1✔
116
        }
117

118
        if (prevElement instanceof PsiWhiteSpace && StringUtil.equals(prevElement.getText(), "\n")) {
1✔
119
          while (true) {
120
            if (prevElement == null || prevElement.getTextOffset() == 0) {
1!
121
              return true;
1✔
122
            }
123
            else if (prevElement.getNode().getElementType() == POD_NEWLINE) {
1✔
124
              return true;
1✔
125
            }
126
            else if (!(prevElement instanceof PsiWhiteSpace)) {
1!
127
              return false;
×
128
            }
129
            prevElement = viewProvider.findElementAt(prevElement.getNode().getStartOffset() - 1, PodLanguage.INSTANCE);
1✔
130
          }
131
        }
132
      }
133
      return super.isInContext(element);
1✔
134
    }
135
  }
136

137
  public static class InsideOver extends CommandPosition {
138
    public InsideOver(@NlsContexts.Label String presentableName) {
139
      super(presentableName);
1✔
140
    }
1✔
141

142
    @Override
143
    protected boolean isInContext(PsiElement element) {
144
      return super.isInContext(element) && PsiTreeUtil.getParentOfType(element, PodOverSectionContent.class) != null;
1✔
145
    }
146

147
    protected @Nullable PodSectionItem getFirstSectionItem(PsiElement element) {
148
      PodOverSectionContent sectionContent = PsiTreeUtil.getParentOfType(element, PodOverSectionContent.class);
1✔
149
      return sectionContent == null ? null : sectionContent.getFirstItem();
1!
150
    }
151
  }
152

153
  public static class InsideOverBulleted extends InsideOver {
154
    public InsideOverBulleted() {
155
      super(PerlBundle.message("label.inside.over.block.bulleted"));
1✔
156
    }
1✔
157

158
    @Override
159
    protected boolean isInContext(PsiElement element) {
160
      if (!super.isInContext(element)) {
1✔
161
        return false;
1✔
162
      }
163

164
      PodSectionItem firstItem = getFirstSectionItem(element);
1✔
165
      return firstItem == null || firstItem.isBulleted();
1!
166
    }
167
  }
168

169
  public static class InsideOverNotBulleted extends InsideOver {
170
    public InsideOverNotBulleted() {
171
      super(PerlBundle.message("label.inside.over.block.not.bulleted"));
1✔
172
    }
1✔
173

174
    @Override
175
    protected boolean isInContext(PsiElement element) {
176
      if (!super.isInContext(element)) {
1✔
177
        return false;
1✔
178
      }
179

180
      PodSectionItem firstItem = getFirstSectionItem(element);
1✔
181
      return firstItem == null || !firstItem.isBulleted();
1!
182
    }
183
  }
184
}
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