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

Camelcade / Perl5-IDEA / #525521703

09 Nov 2025 10:57AM UTC coverage: 75.97% (+0.06%) from 75.91%
#525521703

push

github

hurricup
Safer work with variable name

14772 of 22647 branches covered (65.23%)

Branch coverage included in aggregate %.

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

89 existing lines in 10 files now uncovered.

31098 of 37732 relevant lines covered (82.42%)

0.82 hits per line

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

93.69
/plugin/common/src/main/java/com/perl5/lang/perl/psi/utils/PerlSubArgumentsExtractor.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.utils;
18

19
import com.intellij.openapi.util.text.StringUtil;
20
import com.intellij.psi.PsiElement;
21
import com.intellij.psi.util.PsiTreeUtil;
22
import com.intellij.util.Processor;
23
import com.perl5.lang.perl.idea.PerlElementPatterns;
24
import com.perl5.lang.perl.psi.*;
25
import com.perl5.lang.perl.psi.impl.PsiPerlCallArgumentsImpl;
26
import com.perl5.lang.perl.util.PerlArrayUtilCore;
27
import org.jetbrains.annotations.NotNull;
28
import org.jetbrains.annotations.Nullable;
29

30
import java.util.ArrayList;
31
import java.util.List;
32

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

35
public class PerlSubArgumentsExtractor implements Processor<PsiPerlStatement> {
1✔
36
  private final List<PerlSubArgument> myArguments = new ArrayList<>();
1✔
37

38
  @Override
39
  public boolean process(PsiPerlStatement statement) {
40
    if (myArguments.isEmpty() && PerlPsiUtil.isSelfShortcutStatement(statement)) {
1✔
41
      myArguments.add(PerlSubArgument.self());
1✔
42
      return true;
1✔
43
    }
44
    else if (PerlElementPatterns.EMPTY_SHIFT_STATEMENT_PATTERN.accepts(statement)) {
1✔
45
      myArguments.add(myArguments.isEmpty() ? PerlSubArgument.self() : PerlSubArgument.empty());
1✔
46
      return true;
1✔
47
    }
48
    else if (PerlElementPatterns.DECLARATION_ASSIGNING_PATTERN.accepts(statement)) {
1✔
49
      // fixme see #2007
50
      PerlAssignExpression assignExpression = PsiTreeUtil.getChildOfType(statement, PerlAssignExpression.class);
1✔
51

52
      if (assignExpression == null) {
1!
UNCOV
53
        return false;
×
54
      }
55

56
      PsiElement leftSide = assignExpression.getLeftSide();
1✔
57
      PsiElement rightSide = assignExpression.getRightSide();
1✔
58

59
      if (rightSide == null) {
1!
UNCOV
60
        return false;
×
61
      }
62

63
      PerlVariableDeclarationExpr variableDeclaration = PsiTreeUtil.findChildOfType(leftSide, PerlVariableDeclarationExpr.class, false);
1✔
64

65
      if (variableDeclaration == null) {
1!
UNCOV
66
        return false;
×
67
      }
68

69
      String variableClass = variableDeclaration.getDeclarationType();
1✔
70
      if (variableClass == null) {
1✔
71
        variableClass = "";
1✔
72
      }
73

74
      List<PsiElement> rightSideElements = PerlArrayUtilCore.collectListElements(rightSide);
1✔
75
      int sequenceIndex = 0;
1✔
76

77
      boolean processNextStatement = true;
1✔
78
      PsiElement run = variableDeclaration.getFirstChild();
1✔
79
      while (run != null) {
1✔
80
        var nextArgument = getArgument(run, variableClass);
1✔
81

82
        if (nextArgument != null) {
1✔
83
          // we've found argument of left side
84
          if (rightSideElements.size() > sequenceIndex) {
1✔
85
            PsiElement rightSideElement = rightSideElements.get(sequenceIndex);
1✔
86
            boolean addArgument = false;
1✔
87

88
            if (PerlElementPatterns.SHIFT_PATTERN.accepts(rightSideElement)) // shift on the left side
1✔
89
            {
90
              assert rightSideElement instanceof PsiPerlArrayShiftExpr;
1!
91
              PsiPerlCallArguments callArguments = ((PsiPerlArrayShiftExpr)rightSideElement).getCallArguments();
1✔
92
              List<PsiElement> argumentsList =
93
                callArguments == null ? null : ((PsiPerlCallArgumentsImpl)callArguments).getArgumentsList();
1✔
94
              if (argumentsList == null ||
1✔
95
                  argumentsList.isEmpty() ||
1✔
96
                  PerlElementPatterns.ALL_ARGUMENTS_PATTERN.accepts(argumentsList.getFirst())) {
1✔
97
                addArgument = true;
1✔
98
                sequenceIndex++;
1✔
99
              }
100
            }
1✔
101
            else if (PerlElementPatterns.ALL_ARGUMENTS_ELEMENT_PATTERN.accepts(rightSideElement)) // $_[smth] on the left side
1✔
102
            {
103
              addArgument = true;
1✔
104
              sequenceIndex++;
1✔
105
            }
106
            else if (PerlElementPatterns.ALL_ARGUMENTS_PATTERN.accepts(rightSideElement))    // @_ on the left side
1✔
107
            {
108
              addArgument = true;
1✔
109
              processNextStatement = false;
1✔
110
            }
111

112
            if (addArgument) {
1✔
113
              myArguments.add(nextArgument);
1✔
114
            }
115
          }
116
        }
117

118
        run = run.getNextSibling();
1✔
119
      }
1✔
120

121
      return processNextStatement;
1✔
122
    }
123
    return false;
1✔
124
  }
125

126
  private @Nullable PerlSubArgument getArgument(@NotNull PsiElement run, @NotNull String variableClass) {
127
    if (run instanceof PerlVariableDeclarationElement variableDeclarationElement) {
1✔
128
      PerlVariable variable = variableDeclarationElement.getVariable();
1✔
129
      return PerlSubArgument.mandatory(
1✔
130
        variable.getActualType(),
1✔
131
        StringUtil.notNullize(variable.getName()),
1✔
132
        variableClass
133
      );
134
    }
135
    else if (run.getNode().getElementType() == UNDEF_EXPR) {
1✔
136
      return myArguments.isEmpty() ? PerlSubArgument.self() : PerlSubArgument.empty();
1✔
137
    }
138
    return null;
1✔
139
  }
140

141
  public List<PerlSubArgument> getArguments() {
142
    return myArguments;
1✔
143
  }
144
}
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