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

Camelcade / Perl5-IDEA / #525521824

24 Apr 2026 06:38PM UTC coverage: 76.187% (+0.2%) from 75.952%
#525521824

push

github

hurricup
Pass a disposable to Registry.get to revert it in the end

14757 of 22542 branches covered (65.46%)

Branch coverage included in aggregate %.

31096 of 37643 relevant lines covered (82.61%)

0.83 hits per line

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

79.0
/plugin/common/src/main/java/com/perl5/lang/perl/psi/utils/PerlElementFactory.java
1
/*
2
 * Copyright 2015-2026 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.fileTypes.FileType;
20
import com.intellij.openapi.project.Project;
21
import com.intellij.psi.PsiElement;
22
import com.intellij.psi.PsiFileFactory;
23
import com.intellij.psi.tree.IElementType;
24
import com.intellij.psi.util.PsiTreeUtil;
25
import com.intellij.psi.util.PsiUtilCore;
26
import com.perl5.lang.perl.fileTypes.PerlFileTypePackage;
27
import com.perl5.lang.perl.psi.*;
28
import com.perl5.lang.perl.psi.impl.PerlFileImpl;
29
import com.perl5.lang.perl.psi.impl.PerlHeredocElementImpl;
30
import com.perl5.lang.perl.psi.impl.PerlUseStatementElement;
31
import org.jetbrains.annotations.Contract;
32
import org.jetbrains.annotations.NotNull;
33
import org.jetbrains.annotations.Nullable;
34

35
import java.util.List;
36
import java.util.Objects;
37

38
import static com.perl5.lang.perl.parser.PerlElementTypesGenerated.HEREDOC;
39
import static com.perl5.lang.perl.parser.PerlElementTypesGenerated.HEREDOC_QQ;
40

41
public final class PerlElementFactory {
1✔
42
  public static PsiElement createNewLine(Project project) {
43
    PerlFileImpl file = createFile(project, "\n");
1✔
44
    return file.getFirstChild();
1✔
45
  }
46

47

48
  @Contract(pure = true)
49
  public static @NotNull PsiPerlDerefExpr createMethodCall(@NotNull Project project,
50
                                                           @NotNull String packageName,
51
                                                           @NotNull String subName,
52
                                                           @NotNull String arguments) {
53
    PerlFileImpl file = createFile(project, String.format("%s->%s%s;", packageName, subName, arguments));
1✔
54
    return Objects.requireNonNull(PsiTreeUtil.findChildOfType(file, PsiPerlDerefExpr.class));
1!
55
  }
56

57
  public static PerlUseStatementElement createUseStatement(Project project, String packageName) {
58
    assert packageName != null;
1!
59

60
    PerlFileImpl file = createFile(project, String.format("use %s;", packageName));
1✔
61
    PerlUseStatementElement def = PsiTreeUtil.findChildOfType(file, PerlUseStatementElement.class);
1✔
62
    assert def != null;
1!
63
    return def;
1✔
64
  }
65

66
  /**
67
   * @return a statement psi element created from {@code statementText} or null if something went wrong, statement could not be created
68
   */
69
  public static @Nullable PsiElement createStatement(@NotNull Project project, @NotNull String statementText) {
70
    PerlFileImpl perlFile = createFile(project, statementText + ";");
1✔
71
    PsiElement[] children = perlFile.getChildren();
1✔
72
    return children.length == 0 ? null : children[0];
1!
73
  }
74

75
  /**
76
   * Create a replacement heredoc element with new text
77
   *
78
   * @param originalElement element to replace
79
   * @param newText         new element text
80
   * @return new generated element
81
   */
82
  public static @NotNull PerlHeredocElementImpl createHeredocBodyReplacement(@NotNull PerlHeredocElementImpl originalElement,
83
                                                                             @NotNull String newText) {
84
    StringBuilder sb = new StringBuilder("<<");
1✔
85
    String marker = getSafeHeredocMarker(newText);
1✔
86
    IElementType originalElementType = PsiUtilCore.getElementType(originalElement);
1✔
87
    char quote;
88
    if (originalElementType == HEREDOC) {
1!
89
      quote = '\'';
×
90
    }
91
    else if (originalElementType == HEREDOC_QQ) {
1✔
92
      quote = '"';
1✔
93
    }
94
    else {
95
      quote = '`';
1✔
96
    }
97
    sb.append(quote).append(marker).append(quote).append(";\n").append(newText);
1✔
98
    if (!newText.endsWith("\n")) {
1!
99
      sb.append("\n");
×
100
    }
101

102
    PerlFileImpl newFile = createFile(originalElement.getProject(), sb.append(marker).toString());
1✔
103
    PerlHeredocElementImpl newElement = newFile.findChildByClass(originalElement.getClass());
1✔
104
    assert newElement != null : "Can't find element " + originalElement.getClass() + " generated with: \n" + sb;
1!
105
    return newElement;
1!
106
  }
107

108
  /**
109
   * @param heredocBody text of here-doc body
110
   * @return safe marker to use with this body
111
   */
112
  private static String getSafeHeredocMarker(@NotNull String heredocBody) {
113
    String marker = "EOM";
1✔
114
    while (marker.equals(heredocBody) ||
1!
115
           heredocBody.startsWith(marker + "\n") ||
1!
116
           heredocBody.endsWith(marker + "\n") ||
1!
117
           heredocBody.contains("\n" + marker + "\n")
1!
118
    ) {
119
      //noinspection StringConcatenationInLoop
120
      marker = marker + "M";
×
121
    }
122
    return marker;
1✔
123
  }
124

125
  public static List<PsiElement> createHereDocElements(Project project, char quoteSymbol, String markerText, String contentText) {
126
    PerlFileImpl file = createFile(project,
1✔
127
                                   String.format("<<%c%s%c\n%s\n%s\n;", quoteSymbol, markerText, quoteSymbol, contentText, markerText)
1✔
128
    );
129

130
    PsiElement heredocOpener = PsiTreeUtil.findChildOfType(file, PsiPerlHeredocOpener.class);
1✔
131
    @SuppressWarnings("ConstantConditions") PsiElement headingNewLine = heredocOpener.getNextSibling();
1✔
132
    PsiElement tailingNewLine = headingNewLine.getNextSibling().getNextSibling().getNextSibling();
1✔
133

134
    return List.of(heredocOpener, headingNewLine, tailingNewLine);
1✔
135
  }
136

137
  public static PerlString createBareString(Project project, String content) {
138
    PerlFileImpl file = createFile(project, content + " => 42;");
1✔
139
    PerlString string = PsiTreeUtil.findChildOfType(file, PerlString.class);
1✔
140
    assert string != null : "While creating bare string from: " + content;
1!
141
    return string;
1✔
142
  }
143

144
  public static PerlString createString(Project project, String code) {
145
    PerlFileImpl file = createFile(project, code + ";");
1✔
146
    PerlString string = PsiTreeUtil.findChildOfType(file, PerlString.class);
1✔
147
    assert string != null : "While creating string from: " + code;
1!
148
    return string;
1✔
149
  }
150

151
  public static PsiElement createDereference(Project project) {
152
    PerlFileImpl file = createFile(project, "$a->{bla};");
1✔
153
    PerlVariable variable = PsiTreeUtil.findChildOfType(file, PerlVariable.class);
1✔
154
    assert variable != null : "While creating dereference";
1!
155
    return variable.getNextSibling();
1✔
156
  }
157

158
  public static PsiPerlParenthesisedExpr createParenthesisedExpression(Project project) {
159
    PerlFileImpl file = createFile(project, "();");
1✔
160
    PsiPerlParenthesisedExpr result = PsiTreeUtil.findChildOfType(file, PsiPerlParenthesisedExpr.class);
1✔
161
    assert result != null : "While creating PsiPerlParenthesisedExpr";
1!
162
    return result;
1✔
163
  }
164

165
  public static @NotNull PsiElement createSpace(@NotNull Project project) {
166
    return Objects.requireNonNull(createFile(project, " ").getFirstChild());
1!
167
  }
168

169
  public static @NotNull PsiElement createComma(@NotNull Project project) {
170
    return Objects.requireNonNull(createFile(project, ",").getFirstChild());
1!
171
  }
172

173
  public static PerlFileImpl createFile(@NotNull Project project, @NotNull String text) {
174
    return createFile(project, text, PerlFileTypePackage.INSTANCE);
1✔
175
  }
176

177
  public static PerlFileImpl createFile(@NotNull Project project, @NotNull String text, @NotNull FileType fileType) {
178
    return (PerlFileImpl)PsiFileFactory.getInstance(project).
1✔
179
      createFileFromText("file.dummy", fileType, text);
1✔
180
  }
181
}
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