• 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

85.92
/plugin/backend/src/main/java/com/perl5/lang/pod/idea/completion/PodTitleCompletionProvider.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.completion;
18

19
import com.intellij.codeInsight.completion.CompletionParameters;
20
import com.intellij.codeInsight.completion.CompletionProvider;
21
import com.intellij.codeInsight.completion.CompletionResultSet;
22
import com.intellij.codeInsight.lookup.LookupElementBuilder;
23
import com.intellij.openapi.util.text.StringUtil;
24
import com.intellij.psi.PsiElement;
25
import com.intellij.psi.PsiFile;
26
import com.intellij.psi.ResolveResult;
27
import com.intellij.psi.tree.IElementType;
28
import com.intellij.psi.util.PsiUtilCore;
29
import com.intellij.util.ProcessingContext;
30
import com.perl5.lang.perl.idea.completion.providers.processors.PerlSimpleCompletionProcessor;
31
import com.perl5.lang.perl.psi.PerlSubElement;
32
import com.perl5.lang.perl.psi.utils.PerlPsiUtil;
33
import com.perl5.lang.pod.parser.PodElementPatterns;
34
import com.perl5.lang.pod.parser.psi.PodRecursiveVisitor;
35
import com.perl5.lang.pod.parser.psi.PodSectionTitle;
36
import com.perl5.lang.pod.parser.psi.PodTitledSection;
37
import com.perl5.lang.pod.parser.psi.references.PodSubReference;
38
import com.perl5.lang.pod.parser.psi.util.PodFileUtil;
39
import org.jetbrains.annotations.NotNull;
40

41
import java.util.Arrays;
42
import java.util.HashSet;
43
import java.util.List;
44
import java.util.Set;
45

46
import static com.perl5.lang.pod.elementTypes.PodStubElementTypes.HEAD_1_SECTION;
47
import static com.perl5.lang.pod.parser.PodElementTypesGenerated.POD_IDENTIFIER;
48

49
public class PodTitleCompletionProvider extends CompletionProvider<CompletionParameters> implements PodElementPatterns {
1✔
50
  public static final String COPYRIGHT_AND_LICENSE = "COPYRIGHT AND LICENSE";
51
  public static final List<String> DEFAULT_POD_SECTIONS =
1✔
52
    List.of("VERSION", "SYNOPSIS", "API", "DESCRIPTION", "INSTALLATION", "NAME", "AUTHORS", "CONTRIBUTORS", COPYRIGHT_AND_LICENSE,
1✔
53
            "METHODS", "ATTRIBUTES", "FUNCTIONS");
54

55
  @Override
56
  protected void addCompletions(@NotNull CompletionParameters parameters,
57
                                @NotNull ProcessingContext context,
58
                                @NotNull CompletionResultSet result) {
59
    PsiElement element = parameters.getPosition();
1✔
60

61
    PsiElement elementParent = element.getParent();
1✔
62
    if (PsiUtilCore.getElementType(element) != POD_IDENTIFIER ||
1!
63
        element.getPrevSibling() != null ||
1!
64
        !(elementParent instanceof PodSectionTitle)) {
65
      return;
×
66
    }
67

68
    IElementType grandparentElementType = PsiUtilCore.getElementType(elementParent.getParent());
1✔
69
    PerlSimpleCompletionProcessor completionProcessor = new PerlSimpleCompletionProcessor(parameters, result, element);
1✔
70

71
    if (grandparentElementType == HEAD_1_SECTION) {
1✔
72
      for (String sectionTitle : DEFAULT_POD_SECTIONS) {
1✔
73
        if (completionProcessor.matches(sectionTitle) && !completionProcessor.process(LookupElementBuilder.create(sectionTitle))) {
1!
74
          break;
×
75
        }
76
      }
1✔
77
    }
78

79
    final PsiFile elementFile = element.getContainingFile().getOriginalFile();
1✔
80
    final PsiFile perlFile = PodFileUtil.getTargetPerlFile(elementFile);
1✔
81
    if (perlFile == null) {
1✔
82
      return;
1✔
83
    }
84

85
    Set<PerlSubElement> possibleTargets = new HashSet<>();
1✔
86
    PerlPsiUtil.processSubElements(perlFile, possibleTargets::add);
1✔
87
    elementFile.accept(new PodRecursiveVisitor() {
1✔
88
      @Override
89
      public void visitTargetableSection(PodTitledSection o) {
90
        processSection(o);
1✔
91
        super.visitTargetableSection(o);
1✔
92
      }
1✔
93

94
      private void processSection(@NotNull PodTitledSection o) {
95
        PsiElement titleBlock = o.getTitleElement();
1✔
96
        if (titleBlock == null) {
1✔
97
          return;
1✔
98
        }
99
        PsiElement firstChild = titleBlock.getFirstChild();
1✔
100
        if (firstChild == null) {
1✔
101
          return;
1✔
102
        }
103
        //noinspection SuspiciousMethodCalls
104
        Arrays.stream(firstChild.getReferences())
1✔
105
          .filter(it -> it instanceof PodSubReference)
1✔
106
          .flatMap(it -> Arrays.stream(((PodSubReference)it).multiResolve(false)))
1✔
107
          .map(ResolveResult::getElement)
1✔
108
          .forEach(possibleTargets::remove);
1✔
109
      }
1✔
110
    });
111

112
    for (PerlSubElement subElement : possibleTargets) {
1✔
113
      String lookupString = StringUtil.notNullize(subElement.getPresentableName());
1✔
114
      if (completionProcessor.matches(lookupString) &&
1!
115
          !completionProcessor.process(LookupElementBuilder.create(subElement, lookupString).withIcon(subElement.getIcon(0)))) {
1!
116
        break;
×
117
      }
118
    }
1✔
119
    completionProcessor.logStatus(getClass());
1✔
120
  }
1✔
121
}
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