Search in sources :

Example 6 with PerlVariableDeclarationElement

use of com.perl5.lang.perl.psi.PerlVariableDeclarationElement in project Perl5-IDEA by Camelcade.

the class PerlVariableCompletionUtil method fillWithUnresolvedVars.

public static void fillWithUnresolvedVars(@NotNull PerlVariableNameElement variableNameElement, @NotNull CompletionResultSet resultSet) {
    final PerlLexicalScope lexicalScope = PsiTreeUtil.getParentOfType(variableNameElement, PerlLexicalScope.class);
    PsiElement perlVariable = variableNameElement.getParent();
    final Set<String> collectedNames = new THashSet<>();
    if (lexicalScope != null && perlVariable instanceof PerlVariable) {
        final int minOffset = variableNameElement.getTextOffset();
        final PerlVariableType actualType = ((PerlVariable) perlVariable).getActualType();
        lexicalScope.accept(new PerlRecursiveVisitor() {

            @Override
            public void visitPerlVariable(@NotNull PerlVariable perlVariable) {
                if (perlVariable.isValid() && !(perlVariable.getParent() instanceof PerlVariableDeclarationElement) && perlVariable.getTextOffset() > minOffset && actualType == perlVariable.getActualType()) {
                    String variableName = perlVariable.getName();
                    if (StringUtil.isNotEmpty(variableName) && !collectedNames.contains(variableName) && perlVariable.getLexicalDeclaration() == null) {
                        collectedNames.add(variableName);
                        resultSet.addElement(LookupElementBuilder.create(variableName));
                    }
                }
                super.visitPerlVariable(perlVariable);
            }
        });
    }
}
Also used : PerlVariableType(com.perl5.lang.perl.psi.utils.PerlVariableType) PerlLexicalScope(com.perl5.lang.perl.psi.properties.PerlLexicalScope) PsiElement(com.intellij.psi.PsiElement) THashSet(gnu.trove.THashSet)

Example 7 with PerlVariableDeclarationElement

use of com.perl5.lang.perl.psi.PerlVariableDeclarationElement in project Perl5-IDEA by Camelcade.

the class PerlXNamedValue method computeMySourcePosition.

protected boolean computeMySourcePosition(@Nullable XNavigatable navigatable, @Nullable final XInlineDebuggerDataCallback callback) {
    String name = myPerlValueDescriptor.getName();
    if (StringUtil.isEmpty(name) || name.length() < 2) {
        return false;
    }
    final PerlVariableType variableType = PerlVariableType.bySigil(name.charAt(0));
    if (variableType == null || variableType == PerlVariableType.CODE) {
        return false;
    }
    final String variableName = name.substring(1);
    final XSourcePosition sourcePosition = myStackFrame.getSourcePosition();
    if (sourcePosition == null) {
        return false;
    }
    final Project project = myStackFrame.getPerlExecutionStack().getSuspendContext().getDebugSession().getProject();
    final VirtualFile virtualFile = sourcePosition.getFile();
    PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
    if (!(psiFile instanceof PerlFileImpl)) {
        return false;
    }
    PsiElement element = psiFile.findElementAt(sourcePosition.getOffset());
    if (element == null) {
        return false;
    }
    if (navigatable != null) {
        PerlVariableDeclarationSearcher variableProcessor = new PerlVariableDeclarationSearcher(variableName, variableType, element);
        PerlResolveUtil.treeWalkUp(element, variableProcessor);
        PerlVariableDeclarationElement result = variableProcessor.getResult();
        if (result == null) {
            return false;
        }
        navigatable.setSourcePosition(XSourcePositionImpl.createByElement(result));
    } else if (callback != null) {
        final Document document = psiFile.getViewProvider().getDocument();
        if (document == null) {
            return false;
        }
        final boolean[] found = new boolean[] { false };
        PerlVariableDeclarationSearcher variableProcessor = new PerlVariableDeclarationSearcher(variableName, variableType, element) {

            @Override
            public boolean execute(@NotNull PsiElement possibleElement, @NotNull ResolveState state) {
                boolean result = super.execute(possibleElement, state);
                if (!result) {
                    registerElement(getResult());
                } else if (possibleElement instanceof PerlVariable && ((PerlVariable) possibleElement).getActualType() == variableType && StringUtil.equals(variableName, ((PerlVariable) possibleElement).getName())) {
                    registerElement(possibleElement);
                }
                return result;
            }

            private void registerElement(@Nullable PsiElement targetElement) {
                if (targetElement == null) {
                    return;
                }
                found[0] = true;
                try {
                    if (mySourcePositionMethod != null) {
                        mySourcePositionMethod.invoke(callback, XSourcePositionImpl.createByElement(targetElement));
                    } else if (myLegacyMethod != null) {
                        myLegacyMethod.invoke(callback, virtualFile, document, document.getLineNumber(targetElement.getTextOffset()));
                    } else {
                        found[0] = false;
                    }
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        };
        PerlResolveUtil.treeWalkUp(element, variableProcessor);
        return found[0];
    }
    return true;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) PerlVariableDeclarationElement(com.perl5.lang.perl.psi.PerlVariableDeclarationElement) PerlFileImpl(com.perl5.lang.perl.psi.impl.PerlFileImpl) PerlVariableType(com.perl5.lang.perl.psi.utils.PerlVariableType) PerlVariableDeclarationSearcher(com.perl5.lang.perl.psi.references.scopes.PerlVariableDeclarationSearcher) Document(com.intellij.openapi.editor.Document) InvocationTargetException(java.lang.reflect.InvocationTargetException) ResolveState(com.intellij.psi.ResolveState) Project(com.intellij.openapi.project.Project) PsiFile(com.intellij.psi.PsiFile) PerlVariable(com.perl5.lang.perl.psi.PerlVariable) XSourcePosition(com.intellij.xdebugger.XSourcePosition) PsiElement(com.intellij.psi.PsiElement)

Example 8 with PerlVariableDeclarationElement

use of com.perl5.lang.perl.psi.PerlVariableDeclarationElement in project Perl5-IDEA by Camelcade.

the class PerlStructureViewElement method getChildren.

@NotNull
@Override
public TreeElement[] getChildren() {
    List<TreeElement> result = new ArrayList<>();
    Set<String> implementedMethods = new HashSet<>();
    if (myElement instanceof PerlFile) {
        FileViewProvider viewProvider = ((PerlFile) myElement).getViewProvider();
        PsiFile podFile = viewProvider.getPsi(PodLanguage.INSTANCE);
        if (podFile != null && podFile.getChildren().length > 1) {
            result.add(new PodStructureViewElement(podFile));
        }
        Language targetLanguage = null;
        for (Language language : viewProvider.getLanguages()) {
            if (language == PerlLanguage.INSTANCE) {
                targetLanguage = language;
                break;
            } else if (targetLanguage == null && language.isKindOf(PerlLanguage.INSTANCE)) {
                targetLanguage = language;
            }
        }
        if (targetLanguage != null) {
            viewProvider.getPsi(targetLanguage).accept(new PerlRecursiveVisitor() {

                @Override
                public void visitNamespaceDefinitionElement(@NotNull PerlNamespaceDefinitionElement o) {
                    result.add(new PerlNamespaceStructureViewElement(o));
                    super.visitNamespaceDefinitionElement(o);
                }
            });
        }
    }
    if (myElement instanceof PerlNamespaceDefinitionElement) {
        // global variables
        for (PerlVariableDeclarationElement child : PsiTreeUtil.findChildrenOfType(myElement, PerlVariableDeclarationElement.class)) {
            if (child.isGlobalDeclaration() && myElement.isEquivalentTo(PerlPackageUtil.getNamespaceContainerForElement(child))) {
                result.add(new PerlVariableDeclarationStructureViewElement(child));
            }
        }
        Project project = myElement.getProject();
        GlobalSearchScope projectScope = GlobalSearchScope.projectScope(project);
        // imported scalars
        for (PerlExportDescriptor exportDescritptor : ((PerlNamespaceDefinitionElement) myElement).getImportedScalarDescriptors()) {
            String canonicalName = exportDescritptor.getTargetCanonicalName();
            Collection<PerlVariableDeclarationElement> variables = PerlScalarUtil.getGlobalScalarDefinitions(project, canonicalName);
            for (PerlVariableDeclarationElement variable : variables) {
                result.add(new PerlVariableDeclarationStructureViewElement(variable).setImported(exportDescritptor));
            }
            // globs
            Collection<PsiPerlGlobVariable> items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName, projectScope);
            if (items.isEmpty()) {
                items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName);
            }
            for (PerlGlobVariable item : items) {
                result.add(new PerlGlobStructureViewElement(item).setImported(exportDescritptor));
            }
        }
        // imported arrays
        for (PerlExportDescriptor exportDescritptor : ((PerlNamespaceDefinitionElement) myElement).getImportedArrayDescriptors()) {
            String canonicalName = exportDescritptor.getTargetCanonicalName();
            Collection<PerlVariableDeclarationElement> variables = PerlArrayUtil.getGlobalArrayDefinitions(project, canonicalName);
            for (PerlVariableDeclarationElement variable : variables) {
                result.add(new PerlVariableDeclarationStructureViewElement(variable).setImported(exportDescritptor));
            }
            // globs
            Collection<PsiPerlGlobVariable> items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName, projectScope);
            if (items.isEmpty()) {
                items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName);
            }
            for (PerlGlobVariable item : items) {
                result.add(new PerlGlobStructureViewElement(item).setImported(exportDescritptor));
            }
        }
        // imported hashes
        for (PerlExportDescriptor exportDescritptor : ((PerlNamespaceDefinitionElement) myElement).getImportedHashDescriptors()) {
            String canonicalName = exportDescritptor.getTargetCanonicalName();
            Collection<PerlVariableDeclarationElement> variables = PerlHashUtil.getGlobalHashDefinitions(project, canonicalName);
            for (PerlVariableDeclarationElement variable : variables) {
                result.add(new PerlVariableDeclarationStructureViewElement(variable).setImported(exportDescritptor));
            }
            // globs
            Collection<PsiPerlGlobVariable> items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName, projectScope);
            if (items.isEmpty()) {
                items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName);
            }
            for (PerlGlobVariable item : items) {
                result.add(new PerlGlobStructureViewElement(item).setImported(exportDescritptor));
            }
        }
        // Imported subs
        for (PerlExportDescriptor exportDescritptor : ((PerlNamespaceDefinitionElement) myElement).getImportedSubsDescriptors()) {
            String canonicalName = exportDescritptor.getTargetCanonicalName();
            // declarations
            Collection<PerlSubDeclarationElement> subDeclarations = PerlSubUtil.getSubDeclarations(project, canonicalName, projectScope);
            if (subDeclarations.isEmpty()) {
                subDeclarations = PerlSubUtil.getSubDeclarations(project, canonicalName);
            }
            for (PerlSubDeclarationElement item : subDeclarations) {
                result.add(new PerlSubStructureViewElement(item).setImported(exportDescritptor));
            }
            // definitions
            Collection<PerlSubDefinitionElement> subDefinitions = PerlSubUtil.getSubDefinitions(project, canonicalName, projectScope);
            if (subDefinitions.isEmpty()) {
                subDefinitions = PerlSubUtil.getSubDefinitions(project, canonicalName);
            }
            for (PerlSubDefinitionElement item : subDefinitions) {
                result.add(new PerlSubStructureViewElement(item).setImported(exportDescritptor));
            }
            // globs
            Collection<PsiPerlGlobVariable> items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName, projectScope);
            if (items.isEmpty()) {
                items = PerlGlobUtil.getGlobsDefinitions(project, canonicalName);
            }
            for (PerlGlobVariable item : items) {
                result.add(new PerlGlobStructureViewElement(item).setImported(exportDescritptor));
            }
        }
        myElement.accept(new PerlRecursiveVisitor() {

            @Override
            public void visitPerlSubDefinitionElement(@NotNull PerlSubDefinitionElement child) {
                if (myElement.isEquivalentTo(PerlPackageUtil.getNamespaceContainerForElement(child))) {
                    implementedMethods.add(child.getName());
                    result.add(new PerlSubStructureViewElement(child));
                }
                super.visitPerlSubDefinitionElement(child);
            }

            @Override
            public void visitSubDeclarationElement(@NotNull PerlSubDeclarationElement child) {
                if (myElement.isEquivalentTo(PerlPackageUtil.getNamespaceContainerForElement(child))) {
                    result.add(new PerlSubStructureViewElement(child));
                }
                super.visitSubDeclarationElement(child);
            }

            @Override
            public void visitGlobVariable(@NotNull PsiPerlGlobVariable child) {
                if (child.isLeftSideOfAssignment() && myElement.isEquivalentTo(PerlPackageUtil.getNamespaceContainerForElement(child))) {
                    implementedMethods.add(child.getName());
                    result.add(new PerlGlobStructureViewElement(child));
                }
                super.visitGlobVariable(child);
            }
        });
    }
    // inherited elements
    if (myElement instanceof PerlNamespaceDefinitionWithIdentifier) {
        List<TreeElement> inheritedResult = new ArrayList<>();
        String packageName = ((PerlNamespaceDefinitionElement) myElement).getPackageName();
        if (packageName != null) {
            for (PsiElement element : PerlMro.getVariants(myElement, packageName, true)) {
                if (element instanceof PerlIdentifierOwner && !implementedMethods.contains(((PerlIdentifierOwner) element).getName())) {
                    if (element instanceof PerlLightConstantDefinitionElement) {
                        inheritedResult.add(new PerlSubStructureViewElement((PerlSubDefinitionElement) element).setInherited());
                    } else if (element instanceof PerlSubDefinitionElement) {
                        inheritedResult.add(new PerlSubStructureViewElement((PerlSubDefinitionElement) element).setInherited());
                    } else if (element instanceof PerlSubDeclarationElement) {
                        inheritedResult.add(new PerlSubStructureViewElement((PerlSubDeclarationElement) element).setInherited());
                    } else if (element instanceof PerlGlobVariable && ((PerlGlobVariable) element).isLeftSideOfAssignment() && ((PerlGlobVariable) element).getName() != null) {
                        inheritedResult.add(new PerlGlobStructureViewElement((PerlGlobVariable) element).setInherited());
                    }
                }
            }
        }
        if (!inheritedResult.isEmpty()) {
            result.addAll(0, inheritedResult);
        }
    }
    return result.toArray(new TreeElement[result.size()]);
}
Also used : PerlExportDescriptor(com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor) FileViewProvider(com.intellij.psi.FileViewProvider) Language(com.intellij.lang.Language) PerlLanguage(com.perl5.lang.perl.PerlLanguage) PodLanguage(com.perl5.lang.pod.PodLanguage) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) PsiFile(com.intellij.psi.PsiFile) PsiElement(com.intellij.psi.PsiElement) TreeElement(com.intellij.ide.util.treeView.smartTree.TreeElement) StructureViewTreeElement(com.intellij.ide.structureView.StructureViewTreeElement) SortableTreeElement(com.intellij.ide.util.treeView.smartTree.SortableTreeElement) Project(com.intellij.openapi.project.Project) PerlLightConstantDefinitionElement(com.perl5.lang.perl.parser.constant.psi.light.PerlLightConstantDefinitionElement) PodStructureViewElement(com.perl5.lang.pod.idea.structureView.PodStructureViewElement) PerlIdentifierOwner(com.perl5.lang.perl.psi.properties.PerlIdentifierOwner) NotNull(org.jetbrains.annotations.NotNull)

Example 9 with PerlVariableDeclarationElement

use of com.perl5.lang.perl.psi.PerlVariableDeclarationElement in project Perl5-IDEA by Camelcade.

the class PerlVariableMixin method getVariableTypeHeavy.

@Nullable
private String getVariableTypeHeavy() {
    if (this instanceof PsiPerlScalarVariable) {
        // System.err.println("Guessing type for " + getText() + " at " + getTextOffset());
        PerlVariableNameElement variableNameElement = getVariableNameElement();
        if (variableNameElement != null) {
            // find lexicaly visible declaration and check type
            final PerlVariableDeclarationElement declarationWrapper = getLexicalDeclaration();
            if (declarationWrapper != null) {
                if (declarationWrapper instanceof PerlImplicitVariableDeclaration) {
                    return ((PerlImplicitVariableDeclaration) declarationWrapper).getVariableClass();
                }
                if (declarationWrapper.isInvocantDeclaration() || declarationWrapper.isSelf()) {
                    PerlSelfHinter selfHinter = PsiTreeUtil.getParentOfType(declarationWrapper, PerlSelfHinter.class);
                    if (selfHinter != null) {
                        return selfHinter.getSelfNamespace();
                    }
                    return PerlPackageUtil.getContextPackageName(declarationWrapper);
                }
                // check explicit type in declaration
                String declarationPackageName = declarationWrapper.getDeclaredType();
                if (declarationPackageName != null) {
                    assert !declarationPackageName.equals("");
                    return declarationPackageName;
                }
                // check assignment around declaration
                PerlVariableDeclarationExpr declaration = PsiTreeUtil.getParentOfType(declarationWrapper, PerlVariableDeclarationExpr.class);
                if (declaration != null) {
                    if (declaration.getParent() instanceof PsiPerlAssignExpr) {
                        PsiPerlAssignExpr assignmentExpression = (PsiPerlAssignExpr) declaration.getParent();
                        List<PsiPerlExpr> assignmentElements = assignmentExpression.getExprList();
                        if (!assignmentElements.isEmpty()) {
                            PsiPerlExpr lastExpression = assignmentElements.get(assignmentElements.size() - 1);
                            if (lastExpression != declaration) {
                                // source element is on the left side
                                if (lastExpression instanceof PerlMethodContainer) {
                                    return PerlSubUtil.getMethodReturnValue((PerlMethodContainer) lastExpression);
                                }
                                if (lastExpression instanceof PerlDerefExpression) {
                                    return ((PerlDerefExpression) lastExpression).guessType();
                                }
                            }
                        }
                    }
                }
                // fixme this is bad, because my $var1 && print $var1 will be valid, but it's not
                PerlLexicalScope perlLexicalScope = PsiTreeUtil.getParentOfType(declarationWrapper, PerlLexicalScope.class);
                assert perlLexicalScope != null : "Unable to find lexical scope for:" + declarationWrapper.getClass() + " at " + declarationWrapper.getTextOffset() + " in " + declarationWrapper.getContainingFile();
                final String[] guessResult = new String[] { null };
                int startOffset = declarationWrapper.getTextRange().getEndOffset();
                int endOffset = getTextRange().getStartOffset();
                if (startOffset < endOffset) {
                    PerlPsiUtil.processElementsInRange(perlLexicalScope, new TextRange(startOffset, endOffset), element -> {
                        if (element != PerlVariableMixin.this && element instanceof PsiPerlScalarVariable && element.getParent() instanceof PsiPerlAssignExpr) {
                            PsiElement variableNameElement1 = ((PsiPerlScalarVariable) element).getVariableNameElement();
                            if (variableNameElement1 != null && variableNameElement1.getReference() != null && variableNameElement1.getReference().isReferenceTo(declarationWrapper)) {
                                // found variable assignment
                                PsiPerlAssignExpr assignmentExpression = (PsiPerlAssignExpr) element.getParent();
                                List<PsiPerlExpr> assignmentElements = assignmentExpression.getExprList();
                                if (!assignmentElements.isEmpty()) {
                                    PsiPerlExpr lastExpression = assignmentElements.get(assignmentElements.size() - 1);
                                    if (lastExpression != element && lastExpression.getTextOffset() < getTextOffset()) {
                                        // source element is on the left side
                                        // fixme implement variables assignment support. Need to build kinda visitor with recursion control
                                        String returnValue = null;
                                        if (lastExpression instanceof PerlMethodContainer) {
                                            returnValue = PerlSubUtil.getMethodReturnValue((PerlMethodContainer) lastExpression);
                                        }
                                        if (lastExpression instanceof PerlDerefExpression) {
                                            returnValue = ((PerlDerefExpression) lastExpression).guessType();
                                        }
                                        if (StringUtil.isNotEmpty(returnValue)) {
                                            guessResult[0] = returnValue;
                                            return false;
                                        }
                                    }
                                }
                            }
                        }
                        return true;
                    });
                }
                if (guessResult[0] != null) {
                    return guessResult[0];
                }
            }
            // checking global declarations with explicit types
            for (PerlVariableDeclarationElement declaration : getGlobalDeclarations()) {
                if (declaration.getDeclaredType() != null) {
                    return declaration.getDeclaredType();
                }
            }
        }
    }
    return null;
}
Also used : TextRange(com.intellij.openapi.util.TextRange) PerlLexicalScope(com.perl5.lang.perl.psi.properties.PerlLexicalScope) PerlImplicitVariableDeclaration(com.perl5.lang.perl.psi.impl.PerlImplicitVariableDeclaration) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) Nullable(org.jetbrains.annotations.Nullable)

Example 10 with PerlVariableDeclarationElement

use of com.perl5.lang.perl.psi.PerlVariableDeclarationElement in project Perl5-IDEA by Camelcade.

the class PerlVariableMixin method getGlobalDeclarations.

// fixme this need to be moved to PerlResolveUtil or Resolver
@Override
public List<PerlVariableDeclarationElement> getGlobalDeclarations() {
    List<PerlVariableDeclarationElement> result = new ArrayList<>();
    PerlVariableType myType = getActualType();
    // wrapper if any
    PsiElement parent = getParent();
    if (myType == PerlVariableType.SCALAR) {
        for (PerlVariableDeclarationElement variable : PerlScalarUtil.getGlobalScalarDefinitions(getProject(), getCanonicalName())) {
            if (!variable.equals(parent)) {
                result.add(variable);
            }
        }
    } else if (myType == PerlVariableType.ARRAY) {
        for (PerlVariableDeclarationElement variable : PerlArrayUtil.getGlobalArrayDefinitions(getProject(), getCanonicalName())) {
            if (!variable.equals(parent)) {
                result.add(variable);
            }
        }
    } else if (myType == PerlVariableType.HASH) {
        for (PerlVariableDeclarationElement variable : PerlHashUtil.getGlobalHashDefinitions(getProject(), getCanonicalName())) {
            if (!variable.equals(parent)) {
                result.add(variable);
            }
        }
    }
    return result;
}
Also used : PerlVariableType(com.perl5.lang.perl.psi.utils.PerlVariableType) ArrayList(java.util.ArrayList) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement)

Aggregations

PsiElement (com.intellij.psi.PsiElement)12 PerlVariableDeclarationElement (com.perl5.lang.perl.psi.PerlVariableDeclarationElement)10 NotNull (org.jetbrains.annotations.NotNull)10 PerlVariable (com.perl5.lang.perl.psi.PerlVariable)6 PerlVariableType (com.perl5.lang.perl.psi.utils.PerlVariableType)6 PerlLexicalScope (com.perl5.lang.perl.psi.properties.PerlLexicalScope)5 Project (com.intellij.openapi.project.Project)4 CompletionResultSet (com.intellij.codeInsight.completion.CompletionResultSet)3 LookupElementBuilder (com.intellij.codeInsight.lookup.LookupElementBuilder)3 StringUtil (com.intellij.openapi.util.text.StringUtil)3 GlobalSearchScope (com.intellij.psi.search.GlobalSearchScope)3 PerlExportDescriptor (com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor)3 com.perl5.lang.perl.psi (com.perl5.lang.perl.psi)3 PerlImplicitVariableDeclaration (com.perl5.lang.perl.psi.impl.PerlImplicitVariableDeclaration)3 LookupElement (com.intellij.codeInsight.lookup.LookupElement)2 PsiFile (com.intellij.psi.PsiFile)2 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)2 PsiScopeProcessor (com.intellij.psi.scope.PsiScopeProcessor)2 PsiTreeUtil (com.intellij.psi.util.PsiTreeUtil)2 PerlIcons (com.perl5.PerlIcons)2