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

Camelcade / Perl5-IDEA / #525521553

27 May 2025 10:24AM UTC coverage: 82.286% (-0.03%) from 82.32%
#525521553

push

github

hurricup
Removed redundant implementations, moved up to the abstract class

1 of 1 new or added line in 1 file covered. (100.0%)

128 existing lines in 30 files now uncovered.

30886 of 37535 relevant lines covered (82.29%)

0.82 hits per line

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

93.28
/plugin/core/src/main/java/com/perl5/lang/perl/idea/completion/util/PerlVariableCompletionUtil.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.completion.util;
18

19
import com.intellij.codeInsight.completion.CompletionUtil;
20
import com.intellij.codeInsight.lookup.LookupElement;
21
import com.intellij.codeInsight.lookup.LookupElementBuilder;
22
import com.intellij.openapi.project.Project;
23
import com.intellij.openapi.util.text.StringUtil;
24
import com.intellij.psi.PsiElement;
25
import com.intellij.psi.scope.PsiScopeProcessor;
26
import com.intellij.psi.search.GlobalSearchScope;
27
import com.intellij.psi.util.PsiTreeUtil;
28
import com.intellij.util.Processor;
29
import com.intellij.util.containers.ContainerUtil;
30
import com.perl5.PerlBundle;
31
import com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor;
32
import com.perl5.lang.perl.idea.PerlCompletionWeighter;
33
import com.perl5.lang.perl.idea.completion.PerlInsertHandlers;
34
import com.perl5.lang.perl.idea.completion.providers.processors.PerlDelegatingVariableCompletionProcessor;
35
import com.perl5.lang.perl.idea.completion.providers.processors.PerlVariableCompletionProcessor;
36
import com.perl5.lang.perl.idea.completion.providers.processors.PerlVariableCompletionProcessorImpl;
37
import com.perl5.lang.perl.idea.configuration.settings.PerlSharedSettings;
38
import com.perl5.lang.perl.idea.ui.PerlIconProvider;
39
import com.perl5.lang.perl.internals.PerlVersion;
40
import com.perl5.lang.perl.psi.*;
41
import com.perl5.lang.perl.psi.impl.PerlBuiltInVariable;
42
import com.perl5.lang.perl.psi.properties.PerlLexicalScope;
43
import com.perl5.lang.perl.psi.references.PerlBuiltInVariablesService;
44
import com.perl5.lang.perl.psi.utils.PerlResolveUtil;
45
import com.perl5.lang.perl.psi.utils.PerlVariableType;
46
import com.perl5.lang.perl.util.*;
47
import com.perl5.lang.perl.util.processors.PerlNamespaceEntityProcessor;
48
import org.jetbrains.annotations.NotNull;
49
import org.jetbrains.annotations.Nullable;
50

51
import javax.swing.*;
52
import java.util.HashSet;
53
import java.util.Objects;
54
import java.util.Set;
55

56
import static com.perl5.PerlIcons.GLOB_GUTTER_ICON;
57

58
public class PerlVariableCompletionUtil {
×
59

60
  public static @NotNull LookupElementBuilder processVariableLookupElement(@NotNull String name, @NotNull PerlVariableType variableType) {
61
    return LookupElementBuilder.create(PerlVariable.braceName(name)).withIcon(PerlIconProvider.getIcon(variableType));
1✔
62
  }
63

64
  public static @NotNull LookupElementBuilder createArrayElementLookupElement(@NotNull String name,
65
                                                                              @NotNull PerlVariableType variableType) {
66
    return processVariableLookupElement(name, variableType)
1✔
67
      .withInsertHandler(PerlInsertHandlers.ARRAY_ELEMENT_INSERT_HANDLER).withTailText("[]");
1✔
68
  }
69

70
  public static @NotNull LookupElementBuilder processHashElementLookupElement(@NotNull String name,
71
                                                                              @NotNull PerlVariableType variableType) {
72
    return processVariableLookupElement(name, variableType)
1✔
73
      .withInsertHandler(PerlInsertHandlers.HASH_ELEMENT_INSERT_HANDLER).withTailText("{}");
1✔
74
  }
75

76
  /**
77
   * @param sigilToPrepend '_' means we don't need to prepend
78
   */
79
  public static boolean processVariableLookupElement(@NotNull PerlVariableDeclarationElement element,
80
                                                     char sigilToPrepend,
81
                                                     @NotNull PerlVariableCompletionProcessor completionProcessor) {
82
    String variableName = StringUtil.notNullize(element.getName());
1✔
83
    if (!completionProcessor.hasBraces()) {
1✔
84
      variableName = PerlVariable.braceName(variableName);
1✔
85
    }
86

87
    boolean isBuiltIn = element instanceof PerlBuiltInVariable;
1✔
88

89
    String explicitNamespaceName = completionProcessor.getExplicitNamespaceName();
1✔
90
    if (StringUtil.isNotEmpty(explicitNamespaceName) && !isBuiltIn && element.isGlobalDeclaration() &&
1✔
91
        !explicitNamespaceName.equals(element.getNamespaceName())) {
1✔
92
      return completionProcessor.result();
×
93
    }
94

95
    String lookupString = variableName;
1✔
96
    if (!isBuiltIn && element.isGlobalDeclaration() && !completionProcessor.isLexical()) {
1✔
97
      lookupString = element.getCanonicalName();
1✔
98
      if (StringUtil.isEmpty(lookupString)) {
1✔
99
        return completionProcessor.result();
×
100
      }
101
    }
102

103
    if (completionProcessor.isFullQualified()) {
1✔
104
      if (!completionProcessor.matches(lookupString)) {
1✔
105
        return completionProcessor.result();
1✔
106
      }
107
    }
108
    else {
109
      if (!completionProcessor.matches(variableName)) {
1✔
110
        return completionProcessor.result();
1✔
111
      }
112
    }
113

114
    Icon icon;
115
    if (sigilToPrepend != '_') {
1✔
116
      lookupString = sigilToPrepend + lookupString;
1✔
117
      icon = PerlVariableType.bySigil(sigilToPrepend).getIcon();
1✔
118
    }
119
    else {
120
      icon = PerlIconProvider.getIcon(element);
1✔
121
    }
122

123
    LookupElementBuilder elementBuilder = LookupElementBuilder.create(element, lookupString)
1✔
124
      .withIcon(icon)
1✔
125
      .withPresentableText(variableName);
1✔
126

127
    if (isBuiltIn) {
1✔
128
      elementBuilder = elementBuilder.withTypeText(PerlBundle.message("built.in.type.text"));
1✔
129
    }
130
    else if (element.isGlobalDeclaration()) {
1✔
131
      elementBuilder = elementBuilder.withTypeText(element.getNamespaceName(), true);
1✔
132
    }
133

134
    return completionProcessor.process(
1✔
135
      sigilToPrepend == '_' ?
1✔
136
      elementBuilder :
1✔
137
      elementBuilder.withLookupString(
1✔
138
        completionProcessor.isFullQualified() ? StringUtil.notNullize(element.getCanonicalName()) : variableName));
1✔
139
  }
140

141
  public static @Nullable LookupElementBuilder processVariableLookupElement(@NotNull PerlGlobVariableElement typeGlob,
142
                                                                            boolean withSigil,
143
                                                                            @NotNull PerlVariableCompletionProcessor variableCompletionProcessor) {
144
    String variableName = StringUtil.notNullize(typeGlob.getCanonicalName());
1✔
145
    if (!variableCompletionProcessor.matches(variableName)) {
1✔
146
      return null;
×
147
    }
148
    String lookupString = withSigil ?
1✔
149
                          PerlVariableType.GLOB.getSigil() + variableName :
1✔
150
                          variableName;
1✔
151

152
    LookupElementBuilder elementBuilder = LookupElementBuilder
1✔
153
      .create(typeGlob, lookupString)
1✔
154
      .withPresentableText(Objects.requireNonNull(typeGlob.getName()))
1✔
155
      .withTypeText(typeGlob.getNamespaceName(), true)
1✔
156
      .withIcon(GLOB_GUTTER_ICON);
1✔
157
    return withSigil ? elementBuilder.withLookupString(variableName) : elementBuilder;
1✔
158
  }
159

160
  public static void fillWithUnresolvedVars(@NotNull PerlVariableCompletionProcessorImpl completionProcessor) {
161
    PsiElement variableNameElement = completionProcessor.getLeafElement();
1✔
162
    final PerlLexicalScope lexicalScope = PsiTreeUtil.getParentOfType(variableNameElement, PerlLexicalScope.class);
1✔
163
    PsiElement perlVariable = variableNameElement.getParent();
1✔
164
    final Set<String> collectedNames = new HashSet<>();
1✔
165

166
    if (lexicalScope != null && perlVariable instanceof PerlVariable variable) {
1✔
167
      final int minOffset = variableNameElement.getTextOffset();
1✔
168
      final PerlVariableType actualType = variable.getActualType();
1✔
169

170
      lexicalScope.accept(new PerlCompletionRecursiveVisitor(completionProcessor) {
1✔
171
        @Override
172
        public void visitPerlVariable(@NotNull PerlVariable perlVariable) {
173
          if (perlVariable.isValid() &&
1✔
174
              !(perlVariable.getParent() instanceof PerlVariableDeclarationElement) &&
1✔
175
              perlVariable.getTextOffset() > minOffset &&
×
176
              actualType == perlVariable.getActualType()
×
177
          ) {
178
            String variableName = perlVariable.getName();
×
179
            if (completionProcessor.matches(variableName) &&
×
180
                collectedNames.add(variableName) &&
×
181
                perlVariable.getLexicalDeclaration() == null) {
×
182
              completionProcessor.process(LookupElementBuilder.create(variableName));
×
183
            }
184
          }
185
          super.visitPerlVariable(perlVariable);
1✔
186
        }
1✔
187
      });
188
    }
189
  }
1✔
190

191
  public static @NotNull <T extends LookupElement> T setLexical(@NotNull T element) {
192
    element.putUserData(PerlCompletionWeighter.WEIGHT, 1);
1✔
193
    return element;
1✔
194
  }
195

196
  public static void fillWithBuiltInVariables(@NotNull PerlVariableCompletionProcessor completionProcessor) {
197
    PerlBuiltInVariablesService.getInstance(
1✔
198
      completionProcessor.getProject()).processVariables(createBuiltInVariablesLookupProcessor(completionProcessor));
1✔
199
  }
1✔
200

201
  public static void fillWithLexicalVariables(@NotNull PerlVariableCompletionProcessor variableCompletionProcessor) {
202
    PsiElement perlVariable = variableCompletionProcessor.getLeafParentElement();
1✔
203
    Processor<PerlVariableDeclarationElement> lookupProcessor = createLexicalLookupProcessor(
1✔
204
      new PerlDelegatingVariableCompletionProcessor(variableCompletionProcessor) {
1✔
205
        @Override
206
        public boolean isLexical() {
207
          return true;
1✔
208
        }
209
      });
210

211
    PsiScopeProcessor processor = (element, __) -> {
1✔
212
      if (!(element instanceof PerlVariableDeclarationElement variable)) {
1✔
213
        return true;
1✔
214
      }
215
      PsiElement declarationStatement = PsiTreeUtil.getParentOfType(variable, PerlStatement.class);
1✔
216
      if (PsiTreeUtil.isAncestor(declarationStatement, perlVariable, false)) {
1✔
217
        return true;
1✔
218
      }
219

220
      if (StringUtil.isNotEmpty(variable.getName())) {
1✔
221
        boolean processResult = lookupProcessor.process(variable);
1✔
222
        if (processResult && variable.isGlobalDeclaration()) {
1✔
223
          variableCompletionProcessor.register(variable.getCanonicalNameWithSigil());
1✔
224
        }
225
        return processResult;
1✔
226
      }
227

228
      return true;
×
229
    };
230
    PerlResolveUtil.treeWalkUp(variableCompletionProcessor.getLeafElement(), processor);
1✔
231
  }
1✔
232

233

234
  /**
235
   * @return lookup generator for lexical variables
236
   * @see #createLookupGenerator(Processor, boolean, PerlVariableCompletionProcessor)
237
   */
238
  private static @NotNull Processor<PerlVariableDeclarationElement> createLexicalLookupProcessor(
239
    @NotNull PerlVariableCompletionProcessor variableCompletionProcessor) {
240
    return createVariableLookupProcessor(
1✔
241
      new PerlDelegatingVariableCompletionProcessor(variableCompletionProcessor) {
1✔
242
        @Override
243
        public void addElement(@NotNull LookupElementBuilder lookupElement) {
244
          super.addElement(setLexical(lookupElement));
1✔
245
        }
1✔
246
      });
247
  }
248

249
  /**
250
   * @return lookup generator for built-in variables
251
   * @see #createLookupGenerator(Processor, boolean, PerlVariableCompletionProcessor)
252
   */
253
  private static @NotNull Processor<PerlVariableDeclarationElement> createBuiltInVariablesLookupProcessor(
254
    @NotNull PerlVariableCompletionProcessor perlVariableCompletionProcessor) {
255
    return createVariableLookupProcessor(
1✔
256
      new PerlDelegatingVariableCompletionProcessor(perlVariableCompletionProcessor) {
1✔
257
        @Override
258
        public void addElement(@NotNull LookupElementBuilder lookupElement) {
259
          super.addElement(lookupElement.withBoldness(true));
1✔
260
        }
1✔
261
      });
262
  }
263

264
  /**
265
   * @return processor of variable declarations, generating lookup elements for them and feeding to the {@code lookupConsumer}
266
   */
267
  private static @NotNull Processor<PerlVariableDeclarationElement> createVariableLookupProcessor(
268
    @NotNull PerlVariableCompletionProcessor completionProcessor) {
269

270
    PsiElement perlVariable = completionProcessor.getLeafParentElement();
1✔
271
    boolean addHashSlices = hasHashSlices(perlVariable);
1✔
272

273
    PerlDelegatingVariableCompletionProcessor hashElementCompletionProcessor =
1✔
274
      new PerlDelegatingVariableCompletionProcessor(completionProcessor) {
1✔
275
        @Override
276
        public void addElement(@NotNull LookupElementBuilder lookupElement) {
277
          super.addElement(lookupElement.withInsertHandler(PerlInsertHandlers.HASH_ELEMENT_INSERT_HANDLER).withTailText("{}"));
1✔
278
        }
1✔
279
      };
280
    PerlDelegatingVariableCompletionProcessor arrayElementCompletionProcessor =
1✔
281
      new PerlDelegatingVariableCompletionProcessor(completionProcessor) {
1✔
282
        @Override
283
        public void addElement(@NotNull LookupElementBuilder lookupElement) {
284
          super.addElement(lookupElement.withInsertHandler(PerlInsertHandlers.ARRAY_ELEMENT_INSERT_HANDLER).withTailText("[]"));
1✔
285
        }
1✔
286
      };
287

288
    return switch (perlVariable) {
1✔
289
      case PsiPerlScalarVariable ignored -> variable -> {
1✔
290
        if (variable.getActualType() == PerlVariableType.SCALAR) {
1✔
291
          return processVariableLookupElement(variable, '_', completionProcessor);
1✔
292
        }
293
        else if (variable.getActualType() == PerlVariableType.ARRAY) {
1✔
294
          return processVariableLookupElement(variable, '_', arrayElementCompletionProcessor);
1✔
295
        }
296
        else if (variable.getActualType() == PerlVariableType.HASH) {
1✔
297
          return processVariableLookupElement(variable, '_', hashElementCompletionProcessor);
1✔
298
        }
299
        return completionProcessor.result();
1✔
300
      };
301
      case PsiPerlArrayVariable ignored -> variable -> {
1✔
302
        if (variable.getActualType() == PerlVariableType.ARRAY) {
1✔
303
          return processVariableLookupElement(variable, '_', completionProcessor) &&
1✔
304
                 processVariableLookupElement(variable, '_', arrayElementCompletionProcessor);
1✔
305
        }
306
        else if (variable.getActualType() == PerlVariableType.HASH) {
1✔
307
          return processVariableLookupElement(variable, '_', hashElementCompletionProcessor);
1✔
308
        }
309
        return completionProcessor.result();
1✔
310
      };
311
      case PsiPerlArrayIndexVariable ignored -> variable -> {
1✔
312
        if (variable.getActualType() == PerlVariableType.ARRAY) {
1✔
313
          return processVariableLookupElement(variable, '_', completionProcessor);
1✔
314
        }
315
        return completionProcessor.result();
1✔
316
      };
317
      case PsiPerlHashVariable ignored -> variable -> {
1✔
318
        PerlVariableType variableType = variable.getActualType();
1✔
319
        if (variableType == PerlVariableType.HASH) {
1✔
320
          return processVariableLookupElement(variable, '_', completionProcessor) &&
1✔
321
                 (!addHashSlices || processVariableLookupElement(variable, '_', hashElementCompletionProcessor));
1✔
322
        }
323
        else if (addHashSlices && variableType == PerlVariableType.ARRAY) {
1✔
324
          return processVariableLookupElement(variable, '_', arrayElementCompletionProcessor);
1✔
325
        }
326
        return completionProcessor.result();
1✔
327
      };
328
      case PerlGlobVariableElement ignored -> variable -> processVariableLookupElement(variable, '_', completionProcessor);
1✔
329
      default -> variable -> {
1✔
330
        PerlVariableType variableType = variable.getActualType();
1✔
331
        if (variableType == PerlVariableType.SCALAR) {
1✔
332
          return processVariableLookupElement(variable, PerlVariableType.SCALAR.getSigil(), completionProcessor);
1✔
333
        }
334
        else if (variableType == PerlVariableType.ARRAY) {
1✔
335
          return processVariableLookupElement(variable, PerlVariableType.ARRAY.getSigil(), completionProcessor) &&
1✔
336
                 processVariableLookupElement(variable, PerlVariableType.SCALAR.getSigil(), arrayElementCompletionProcessor) &&
1✔
337
                 processVariableLookupElement(variable, PerlVariableType.ARRAY.getSigil(), arrayElementCompletionProcessor);
1✔
338
        }
339
        else if (variable.getActualType() == PerlVariableType.HASH) {
1✔
340
          return processVariableLookupElement(variable, PerlVariableType.HASH.getSigil(), completionProcessor) &&
1✔
341
                 processVariableLookupElement(variable, PerlVariableType.SCALAR.getSigil(), hashElementCompletionProcessor) &&
1✔
342
                 processVariableLookupElement(variable, PerlVariableType.ARRAY.getSigil(), hashElementCompletionProcessor);
1✔
343
        }
344
        return completionProcessor.result();
1✔
345
      };
346
    };
347
  }
348

349
  /**
350
   * @return true iff 5.20 hash/array slices are enabled
351
   */
352
  private static boolean hasHashSlices(@NotNull PsiElement psiElement) {
353
    return !PerlSharedSettings.getInstance(psiElement).getTargetPerlVersion().lesserThan(PerlVersion.V5_20);
1✔
354
  }
355

356
  private static final Set<String> VARIABLES_AVAILABLE_ONLY_WITH_FQN = ContainerUtil.newHashSet(
1✔
357
    "ISA", "EXPORT", "EXPORT_OK", "EXPORT_TAGS", "EXPORT_FAIL", "VERSION"
358
  );
359

360
  @SuppressWarnings("UnusedReturnValue")
361
  public static boolean processFullQualifiedVariables(@NotNull PerlVariableCompletionProcessor variableCompletionProcessor) {
362
    if (!variableCompletionProcessor.isFullQualified() && variableCompletionProcessor.getCompletionParameters().getInvocationCount() == 0) {
1✔
363
      return variableCompletionProcessor.result();
1✔
364
    }
365
    PsiElement variableNameElement = variableCompletionProcessor.getLeafElement();
1✔
366
    PsiElement perlVariable = variableCompletionProcessor.getLeafParentElement();
1✔
367
    Processor<PerlVariableDeclarationElement> variableProcessor = createVariableLookupProcessor(variableCompletionProcessor);
1✔
368
    Processor<PerlVariableDeclarationElement> lookupGenerator = it -> {
1✔
369
      if (!variableCompletionProcessor.isFullQualified() && VARIABLES_AVAILABLE_ONLY_WITH_FQN.contains(it.getName())) {
1✔
370
        return variableCompletionProcessor.result();
1✔
371
      }
372

373
      String idString = it.getCanonicalNameWithSigil();
1✔
374
      if (!variableCompletionProcessor.isRegistered(idString)) {
1✔
375
        return variableProcessor.process(it);
1✔
376
      }
377
      return variableCompletionProcessor.result();
1✔
378
    };
379

380
    Project project = variableNameElement.getProject();
1✔
381
    GlobalSearchScope resolveScope = variableNameElement.getResolveScope();
1✔
382
    String namespaceName = variableCompletionProcessor.getExplicitNamespaceName();
1✔
383

384
    return switch (perlVariable) {
1✔
385
      case PsiPerlScalarVariable ignored ->
1✔
386
        PerlScalarUtil.processGlobalScalars(project, resolveScope, namespaceName, false, lookupGenerator) &&
1✔
387
        PerlArrayUtil.processGlobalArrays(project, resolveScope, namespaceName, false, lookupGenerator) &&
1✔
388
        PerlHashUtil.processGlobalHashes(project, resolveScope, namespaceName, false, lookupGenerator);
1✔
389

390
      case PsiPerlArrayVariable ignored ->
1✔
391
        PerlArrayUtil.processGlobalArrays(project, resolveScope, namespaceName, false, lookupGenerator) &&
1✔
392
        PerlHashUtil.processGlobalHashes(project, resolveScope, namespaceName, false, lookupGenerator);
1✔
393

394
      case PsiPerlArrayIndexVariable ignored ->
1✔
395
        PerlArrayUtil.processGlobalArrays(project, resolveScope, namespaceName, false, lookupGenerator);
1✔
396

397
      case PsiPerlHashVariable variable -> PerlHashUtil.processGlobalHashes(
1✔
398
        project, resolveScope, namespaceName, false, lookupGenerator) &&
399
                                           (!hasHashSlices(variable) ||
1✔
400
                                            PerlArrayUtil.processGlobalArrays(project, resolveScope, namespaceName, false,
1✔
401
                                                                              lookupGenerator));
402
      default -> {
403
        Processor<PerlGlobVariableElement> typeGlobProcessor = typeglob -> variableCompletionProcessor.process(
1✔
404
          processVariableLookupElement(typeglob, perlVariable instanceof PsiPerlMethod, variableCompletionProcessor));
1✔
405
        yield PerlScalarUtil.processGlobalScalars(project, resolveScope, namespaceName, false, lookupGenerator) &&
1✔
406
              PerlArrayUtil.processGlobalArrays(project, resolveScope, namespaceName, false, lookupGenerator) &&
1✔
407
              PerlHashUtil.processGlobalHashes(project, resolveScope, namespaceName, false, lookupGenerator) &&
1✔
408
              PerlGlobUtil.processGlobs(project, resolveScope, namespaceName, false, typeGlobProcessor);
1✔
409
      }
410
    };
411
  }
412

413
  public static void processVariables(@NotNull PerlVariableCompletionProcessor variableCompletionProcessor,
414
                                      @NotNull PerlTimeLogger logger) {
415
    if (!variableCompletionProcessor.isFullQualified()) {
1✔
416
      fillWithLexicalVariables(variableCompletionProcessor);
1✔
417
      logger.debug("Processed lexical variables");
1✔
418
      fillWithBuiltInVariables(variableCompletionProcessor);
1✔
419
      logger.debug("Processed built in variables");
1✔
420
      fillWithImportedVariables(variableCompletionProcessor);
1✔
421
      logger.debug("Processed imported variables");
1✔
422
    }
423

424
    processFullQualifiedVariables(variableCompletionProcessor);
1✔
425
    logger.debug("Processed full qualified variables");
1✔
426
  }
1✔
427

428
  public static void fillWithImportedVariables(@NotNull PerlVariableCompletionProcessor variableCompletionProcessor) {
429
    PerlNamespaceDefinitionElement namespaceContainer =
1✔
430
      PerlPackageUtil.getNamespaceContainerForElement(variableCompletionProcessor.getLeafElement());
1✔
431

432
    if (namespaceContainer == null) {
1✔
UNCOV
433
      return;
×
434
    }
435

436
    namespaceContainer = CompletionUtil.getOriginalOrSelf(namespaceContainer);
1✔
437

438
    String packageName = namespaceContainer.getNamespaceName();
1✔
439

440
    if (StringUtil.isEmpty(packageName)) {
1✔
UNCOV
441
      return;
×
442
    }
443

444
    PerlNamespaceEntityProcessor<PerlExportDescriptor> processor = null;
1✔
445
    PsiElement perlVariable = variableCompletionProcessor.getLeafParentElement();
1✔
446

447
    if (perlVariable instanceof PsiPerlScalarVariable) {
1✔
448
      processor = (namespaceName, descriptor) -> {
1✔
449
        LookupElementBuilder lookupElement = null;
1✔
450
        String entityName = descriptor.getImportedName();
1✔
451
        if (!variableCompletionProcessor.matches(entityName)) {
1✔
UNCOV
452
          return variableCompletionProcessor.result();
×
453
        }
454
        if (descriptor.isScalar()) {
1✔
455
          lookupElement = processVariableLookupElement(entityName, PerlVariableType.SCALAR);
1✔
456
        }
457
        else if (descriptor.isArray()) {
1✔
458
          lookupElement = processVariableLookupElement(entityName, PerlVariableType.ARRAY);
1✔
459
        }
460
        else if (descriptor.isHash()) {
1✔
461
          lookupElement = processVariableLookupElement(entityName, PerlVariableType.HASH);
1✔
462
        }
463

464
        if (lookupElement != null) {
1✔
465
          return variableCompletionProcessor.process(lookupElement.withTypeText(descriptor.getRealPackage(), true));
1✔
466
        }
467
        return variableCompletionProcessor.result();
1✔
468
      };
469
    }
470
    else if (perlVariable instanceof PsiPerlArrayVariable || perlVariable instanceof PsiPerlArrayIndexVariable) {
1✔
471
      processor = (namespaceName, descriptor) -> {
1✔
472
        LookupElementBuilder lookupElement = null;
1✔
473
        String entityName = descriptor.getImportedName();
1✔
474
        if (!variableCompletionProcessor.matches(entityName)) {
1✔
UNCOV
475
          return variableCompletionProcessor.result();
×
476
        }
477
        if (descriptor.isArray()) {
1✔
478
          lookupElement = createArrayElementLookupElement(entityName, PerlVariableType.ARRAY);
1✔
479
        }
480
        else if (descriptor.isHash()) {
1✔
481
          lookupElement = processHashElementLookupElement(entityName, PerlVariableType.HASH);
1✔
482
        }
483

484
        if (lookupElement != null) {
1✔
485
          return variableCompletionProcessor.process(lookupElement.withTypeText(descriptor.getRealPackage(), true));
1✔
486
        }
487
        return variableCompletionProcessor.result();
1✔
488
      };
489
    }
490
    else if (perlVariable instanceof PsiPerlHashVariable) {
1✔
491
      processor = (namespaceName, descriptor) -> {
1✔
492
        LookupElementBuilder lookupElement = null;
1✔
493
        if (descriptor.isHash()) {
1✔
494
          String entityName = descriptor.getImportedName();
1✔
495
          if (!variableCompletionProcessor.matches(entityName)) {
1✔
UNCOV
496
            return variableCompletionProcessor.result();
×
497
          }
498
          lookupElement = processVariableLookupElement(entityName, PerlVariableType.HASH);
1✔
499
        }
500

501
        if (lookupElement != null) {
1✔
502
          return variableCompletionProcessor.process(lookupElement.withTypeText(descriptor.getRealPackage(), true));
1✔
503
        }
504
        return variableCompletionProcessor.result();
1✔
505
      };
506
    }
507

508
    if (processor != null) {
1✔
509
      namespaceContainer.processExportDescriptors(processor);
1✔
510
    }
511
  }
1✔
512
}
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