Search in sources :

Example 1 with PerlExportDescriptor

use of com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor 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 2 with PerlExportDescriptor

use of com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor in project Perl5-IDEA by Camelcade.

the class PerlSubReference method resolveInner.

@NotNull
@Override
protected ResolveResult[] resolveInner(boolean incompleteCode) {
    PsiElement myElement = getElement();
    assert myElement instanceof PerlSubNameElement;
    PsiElement parent = myElement.getParent();
    if (parent instanceof PerlSubDeclarationElement || parent instanceof PerlSubDefinitionElement) {
        return ResolveResult.EMPTY_ARRAY;
    }
    PerlSubNameElement subNameElement = (PerlSubNameElement) myElement;
    List<PsiElement> relatedItems = new ArrayList<>();
    String packageName = subNameElement.getPackageName();
    String subName = subNameElement.getName();
    Project project = subNameElement.getProject();
    PerlNamespaceElement expliclitPackageElement = null;
    if (parent instanceof PerlNamespaceElementContainer) {
        expliclitPackageElement = ((PerlNamespaceElementContainer) parent).getNamespaceElement();
    }
    if (!subName.isEmpty()) {
        if (parent instanceof PerlMethod && ((PerlMethod) parent).isObjectMethod()) {
            boolean isSuper = expliclitPackageElement != null && expliclitPackageElement.isSUPER();
            relatedItems.addAll(PerlMro.resolveSub(project, isSuper ? PerlPackageUtil.getContextPackageName(subNameElement) : packageName, subName, isSuper));
        } else // static resolution
        {
            if (PerlSharedSettings.getInstance(project).SIMPLE_MAIN_RESOLUTION && // fixme this is a dirty hack until proper names resolution implemented
            PerlPackageUtil.isMain(packageName)) {
                PsiFile file = subNameElement.getContainingFile();
                GlobalSearchScope fileScope = GlobalSearchScope.fileScope(file);
                collectRelatedItems(packageName + PerlPackageUtil.PACKAGE_SEPARATOR + subName, project, parent, relatedItems, fileScope);
            // if (file instanceof PerlFile)
            // ((PerlFile) file).getElementsResolveScope();
            // System.err.println("Checking for " + subName);
            }
            if (relatedItems.isEmpty()) {
                GlobalSearchScope globalSearchScope = GlobalSearchScope.allScope(project);
                // check indexes for defined subs
                collectRelatedItems(packageName + PerlPackageUtil.PACKAGE_SEPARATOR + subName, project, parent, relatedItems, globalSearchScope);
                if (expliclitPackageElement == null) {
                    // check for imports to the current file
                    PerlNamespaceDefinitionElement namespaceContainer = PerlPackageUtil.getNamespaceContainerForElement(subNameElement);
                    if (namespaceContainer != null) {
                        for (PerlExportDescriptor exportDescriptor : namespaceContainer.getImportedSubsDescriptors()) {
                            if (exportDescriptor.getImportedName().equals(subName)) {
                                int currentSize = relatedItems.size();
                                collectRelatedItems(exportDescriptor.getTargetCanonicalName(), project, parent, relatedItems, globalSearchScope);
                                if (// imported, but not found, attempting autoload
                                relatedItems.size() == currentSize) {
                                    collectRelatedItems(exportDescriptor.getRealPackage() + PerlSubUtil.SUB_AUTOLOAD_WITH_PREFIX, project, parent, relatedItems, globalSearchScope);
                                }
                            }
                        }
                    }
                } else // check imports to target namespace
                {
                    String targetPackageName = expliclitPackageElement.getCanonicalName();
                    if (targetPackageName != null) {
                        // fixme partially not DRY with previous block
                        for (PerlNamespaceDefinitionElement namespaceDefinition : PerlPackageUtil.getNamespaceDefinitions(project, targetPackageName)) {
                            for (PerlExportDescriptor exportDescriptor : namespaceDefinition.getImportedSubsDescriptors()) {
                                if (exportDescriptor.getImportedName().equals(subName)) {
                                    collectRelatedItems(exportDescriptor.getTargetCanonicalName(), project, parent, relatedItems, globalSearchScope);
                                }
                            }
                        }
                    }
                }
                // check for builtins
                if (relatedItems.isEmpty()) {
                    PerlSubDefinitionElement builtInSub = PerlBuiltInSubsService.getInstance(project).findSub(subName);
                    if (builtInSub != null) {
                        relatedItems.add(builtInSub);
                    }
                }
                // check for autoload
                if (relatedItems.isEmpty() && // don't check for UNIVERSAL::AUTOLOAD
                !PerlPackageUtil.isUNIVERSAL(packageName)) {
                    collectRelatedItems(packageName + PerlSubUtil.SUB_AUTOLOAD_WITH_PREFIX, project, parent, relatedItems, globalSearchScope);
                }
            }
        }
    }
    List<ResolveResult> result = getResolveResults(relatedItems);
    return result.toArray(new ResolveResult[result.size()]);
}
Also used : ArrayList(java.util.ArrayList) Project(com.intellij.openapi.project.Project) PerlExportDescriptor(com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) PerlNamespaceElementContainer(com.perl5.lang.perl.psi.properties.PerlNamespaceElementContainer) PsiFile(com.intellij.psi.PsiFile) ResolveResult(com.intellij.psi.ResolveResult) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with PerlExportDescriptor

use of com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor in project Perl5-IDEA by Camelcade.

the class PerlVariableReference method resolveInner.

@NotNull
@Override
protected ResolveResult[] resolveInner(boolean incompleteCode) {
    PsiElement elementParent = myElement.getParent();
    assert elementParent instanceof PerlVariable;
    PerlVariable perlVariable = (PerlVariable) elementParent;
    List<ResolveResult> result = new ArrayList<>();
    PerlVariableDeclarationElement lexicalDeclaration = PerlResolveUtil.getLexicalDeclaration(perlVariable);
    if (lexicalDeclaration == null || lexicalDeclaration.isGlobalDeclaration() && !(lexicalDeclaration instanceof PerlImplicitVariableDeclaration)) {
        // not found explicit lexically visible declarations
        // imports
        PerlVariableType actualType = perlVariable.getActualType();
        Project project = perlVariable.getProject();
        PerlNamespaceDefinitionElement namespaceContainer = PerlPackageUtil.getNamespaceContainerForElement(perlVariable);
        if (// not true if LPE in TemplateToolkit
        namespaceContainer != null) {
            String variableName = perlVariable.getName();
            if (actualType == PerlVariableType.SCALAR) {
                for (PerlExportDescriptor importEntry : namespaceContainer.getImportedScalarDescriptors()) {
                    if (importEntry.getImportedName().equals(variableName)) {
                        for (PerlVariableDeclarationElement targetVariable : PerlScalarUtil.getGlobalScalarDefinitions(project, importEntry.getTargetCanonicalName())) {
                            result.add(new PsiElementResolveResult(targetVariable));
                        }
                    }
                }
            } else if (actualType == PerlVariableType.ARRAY) {
                for (PerlExportDescriptor importEntry : namespaceContainer.getImportedArrayDescriptors()) {
                    if (importEntry.getImportedName().equals(variableName)) {
                        for (PerlVariableDeclarationElement targetVariable : PerlArrayUtil.getGlobalArrayDefinitions(project, importEntry.getTargetCanonicalName())) {
                            result.add(new PsiElementResolveResult(targetVariable));
                        }
                    }
                }
            } else if (actualType == PerlVariableType.HASH) {
                for (PerlExportDescriptor importEntry : namespaceContainer.getImportedHashDescriptors()) {
                    if (importEntry.getImportedName().equals(variableName)) {
                        for (PerlVariableDeclarationElement targetVariable : PerlHashUtil.getGlobalHashDefinitions(project, importEntry.getTargetCanonicalName())) {
                            result.add(new PsiElementResolveResult(targetVariable));
                        }
                    }
                }
            }
        }
        // our variable declaration
        for (PerlGlobVariable glob : perlVariable.getRelatedGlobs()) {
            result.add(new PsiElementResolveResult(glob));
        }
        // globs
        for (PerlVariableDeclarationElement globalDeclaration : perlVariable.getGlobalDeclarations()) {
            result.add(new PsiElementResolveResult(globalDeclaration));
        }
    } else {
        result.add(new PsiElementResolveResult(lexicalDeclaration));
    }
    return result.toArray(new ResolveResult[result.size()]);
}
Also used : PerlVariableDeclarationElement(com.perl5.lang.perl.psi.PerlVariableDeclarationElement) PerlVariableType(com.perl5.lang.perl.psi.utils.PerlVariableType) ArrayList(java.util.ArrayList) PsiElementResolveResult(com.intellij.psi.PsiElementResolveResult) Project(com.intellij.openapi.project.Project) PerlExportDescriptor(com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor) PerlNamespaceDefinitionElement(com.perl5.lang.perl.psi.PerlNamespaceDefinitionElement) PerlGlobVariable(com.perl5.lang.perl.psi.PerlGlobVariable) PerlVariable(com.perl5.lang.perl.psi.PerlVariable) PsiElementResolveResult(com.intellij.psi.PsiElementResolveResult) ResolveResult(com.intellij.psi.ResolveResult) PerlImplicitVariableDeclaration(com.perl5.lang.perl.psi.impl.PerlImplicitVariableDeclaration) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with PerlExportDescriptor

use of com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor in project Perl5-IDEA by Camelcade.

the class PerlStructureViewElement method getPresentation.

@NotNull
@Override
public ItemPresentation getPresentation() {
    ItemPresentation itemPresentation = createPresentation();
    if ((isInherited() || isImported()) && itemPresentation instanceof PerlItemPresentationBase) {
        if (getValue() instanceof PerlDeprecatable && ((PerlDeprecatable) getValue()).isDeprecated()) {
            ((PerlItemPresentationBase) itemPresentation).setAttributesKey(PerlSyntaxHighlighter.UNUSED_DEPRECATED);
        } else {
            ((PerlItemPresentationBase) itemPresentation).setAttributesKey(CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES);
        }
    }
    if (isImported() && itemPresentation instanceof PerlItemPresentationSimple) {
        PerlExportDescriptor exportDescriptor = getExportDescriptor();
        assert exportDescriptor != null;
        ((PerlItemPresentationSimple) itemPresentation).setPresentableText(exportDescriptor.getImportedName());
    }
    return itemPresentation;
}
Also used : PerlItemPresentationSimple(com.perl5.lang.perl.idea.presentations.PerlItemPresentationSimple) PerlExportDescriptor(com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor) ItemPresentation(com.intellij.navigation.ItemPresentation) PerlItemPresentationBase(com.perl5.lang.perl.idea.presentations.PerlItemPresentationBase) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with PerlExportDescriptor

use of com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor in project Perl5-IDEA by Camelcade.

the class PerlStructureViewElement method getAlphaSortKey.

@NotNull
@Override
public String getAlphaSortKey() {
    assert myElement instanceof PsiNamedElement;
    PerlExportDescriptor exportDescriptor = getExportDescriptor();
    if (exportDescriptor != null) {
        return exportDescriptor.getImportedName();
    }
    String name = ((PsiNamedElement) myElement).getName();
    if (name == null) {
        name = "Empty named " + myElement;
    }
    return name;
}
Also used : PerlExportDescriptor(com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor) PsiNamedElement(com.intellij.psi.PsiNamedElement) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

PerlExportDescriptor (com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor)9 NotNull (org.jetbrains.annotations.NotNull)9 PsiElement (com.intellij.psi.PsiElement)5 PerlImportsCollector (com.perl5.lang.perl.util.processors.PerlImportsCollector)4 Project (com.intellij.openapi.project.Project)3 PsiFile (com.intellij.psi.PsiFile)2 ResolveResult (com.intellij.psi.ResolveResult)2 GlobalSearchScope (com.intellij.psi.search.GlobalSearchScope)2 ArrayList (java.util.ArrayList)2 LookupElementBuilder (com.intellij.codeInsight.lookup.LookupElementBuilder)1 StructureViewTreeElement (com.intellij.ide.structureView.StructureViewTreeElement)1 SortableTreeElement (com.intellij.ide.util.treeView.smartTree.SortableTreeElement)1 TreeElement (com.intellij.ide.util.treeView.smartTree.TreeElement)1 Language (com.intellij.lang.Language)1 ItemPresentation (com.intellij.navigation.ItemPresentation)1 FileViewProvider (com.intellij.psi.FileViewProvider)1 PsiElementResolveResult (com.intellij.psi.PsiElementResolveResult)1 PsiNamedElement (com.intellij.psi.PsiNamedElement)1 PerlLanguage (com.perl5.lang.perl.PerlLanguage)1 PerlItemPresentationBase (com.perl5.lang.perl.idea.presentations.PerlItemPresentationBase)1