• 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.13
/mason/htmlmason/core/src/main/java/com/perl5/lang/htmlmason/parser/psi/impl/HTMLMasonFileImpl.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.htmlmason.parser.psi.impl;
18

19
import com.intellij.openapi.project.Project;
20
import com.intellij.openapi.util.NlsSafe;
21
import com.intellij.openapi.util.text.StringUtil;
22
import com.intellij.openapi.vfs.VfsUtilCore;
23
import com.intellij.openapi.vfs.VirtualFile;
24
import com.intellij.psi.*;
25
import com.intellij.psi.scope.PsiScopeProcessor;
26
import com.intellij.psi.search.GlobalSearchScope;
27
import com.intellij.psi.stubs.StubElement;
28
import com.intellij.psi.stubs.StubIndex;
29
import com.intellij.psi.util.CachedValueProvider;
30
import com.intellij.psi.util.CachedValuesManager;
31
import com.intellij.psi.util.PsiTreeUtil;
32
import com.intellij.util.Processor;
33
import com.perl5.lang.htmlmason.HTMLMasonLanguage;
34
import com.perl5.lang.htmlmason.HTMLMasonUtil;
35
import com.perl5.lang.htmlmason.MasonCoreUtil;
36
import com.perl5.lang.htmlmason.idea.configuration.HTMLMasonSettings;
37
import com.perl5.lang.htmlmason.parser.psi.*;
38
import com.perl5.lang.htmlmason.parser.stubs.HTMLMasonFlagsStubIndex;
39
import com.perl5.lang.perl.psi.PerlCompositeElement;
40
import com.perl5.lang.perl.psi.PerlVariableDeclarationElement;
41
import com.perl5.lang.perl.psi.impl.PerlFileImpl;
42
import com.perl5.lang.perl.psi.properties.PerlLexicalScope;
43
import com.perl5.lang.perl.psi.utils.PerlPsiUtil;
44
import org.jetbrains.annotations.NotNull;
45
import org.jetbrains.annotations.Nullable;
46

47
import java.util.*;
48

49
import static com.intellij.openapi.vfs.VfsUtilCore.VFS_SEPARATOR;
50
import static com.intellij.openapi.vfs.VfsUtilCore.VFS_SEPARATOR_CHAR;
51

52
public class HTMLMasonFileImpl extends PerlFileImpl implements HTMLMasonFile {
1✔
53
  protected List<PerlVariableDeclarationElement> myImplicitVariables = null;
1✔
54
  protected int myMasonChangeCounter;
55

56
  public HTMLMasonFileImpl(@NotNull FileViewProvider viewProvider) {
57
    super(viewProvider, HTMLMasonLanguage.INSTANCE);
1✔
58
  }
1✔
59

60
  public @Nullable VirtualFile getComponentRoot() {
61
    return HTMLMasonUtil.getComponentRoot(getProject(), getComponentVirtualFile());
1✔
62
  }
63

64
  public VirtualFile getComponentVirtualFile() {
65
    return MasonCoreUtil.getContainingVirtualFile(this);
1✔
66
  }
67

68
  /**
69
   * @return absolute path relative to the components root
70
   */
71
  public @NlsSafe @Nullable String getAbsoluteComponentPath() {
72
    VirtualFile componentFile = getComponentVirtualFile();
1✔
73
    VirtualFile componentRoot = getComponentRoot();
1✔
74

75
    if (componentFile != null && componentRoot != null) {
1✔
76
      return VFS_SEPARATOR + VfsUtilCore.getRelativePath(componentFile, componentRoot);
1✔
77
    }
78
    return null;
×
79
  }
80

81
  /**
82
   * @return absolute containing dir path relative to the components root
83
   */
84
  public @NlsSafe @Nullable String getAbsoluteComponentContainerPath() {
85
    VirtualFile componentFile = getComponentVirtualFile();
×
86
    VirtualFile componentRoot = getComponentRoot();
×
87

88
    if (componentFile != null && componentRoot != null) {
×
89
      return VFS_SEPARATOR + VfsUtilCore.getRelativePath(componentFile.getParent(), componentRoot);
×
90
    }
91
    return null;
×
92
  }
93

94
  @Override
95
  public @NotNull List<PerlVariableDeclarationElement> getImplicitVariables() {
96
    HTMLMasonSettings settings = HTMLMasonSettings.getInstance(getProject());
1✔
97
    if (myImplicitVariables == null || myMasonChangeCounter != settings.getChangeCounter()) {
1✔
98
      myImplicitVariables = buildImplicitVariables(settings);
1✔
99
      myMasonChangeCounter = settings.getChangeCounter();
1✔
100
    }
101
    return myImplicitVariables;
1✔
102
  }
103

104
  protected List<PerlVariableDeclarationElement> buildImplicitVariables(HTMLMasonSettings settings) {
105
    List<PerlVariableDeclarationElement> newImplicitVariables = new ArrayList<>();
1✔
106

107
    if (isValid()) {
1✔
108
      MasonCoreUtil.fillVariablesList(this, newImplicitVariables, settings.globalVariables);
1✔
109
    }
110
    return newImplicitVariables;
1✔
111
  }
112

113
  public @Nullable HTMLMasonFileImpl getParentComponent() {
114
    String parentComponentPath = getParentComponentPath();
1✔
115
    HTMLMasonSettings settings = HTMLMasonSettings.getInstance(getProject());
1✔
116
    VirtualFile parentFile = null;
1✔
117

118
    if (parentComponentPath == null) {
1✔
119
      VirtualFile containingFile = getComponentVirtualFile();
1✔
120
      if (containingFile != null) {
1✔
121
        VirtualFile startDir = containingFile.getParent();
1✔
122
        if (StringUtil.equals(containingFile.getName(), settings.autoHandlerName)) {
1✔
123
          startDir = startDir.getParent();
1✔
124
        }
125

126
        VirtualFile componentRoot = HTMLMasonUtil.getComponentRoot(getProject(), startDir);
1✔
127
        if (componentRoot != null) {
1✔
128
          while (VfsUtilCore.isAncestor(componentRoot, startDir, false)) {
1✔
129
            if ((parentFile = startDir.findFileByRelativePath(settings.autoHandlerName)) != null) {
1✔
130
              break;
1✔
131
            }
132
            startDir = startDir.getParent();
1✔
133
          }
134
        }
135
      }
136
    }
1✔
137
    else if (!StringUtil.equals(parentComponentPath, HTMLMasonFlagsStatement.UNDEF_RESULT)) {
1✔
138
      if (StringUtil.startsWith(parentComponentPath, "/")) {
1✔
139
        parentComponentPath = parentComponentPath.substring(1);
1✔
140
        for (VirtualFile root : settings.getComponentsRoots()) {
1✔
141
          if ((parentFile = root.findFileByRelativePath(parentComponentPath)) != null) {
1✔
142
            break;
1✔
143
          }
144
        }
1✔
145
      }
146
      else {
147
        VirtualFile containingVirtualFile = getComponentVirtualFile();
1✔
148
        if (containingVirtualFile != null) {
1✔
149
          VirtualFile containingDir = containingVirtualFile.getParent();
1✔
150
          if (containingDir != null) {
1✔
151
            parentFile = containingDir.findFileByRelativePath(parentComponentPath);
1✔
152
          }
153
        }
154
      }
155
    }
156

157
    if (parentFile != null) {
1✔
158
      PsiFile file = PsiManager.getInstance(getProject()).findFile(parentFile);
1✔
159
      if (file instanceof HTMLMasonFileImpl htmlMasonFile) {
1✔
160
        return htmlMasonFile;
1✔
161
      }
162
    }
163

164
    return null;
1✔
165
  }
166

167
  public @NotNull List<HTMLMasonFileImpl> getChildComponents() {
168
    VirtualFile containingFile = getComponentVirtualFile();
1✔
169

170
    if (containingFile == null) {
1✔
171
      return Collections.emptyList();
×
172
    }
173

174
    VirtualFile componentRoot = getComponentRoot();
1✔
175

176
    if (componentRoot == null) {
1✔
177
      return Collections.emptyList();
×
178
    }
179

180
    final List<HTMLMasonFileImpl> result = new ArrayList<>();
1✔
181
    final String relativePath = VFS_SEPARATOR + VfsUtilCore.getRelativePath(containingFile, componentRoot);
1✔
182
    final Project project = getProject();
1✔
183
    final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
1✔
184
    final HTMLMasonFileImpl currentFile = this;
1✔
185
    HTMLMasonSettings settings = HTMLMasonSettings.getInstance(project);
1✔
186

187
    // indexed children
188
    for (String parentPath : StubIndex.getInstance().getAllKeys(HTMLMasonFlagsStubIndex.KEY, project)) {
1✔
189
      boolean isEquals = StringUtil.equals(relativePath, parentPath);
1✔
190
      boolean isRelative = parentPath.isEmpty() || parentPath.charAt(0) != VFS_SEPARATOR_CHAR;
1✔
191

192
      for (HTMLMasonFlagsStatement statement : StubIndex.getElements(
1✔
193
        HTMLMasonFlagsStubIndex.KEY, parentPath, project, scope, HTMLMasonFlagsStatement.class)) {
194
        PsiFile file = statement.getContainingFile();
1✔
195
        if (file instanceof HTMLMasonFileImpl htmlMasonFile &&
1✔
196
            (isEquals || isRelative && currentFile.equals(htmlMasonFile.getParentComponent()))) {
1✔
197
          result.add(htmlMasonFile);
1✔
198
        }
199
      }
1✔
200
    }
1✔
201

202
    if (StringUtil.equals(containingFile.getName(), settings.autoHandlerName)) {
1✔
203
      collectAutoHandledFiles(PsiManager.getInstance(project), containingFile.getParent(), result, settings.autoHandlerName, null);
1✔
204
    }
205

206
    return result;
1✔
207
  }
208

209
  protected void collectAutoHandledFiles(@NotNull PsiManager manager,
210
                                         @Nullable VirtualFile dir,
211
                                         @NotNull List<HTMLMasonFileImpl> result,
212
                                         @NotNull String autoHandlerName,
213
                                         @Nullable Set<VirtualFile> recursionMap) {
214
    if (dir == null) {
1✔
215
      return;
×
216
    }
217
    if (recursionMap == null) {
1✔
218
      recursionMap = new HashSet<>();
1✔
219
    }
220
    else {
221
      VirtualFile autoHandlerVirtualFile = dir.findChild(autoHandlerName);
1✔
222
      if (autoHandlerVirtualFile != null) {
1✔
223
        PsiFile autoHandlerPsiFile = manager.findFile(autoHandlerVirtualFile);
1✔
224
        if (autoHandlerPsiFile instanceof HTMLMasonFileImpl htmlMasonFile &&
1✔
225
            this.equals(htmlMasonFile.getParentComponent())) {
1✔
226
          result.add(htmlMasonFile);
1✔
227
        }
228
        return;
1✔
229
      }
230
    }
231

232
    recursionMap.add(dir);
1✔
233

234
    for (VirtualFile file : dir.getChildren()) {
1✔
235
      if (file.isDirectory() && !recursionMap.contains(file)) {
1✔
236
        collectAutoHandledFiles(manager, file, result, autoHandlerName, recursionMap);
1✔
237
      }
238
      else if (!StringUtil.equals(file.getName(), autoHandlerName)) {
1✔
239
        PsiFile psiFile = manager.findFile(file);
1✔
240
        if (psiFile instanceof HTMLMasonFileImpl htmlMasonFile && this.equals(htmlMasonFile.getParentComponent())) {
1✔
241
          result.add(htmlMasonFile);
1✔
242
        }
243
      }
244
    }
245
  }
1✔
246

247
  protected @Nullable String getParentComponentPath() {
248
    HTMLMasonFlagsStatement statement = getFlagsStatement();
1✔
249
    return statement == null ? null : statement.getParentComponentPath();
1✔
250
  }
251

252
  public @Nullable HTMLMasonFlagsStatement getFlagsStatement() {
253
    StubElement<?> stub = getStub();
1✔
254
    FlagsStatementSeeker<PsiElement> seeker;
255

256
    if (stub != null) {
1✔
257
      seeker = new FlagsStatementStubSeeker();
1✔
258
      PerlPsiUtil.processElementsFromStubs(stub, seeker, null);
1✔
259
    }
260
    else {
261
      seeker = new FlagsStatementPsiSeeker();
1✔
262
      PerlPsiUtil.processElementsFromPsi(this, seeker, null);
1✔
263
    }
264
    return seeker.getResult();
1✔
265
  }
266

267
  @Override
268
  public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
269
                                     @NotNull ResolveState state,
270
                                     PsiElement lastParent,
271
                                     @NotNull PsiElement place) {
272
    boolean checkShared = false;
1✔
273
    boolean checkArgs = false;
1✔
274
    boolean checkInit = false;
1✔
275
    boolean checkCode = false;
1✔
276
    boolean checkCleanup = false;
1✔
277

278
    PsiElement onceAnchor = null;
1✔
279
    PsiElement sharedAnchor = null;
1✔
280
    PsiElement argsAnchor = null;
1✔
281
    PsiElement initAnchor = null;
1✔
282
    PsiElement cleanupAnchor = null;
1✔
283

284
    if (lastParent instanceof HTMLMasonSharedBlockImpl) {
1✔
285
      checkShared = true;
1✔
286
      sharedAnchor = lastParent;
1✔
287
    }
288
    else if (lastParent instanceof HTMLMasonArgsBlockImpl) {
1✔
289
      checkShared = true;
1✔
290
      checkArgs = true;
1✔
291
      argsAnchor = lastParent;
1✔
292
    }
293
    else if (lastParent instanceof HTMLMasonInitBlockImpl) {
1✔
294
      checkArgs = true;
1✔
295
      checkShared = true;
1✔
296
      checkInit = true;
1✔
297
      initAnchor = lastParent;
1✔
298
    }
299
    else if (lastParent instanceof HTMLMasonFilterBlockImpl) {
1✔
300
      checkArgs = true;
1✔
301
      checkShared = true;
1✔
302
    }
303
    else if (lastParent instanceof HTMLMasonOnceBlock) {
1✔
304
      onceAnchor = lastParent;
1✔
305
    }
306
    else if (!(lastParent instanceof HTMLMasonSubcomponentDefitnitionImpl || lastParent instanceof HTMLMasonMethodDefinitionImpl)) {
1✔
307
      checkArgs = true;
1✔
308
      checkShared = true;
1✔
309
      checkInit = true;
1✔
310
      checkCode = true;
1✔
311

312
      if (lastParent instanceof HTMLMasonCleanupBlockImpl) {
1✔
313
        checkCleanup = true;
1✔
314
        cleanupAnchor = lastParent;
1✔
315
        lastParent = null;
1✔
316
      }
317
    }
318

319
    if (checkCode) {
1✔
320
      if (!processChildren(this, processor, state, lastParent, place)) {
1✔
321
        return false;
1✔
322
      }
323
    }
324
    if (checkCleanup) {
1✔
325
      if (!checkSubblocks(processor, state, place, HTMLMasonCleanupBlock.class, cleanupAnchor)) {
1✔
326
        return false;
1✔
327
      }
328
    }
329
    if (checkInit) {
1✔
330
      if (!checkSubblocks(processor, state, place, HTMLMasonInitBlock.class, initAnchor)) {
1✔
331
        return false;
1✔
332
      }
333
    }
334
    if (checkArgs) {
1✔
335
      if (!checkSubblocks(processor, state, place, HTMLMasonArgsBlock.class, argsAnchor)) {
1✔
336
        return false;
1✔
337
      }
338
    }
339
    if (checkShared) {
1✔
340
      if (!checkSubblocks(processor, state, place, HTMLMasonSharedBlock.class, sharedAnchor)) {
1✔
341
        return false;
1✔
342
      }
343
    }
344

345
    if (!checkSubblocks(processor, state, place, HTMLMasonOnceBlock.class, onceAnchor)) {
1✔
346
      return false;
1✔
347
    }
348

349
    // implicit variables
350
    for (PerlVariableDeclarationElement wrapper : getImplicitVariables()) {
1✔
351
      if (!processor.execute(wrapper, state)) {
1✔
352
        return false;
1✔
353
      }
354
    }
1✔
355

356
    return false;
1✔
357
  }
358

359
  @SuppressWarnings("Duplicates")
360
  protected boolean checkSubblocks(
361
    @NotNull PsiScopeProcessor processor,
362
    @NotNull ResolveState state,
363
    @NotNull PsiElement place,
364
    @NotNull Class<? extends HTMLMasonCompositeElement> clazz,
365
    @Nullable PsiElement anchor
366
  ) {
367
    List<HTMLMasonCompositeElement> elements = getBlocksMap().get(clazz);
1✔
368

369
    for (int i = elements.size() - 1; i >= 0; i--) {
1✔
370
      HTMLMasonCompositeElement element = elements.get(i);
1✔
371
      if (anchor == null && !element.processDeclarationsForReal(processor, state, null, place)) {
1✔
372
        return false;
1✔
373
      }
374
      else if (anchor != null && anchor.equals(element)) {
1✔
375
        anchor = null;
1✔
376
      }
377
    }
378

379
    return true;
1✔
380
  }
381

382
  public List<HTMLMasonCompositeElement> getSubComponentsDefinitions() {
383
    return getBlocksMap().get(HTMLMasonSubcomponentDefitnition.class);
1✔
384
  }
385

386
  /**
387
   * Recursively looking for method in child components
388
   *
389
   * @param name method name
390
   * @return list of child components
391
   */
392
  public @NotNull List<HTMLMasonMethodDefinition> findMethodDefinitionByNameInChildComponents(String name) {
393
    List<HTMLMasonMethodDefinition> result = new ArrayList<>();
1✔
394
    Set<HTMLMasonFileImpl> recursionSet = new HashSet<>();
1✔
395

396
    collectMethodDefinitionByNameInChildComponents(name, result, recursionSet);
1✔
397

398
    return result;
1✔
399
  }
400

401
  protected void collectMethodDefinitionByNameInChildComponents(String name,
402
                                                                List<HTMLMasonMethodDefinition> result,
403
                                                                Set<HTMLMasonFileImpl> recursionSet) {
404
    for (HTMLMasonFileImpl childComponent : getChildComponents()) {
1✔
405
      if (!recursionSet.contains(childComponent)) {
1✔
406
        recursionSet.add(childComponent);
1✔
407
        HTMLMasonMethodDefinition methodDefinition = childComponent.getMethodDefinitionByName(name);
1✔
408
        if (methodDefinition != null) {
1✔
409
          result.add(methodDefinition);
1✔
410
        }
411
        else {
412
          childComponent.collectMethodDefinitionByNameInChildComponents(name, result, recursionSet);
×
413
        }
414
      }
415
    }
1✔
416
  }
1✔
417

418
  /**
419
   * Recursively looking for method in parent components
420
   *
421
   * @param name method name
422
   * @return method definition or null
423
   */
424
  public @Nullable HTMLMasonMethodDefinition findMethodDefinitionByNameInParents(String name) {
425
    HTMLMasonFileImpl parentComponent = getParentComponent();
1✔
426
    return parentComponent == null ? null : parentComponent.findMethodDefinitionByNameInThisOrParents(name);
1✔
427
  }
428

429
  /**
430
   * Recursively looking for method in current or parent components
431
   *
432
   * @param name method name
433
   * @return method definition or null
434
   */
435
  public @Nullable HTMLMasonMethodDefinition findMethodDefinitionByNameInThisOrParents(String name) {
436
    HTMLMasonMethodDefinitionSeeker seeker = new HTMLMasonMethodDefinitionSeeker(name);
1✔
437
    processMethodDefinitionsInThisOrParents(seeker);
1✔
438
    return seeker.getResult();
1✔
439
  }
440

441
  @SuppressWarnings("UnusedReturnValue")
442
  public boolean processMethodDefinitionsInThisOrParents(Processor<HTMLMasonMethodDefinition> processor) {
443
    return processMethodDefinitionsInThisOrParents(processor, new HashSet<>());
1✔
444
  }
445

446
  protected boolean processMethodDefinitionsInThisOrParents(Processor<HTMLMasonMethodDefinition> processor,
447
                                                            Set<HTMLMasonFileImpl> recursionSet) {
448
    if (recursionSet.contains(this)) {
1✔
UNCOV
449
      return false;
×
450
    }
451
    recursionSet.add(this);
1✔
452

453
    if (!processMethodDefinitions(processor)) {
1✔
454
      return false;
1✔
455
    }
456

UNCOV
457
    HTMLMasonFileImpl parentComponent = getParentComponent();
×
458

UNCOV
459
    return parentComponent != null && parentComponent.processMethodDefinitionsInThisOrParents(processor, recursionSet);
×
460
  }
461

462
  public @Nullable HTMLMasonMethodDefinition getMethodDefinitionByName(String name) {
463
    HTMLMasonMethodDefinitionSeeker seeker = new HTMLMasonMethodDefinitionSeeker(name);
1✔
464
    processMethodDefinitions(seeker);
1✔
465
    return seeker.getResult();
1✔
466
  }
467

468
  protected boolean processMethodDefinitions(Processor<HTMLMasonMethodDefinition> processor) {
469
    for (HTMLMasonCompositeElement methodDefinition : getMethodsDefinitions()) {
1✔
470
      assert methodDefinition instanceof HTMLMasonMethodDefinition : "got " + methodDefinition + " instead of method definition";
1✔
471
      if (!processor.process((HTMLMasonMethodDefinition)methodDefinition)) {
1✔
472
        return false;
1✔
473
      }
474
    }
×
UNCOV
475
    return true;
×
476
  }
477

478
  public List<HTMLMasonCompositeElement> getMethodsDefinitions() {
479
    StubElement<?> parentStub = getStub();
1✔
480
    if (parentStub != null) {
1✔
481
      final List<HTMLMasonCompositeElement> result = new ArrayList<>();
1✔
482
      PerlPsiUtil.processElementsFromStubs(parentStub, psi ->
1✔
483
      {
484
        if (psi instanceof HTMLMasonMethodDefinition methodDefinition) {
1✔
485
          result.add(methodDefinition);
1✔
486
        }
487
        return true;
1✔
488
      }, null);
489

490
      return result;
1✔
491
    }
UNCOV
492
    return getBlocksMap().get(HTMLMasonMethodDefinition.class);
×
493
  }
494

495
  @Override
496
  public @NotNull List<HTMLMasonCompositeElement> getArgsBlocks() {
497
    StubElement<?> rootStub = getStub();
1✔
498

499
    //noinspection Duplicates in HTMLMasonStubBasedNamedElementImpl
500
    if (rootStub != null) {
1✔
501
      final List<HTMLMasonCompositeElement> result = new ArrayList<>();
1✔
502

503
      PerlPsiUtil.processElementsFromStubs(
1✔
504
        rootStub,
505
        psi ->
506
        {
507
          if (psi instanceof HTMLMasonArgsBlock argsBlock) {
1✔
UNCOV
508
            result.add(argsBlock);
×
509
          }
510
          return true;
1✔
511
        },
512
        HTMLMasonNamedElement.class
513
      );
514
      return result;
1✔
515
    }
516

517
    return getBlocksMap().get(HTMLMasonArgsBlock.class);
1✔
518
  }
519

520
  @Override
521
  public byte @Nullable [] getPerlContentInBytes() {
UNCOV
522
    return null;
×
523
  }
524

525
  private Map<Class<? extends HTMLMasonCompositeElement>, List<HTMLMasonCompositeElement>> getBlocksMap() {
526
    return CachedValuesManager.getCachedValue(this, () ->
1✔
527
    {
528
      Map<Class<? extends HTMLMasonCompositeElement>, List<HTMLMasonCompositeElement>> result = new HashMap<>();
1✔
529

530
      final List<HTMLMasonCompositeElement> cleanupResult = new ArrayList<>();
1✔
531
      final List<HTMLMasonCompositeElement> initResult = new ArrayList<>();
1✔
532
      final List<HTMLMasonCompositeElement> argsResult = new ArrayList<>();
1✔
533
      final List<HTMLMasonCompositeElement> sharedResult = new ArrayList<>();
1✔
534
      final List<HTMLMasonCompositeElement> onceResult = new ArrayList<>();
1✔
535
      final List<HTMLMasonCompositeElement> methodsResult = new ArrayList<>();
1✔
536
      final List<HTMLMasonCompositeElement> subComponentsResult = new ArrayList<>();
1✔
537

538
      result.put(HTMLMasonOnceBlock.class, onceResult);
1✔
539
      result.put(HTMLMasonSharedBlock.class, sharedResult);
1✔
540
      result.put(HTMLMasonInitBlock.class, initResult);
1✔
541
      result.put(HTMLMasonArgsBlock.class, argsResult);
1✔
542
      result.put(HTMLMasonCleanupBlock.class, cleanupResult);
1✔
543
      result.put(HTMLMasonMethodDefinition.class, methodsResult);
1✔
544
      result.put(HTMLMasonSubcomponentDefitnition.class, subComponentsResult);
1✔
545

546
      PsiTreeUtil.processElements(HTMLMasonFileImpl.this, element ->
1✔
547
      {
548
        switch (element) {
1✔
549
          case HTMLMasonOnceBlock block -> onceResult.add(block);
1✔
550
          case HTMLMasonSharedBlock block -> sharedResult.add(block);
1✔
551
          case HTMLMasonCleanupBlock block -> cleanupResult.add(block);
1✔
552
          case HTMLMasonInitBlock block
1✔
553
            when HTMLMasonFileImpl.this.equals(PsiTreeUtil.getParentOfType(element, HTMLMasonArgsContainer.class)) -> initResult.add(block);
1✔
554
          case HTMLMasonArgsBlock block
1✔
555
            when HTMLMasonFileImpl.this.equals(PsiTreeUtil.getParentOfType(element, HTMLMasonArgsContainer.class)) -> argsResult.add(block);
1✔
556
          case HTMLMasonMethodDefinition definition -> methodsResult.add(definition);
1✔
557
          case HTMLMasonSubcomponentDefitnition defitnition -> subComponentsResult.add(defitnition);
1✔
558
          default -> {
559
          }
1✔
560
        }
561

562
        return true;
1✔
563
      });
564

565
      return CachedValueProvider.Result.create(result, HTMLMasonFileImpl.this);
1✔
566
    });
567
  }
568

569
  public static boolean processChildren(@NotNull PsiElement element,
570
                                        @NotNull PsiScopeProcessor processor,
571
                                        @NotNull ResolveState resolveState,
572
                                        @Nullable PsiElement lastParent,
573
                                        @NotNull PsiElement place) {
574
    PsiElement run = lastParent == null ? element.getLastChild() : lastParent.getPrevSibling();
1✔
575
    while (run != null) {
1✔
576
      if (run instanceof PerlCompositeElement &&
1✔
577
          !(run instanceof PerlLexicalScope) &&
578
          !run.processDeclarations(processor, resolveState, null, place)
1✔
579
      ) {
580
        return false;
1✔
581
      }
582
      run = run.getPrevSibling();
1✔
583
    }
584

585
    return true;
1✔
586
  }
587

588
  protected abstract static class FlagsStatementSeeker<T> implements Processor<T> {
1✔
589
    protected HTMLMasonFlagsStatement myResult = null;
1✔
590

591
    public HTMLMasonFlagsStatement getResult() {
592
      return myResult;
1✔
593
    }
594
  }
595

596
  protected static class FlagsStatementStubSeeker extends FlagsStatementSeeker<PsiElement> {
1✔
597
    @Override
598
    public boolean process(PsiElement psi) {
599
      if (psi instanceof HTMLMasonFlagsStatement flagsStatement) {
1✔
600
        myResult = flagsStatement;
1✔
601
        return false;
1✔
602
      }
UNCOV
603
      return true;
×
604
    }
605
  }
606

607
  protected static class FlagsStatementPsiSeeker extends FlagsStatementSeeker<PsiElement> {
1✔
608
    @Override
609
    public boolean process(PsiElement element) {
610
      if (element instanceof HTMLMasonFlagsStatement flagsStatement) {
1✔
611
        myResult = flagsStatement;
1✔
612
        return false;
1✔
613
      }
614
      return true;
1✔
615
    }
616
  }
617

618
  protected static class HTMLMasonMethodDefinitionSeeker implements Processor<HTMLMasonMethodDefinition> {
619
    private final String myName;
620
    private HTMLMasonMethodDefinition myResult;
621

622
    public HTMLMasonMethodDefinitionSeeker(String myName) {
1✔
623
      this.myName = myName;
1✔
624
    }
1✔
625

626
    @Override
627
    public boolean process(HTMLMasonMethodDefinition htmlMasonMethodDefinition) {
628
      if (StringUtil.equals(myName, htmlMasonMethodDefinition.getName())) {
1✔
629
        myResult = htmlMasonMethodDefinition;
1✔
630
        return false;
1✔
631
      }
UNCOV
632
      return true;
×
633
    }
634

635
    public HTMLMasonMethodDefinition getResult() {
636
      return myResult;
1✔
637
    }
638
  }
639
}
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