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

Camelcade / Perl5-IDEA / #525521563

01 Jun 2025 02:15PM UTC coverage: 82.332% (+0.04%) from 82.289%
#525521563

push

github

hurricup
Bounded wildcards

2 of 2 new or added lines in 2 files covered. (100.0%)

69 existing lines in 17 files now uncovered.

30882 of 37509 relevant lines covered (82.33%)

0.82 hits per line

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

91.07
/plugin/core/src/main/java/com/perl5/lang/perl/psi/references/PerlImplicitDeclarationsService.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.psi.references;
18

19
import com.intellij.openapi.diagnostic.Logger;
20
import com.intellij.openapi.progress.ProgressManager;
21
import com.intellij.openapi.project.Project;
22
import com.intellij.psi.PsiManager;
23
import com.intellij.util.Processor;
24
import com.perl5.lang.perl.psi.PerlSubDefinitionElement;
25
import com.perl5.lang.perl.psi.PerlVariableDeclarationElement;
26
import com.perl5.lang.perl.psi.impl.PerlImplicitSubDefinition;
27
import com.perl5.lang.perl.psi.impl.PerlImplicitVariableDeclaration;
28
import com.perl5.lang.perl.psi.properties.PerlPackageMember;
29
import org.jetbrains.annotations.Contract;
30
import org.jetbrains.annotations.NotNull;
31
import org.jetbrains.annotations.Nullable;
32

33
import java.util.HashMap;
34
import java.util.Map;
35

36
import static com.perl5.lang.perl.util.PerlPackageUtil.CORE_NAMESPACE;
37
import static com.perl5.lang.perl.util.PerlPackageUtil.NAMESPACE_SEPARATOR;
38

39
/**
40
 * Service for a common tricky-defined entities:<ul>
41
 * <li>Built-in subs</li>
42
 * <li>Subs from extensions</li>
43
 * <li>Global scalars, arrays and hashes defined by modules code</li>
44
 * </ul>
45
 */
46
public class PerlImplicitDeclarationsService {
47
  private static final Logger LOG = Logger.getInstance(PerlImplicitDeclarationsService.class);
1✔
48
  private final Map<String, PerlImplicitSubDefinition> mySubsMap = new HashMap<>();
1✔
49
  private final Map<String, PerlImplicitVariableDeclaration> myScalarsMap = new HashMap<>();
1✔
50
  private final Map<String, PerlImplicitVariableDeclaration> myArraysMap = new HashMap<>();
1✔
51
  private final Map<String, PerlImplicitVariableDeclaration> myHashesMap = new HashMap<>();
1✔
52
  private final @NotNull PsiManager myPsiManager;
53

54
  public PerlImplicitDeclarationsService(@NotNull Project project) {
1✔
55
    myPsiManager = PsiManager.getInstance(project);
1✔
56
    PerlImplicitDeclarationsProvider.EP_NAME.forEachExtensionSafe(it -> it.registerDeclarations(this));
1✔
57
  }
1✔
58

59
  public @NotNull PsiManager getPsiManager() {
60
    return myPsiManager;
1✔
61
  }
62

63
  public void registerVariable(@NotNull PerlImplicitVariableDeclaration implicitVariable) {
64
    switch (implicitVariable.getVariableType()) {
1✔
65
      case SCALAR -> doRegister(myScalarsMap, implicitVariable);
1✔
UNCOV
66
      case ARRAY -> doRegister(myArraysMap, implicitVariable);
×
UNCOV
67
      case HASH -> doRegister(myHashesMap, implicitVariable);
×
68
      default -> LOG.warn("Can handle only SCALAR, ARRAY or HASH at the moment, got: " + implicitVariable);
×
69
    }
70
  }
1✔
71

72
  public void registerSub(@NotNull PerlImplicitSubDefinition subDefinition) {
73
    doRegister(mySubsMap, subDefinition);
1✔
74
  }
1✔
75

76
  private static <T extends PerlPackageMember> void doRegister(@NotNull Map<? super String, T> targetMap, @NotNull T entity) {
77
    String canonicalName = entity.getCanonicalName();
1✔
78
    LOG.assertTrue(!targetMap.containsKey(canonicalName), "Multiple registrations for: " + entity);
1✔
79
    targetMap.put(canonicalName, entity);
1✔
80
  }
1✔
81

82
  public @Nullable PerlSubDefinitionElement getCoreSub(@Nullable String subName) {
83
    return getSub(CORE_NAMESPACE, subName);
1✔
84
  }
85

86
  public @Nullable PerlSubDefinitionElement getSub(@Nullable String packageName, @Nullable String subName) {
87
    return getSub(packageName + NAMESPACE_SEPARATOR + subName);
1✔
88
  }
89

90
  @Contract("null->null")
91
  public @Nullable PerlSubDefinitionElement getSub(@Nullable String canonicalName) {
92
    return mySubsMap.get(canonicalName);
1✔
93
  }
94

95
  public boolean processSubsInPackage(@NotNull String packageName, @NotNull Processor<? super PerlSubDefinitionElement> processor) {
96
    return processSubs(it -> !packageName.equals(it.getNamespaceName()) || processor.process(it));
1✔
97
  }
98

99
  public boolean processSubs(@NotNull String canonicalName, @NotNull Processor<? super PerlSubDefinitionElement> processor) {
100
    PerlSubDefinitionElement subDefinitionElement = getSub(canonicalName);
1✔
101
    return subDefinitionElement == null || processor.process(subDefinitionElement);
1✔
102
  }
103

104
  public boolean processSubs(@NotNull Processor<? super PerlSubDefinitionElement> processor) {
105
    for (PerlImplicitSubDefinition subDefinition : mySubsMap.values()) {
1✔
106
      ProgressManager.checkCanceled();
1✔
107
      if (!processor.process(subDefinition)) {
1✔
UNCOV
108
        return false;
×
109
      }
110
    }
1✔
111
    return true;
1✔
112
  }
113

114
  @Contract("null->null")
115
  public @Nullable PerlVariableDeclarationElement getScalar(@Nullable String canonicalName) {
116
    return myScalarsMap.get(canonicalName);
1✔
117
  }
118

119
  @Contract("null->null")
120
  public @Nullable PerlVariableDeclarationElement getArray(@Nullable String canonicalName) {
121
    return myArraysMap.get(canonicalName);
1✔
122
  }
123

124
  @Contract("null->null")
125
  public @Nullable PerlVariableDeclarationElement getHash(@Nullable String canonicalName) {
126
    return myHashesMap.get(canonicalName);
1✔
127
  }
128

129
  public boolean processScalars(@NotNull String canonicalName, @NotNull Processor<? super PerlVariableDeclarationElement> processor) {
130
    PerlVariableDeclarationElement scalar = getScalar(canonicalName);
1✔
131
    return scalar == null || processor.process(scalar);
1✔
132
  }
133

134
  public boolean processArrays(@NotNull String canonicalName, @NotNull Processor<? super PerlVariableDeclarationElement> processor) {
135
    PerlVariableDeclarationElement array = getArray(canonicalName);
1✔
136
    return array == null || processor.process(array);
1✔
137
  }
138

139
  public boolean processHashes(@NotNull String canonicalName, @NotNull Processor<? super PerlVariableDeclarationElement> processor) {
140
    PerlVariableDeclarationElement hash = getHash(canonicalName);
1✔
141
    return hash == null || processor.process(hash);
1✔
142
  }
143

144
  public boolean processScalarsInNamespace(@NotNull String namespaceName,
145
                                           @NotNull Processor<? super PerlVariableDeclarationElement> processor) {
146
    return processScalars(it -> !namespaceName.equals(it.getNamespaceName()) || processor.process(it));
1✔
147
  }
148

149
  public boolean processArraysInNamespace(@NotNull String namespaceName,
150
                                          @NotNull Processor<? super PerlVariableDeclarationElement> processor) {
151
    return processArrays(it -> !namespaceName.equals(it.getNamespaceName()) || processor.process(it));
1✔
152
  }
153

154
  public boolean processHashesInNamespace(@NotNull String namespaceName,
155
                                          @NotNull Processor<? super PerlVariableDeclarationElement> processor) {
156
    return processHashes(it -> !namespaceName.equals(it.getNamespaceName()) || processor.process(it));
1✔
157
  }
158

159
  public boolean processScalars(@NotNull Processor<? super PerlVariableDeclarationElement> processor) {
160
    return processVariables(myScalarsMap, processor);
1✔
161
  }
162

163
  public boolean processArrays(@NotNull Processor<? super PerlVariableDeclarationElement> processor) {
164
    return processVariables(myArraysMap, processor);
1✔
165
  }
166

167
  public boolean processHashes(@NotNull Processor<? super PerlVariableDeclarationElement> processor) {
168
    return processVariables(myHashesMap, processor);
1✔
169
  }
170

171
  private static boolean processVariables(@NotNull Map<String, ? extends PerlImplicitVariableDeclaration> variablesMap,
172
                                          @NotNull Processor<? super PerlVariableDeclarationElement> processor) {
173
    for (PerlImplicitVariableDeclaration variableDeclaration : variablesMap.values()) {
1✔
174
      ProgressManager.checkCanceled();
1✔
175
      if (!processor.process(variableDeclaration)) {
1✔
UNCOV
176
        return false;
×
177
      }
178
    }
1✔
179
    return true;
1✔
180
  }
181

182
  public static @NotNull PerlImplicitDeclarationsService getInstance(@NotNull Project project) {
183
    return project.getService(PerlImplicitDeclarationsService.class);
1✔
184
  }
185
}
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