Search in sources :

Example 1 with PodFile

use of com.perl5.lang.pod.parser.psi.PodFile in project Perl5-IDEA by Camelcade.

the class PerlDocumentationProvider method getCustomDocumentationElement.

@Nullable
@Override
public PsiElement getCustomDocumentationElement(@NotNull Editor editor, @NotNull PsiFile file, @Nullable PsiElement contextElement) {
    if (contextElement == null || contextElement.getLanguage() != PerlLanguage.INSTANCE) {
        return null;
    }
    IElementType elementType = contextElement.getNode().getElementType();
    if (contextElement instanceof PerlVariable) {
        // fixme try to search doc in package or declaration
        return PerlDocUtil.getPerlVarDoc((PerlVariable) contextElement);
    } else if (elementType == REGEX_MODIFIER) {
        return PerlDocUtil.getRegexModifierDoc(contextElement);
    } else if (elementType == REGEX_TOKEN) {
        return PerlDocUtil.resolveDocLink("perlretut", contextElement);
    } else if (elementType == VERSION_ELEMENT) {
        return PerlDocUtil.resolveDocLink("perldata/\"Version Strings\"", contextElement);
    } else if (isFunc(contextElement)) {
        return PerlDocUtil.getPerlFuncDoc(contextElement);
    } else if (isOp(contextElement)) {
        return PerlDocUtil.getPerlOpDoc(contextElement);
    } else if (contextElement instanceof PerlSubNameElement) {
        String packageName = ((PerlSubNameElement) contextElement).getPackageName();
        String subName = ((PerlSubNameElement) contextElement).getName();
        if (StringUtil.isNotEmpty(subName)) {
            PsiElement result = null;
            // search by link
            if (StringUtil.isNotEmpty(packageName) && !StringUtil.equals(PerlPackageUtil.MAIN_PACKAGE, packageName)) {
                result = PerlDocUtil.resolveDocLink(packageName + "/" + ((PerlSubNameElement) contextElement).getName(), contextElement);
            }
            // not found or main::
            if (result == null) {
                PsiElement target = null;
                if (contextElement.getParent() instanceof PerlSubElement) {
                    target = contextElement.getParent();
                } else {
                    PsiReference reference = contextElement.getReference();
                    if (reference != null) {
                        target = reference.resolve();
                    }
                }
                if (target != null) {
                    PsiFile targetFile = target.getContainingFile();
                    if (targetFile != null) {
                        PsiFile podFile = targetFile.getViewProvider().getPsi(PodLanguage.INSTANCE);
                        if (podFile != null) {
                            result = PerlDocUtil.searchPodElement(targetFile, PodDocumentPattern.headingAndItemPattern(subName));
                        }
                    }
                }
            }
            if (result != null) {
                return result;
            }
        }
    } else if (contextElement instanceof PerlNamespaceElement) {
        String packageName = ((PerlNamespaceElement) contextElement).getCanonicalName();
        if (StringUtil.equals(PerlPackageUtil.SUPER_PACKAGE, packageName)) {
            return PerlDocUtil.resolveDocLink("perlobj/Inheritance", contextElement);
        } else if (StringUtil.isNotEmpty(packageName)) {
            return PerlDocUtil.resolveDocLink(packageName, contextElement);
        }
    }
    return super.getCustomDocumentationElement(editor, file, contextElement);
}
Also used : IElementType(com.intellij.psi.tree.IElementType) PerlSubNameElement(com.perl5.lang.perl.psi.PerlSubNameElement) PerlSubElement(com.perl5.lang.perl.psi.PerlSubElement) PsiReference(com.intellij.psi.PsiReference) PerlNamespaceElement(com.perl5.lang.perl.psi.PerlNamespaceElement) PsiFile(com.intellij.psi.PsiFile) PerlVariable(com.perl5.lang.perl.psi.PerlVariable) PsiElement(com.intellij.psi.PsiElement) Nullable(org.jetbrains.annotations.Nullable)

Example 2 with PodFile

use of com.perl5.lang.pod.parser.psi.PodFile in project Perl5-IDEA by Camelcade.

the class PodTypedHandler method beforeCharTyped.

@Override
public Result beforeCharTyped(char c, Project project, Editor editor, PsiFile file, FileType fileType) {
    if (file instanceof PodFile) {
        if (c == '<') {
            CaretModel caretModel = editor.getCaretModel();
            int offset = caretModel.getOffset() - 1;
            PsiElement element = file.findElementAt(offset);
            IElementType elementType = element == null ? null : element.getNode().getElementType();
            String text = element == null ? null : element.getText();
            if (elementType == POD_IDENTIFIER && text != null) {
                if (text.length() == 1 && StringUtil.containsChar(POD_COMMANDS, text.charAt(0))) {
                    EditorModificationUtil.insertStringAtCaret(editor, ">", false, false, 0);
                }
            } else if (elementType == POD_ANGLE_LEFT || POD_COMMANDS_TOKENSET.contains(elementType)) {
                // noinspection ConstantConditions
                extendAngles(element.getParent());
                caretModel.moveToOffset(offset + 2);
                return Result.STOP;
            }
        } else if (// '>'
        c == '>') {
            CaretModel caretModel = editor.getCaretModel();
            int offset = caretModel.getOffset();
            PsiElement element = file.findElementAt(offset);
            IElementType elementType = element == null ? null : element.getNode().getElementType();
            int extraOffset = 0;
            if (elementType != POD_ANGLE_RIGHT) {
                offset--;
                element = file.findElementAt(offset);
                elementType = element == null ? null : element.getNode().getElementType();
                extraOffset++;
            }
            if (elementType == POD_ANGLE_RIGHT) {
                // noinspection ConstantConditions
                caretModel.moveToOffset(offset + extendAngles(element.getParent()) + extraOffset);
                return Result.STOP;
            }
        }
    }
    return super.beforeCharTyped(c, project, editor, file, fileType);
}
Also used : IElementType(com.intellij.psi.tree.IElementType) CaretModel(com.intellij.openapi.editor.CaretModel) PodFile(com.perl5.lang.pod.parser.psi.PodFile) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement) PsiElement(com.intellij.psi.PsiElement)

Example 3 with PodFile

use of com.perl5.lang.pod.parser.psi.PodFile 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 4 with PodFile

use of com.perl5.lang.pod.parser.psi.PodFile in project Perl5-IDEA by Camelcade.

the class PodBackspaceHandler method charDeleted.

@Override
public boolean charDeleted(char c, PsiFile file, Editor editor) {
    if (file instanceof PodFile) {
        CaretModel caretModel = editor.getCaretModel();
        int offset = caretModel.getOffset();
        PsiElement element = file.findElementAt(offset);
        IElementType elementType = element == null ? null : element.getNode().getElementType();
        if (elementType == POD_ANGLE_RIGHT) {
            @SuppressWarnings("ConstantConditions") PsiElement formatterBlock = element.getParent();
            if (formatterBlock != null) {
                PsiElement openAngles = formatterBlock.getFirstChild();
                openAngles = openAngles == null ? null : openAngles.getNextSibling();
                if (openAngles != null) {
                    int openAnglesOffset = openAngles.getTextRange().getStartOffset();
                    editor.getDocument().deleteString(openAnglesOffset, openAnglesOffset + 1);
                    return true;
                }
            }
        } else if (elementType == POD_ANGLE_LEFT) {
            @SuppressWarnings("ConstantConditions") PsiElement formatterBlock = element.getParent();
            if (formatterBlock != null) {
                PsiElement closeAngles = formatterBlock.getLastChild();
                if (closeAngles != null) {
                    int closeAnglesOffset = closeAngles.getTextRange().getStartOffset();
                    editor.getDocument().deleteString(closeAnglesOffset - 1, closeAnglesOffset);
                    return true;
                }
            }
            return true;
        }
    }
    return false;
}
Also used : IElementType(com.intellij.psi.tree.IElementType) CaretModel(com.intellij.openapi.editor.CaretModel) PodFile(com.perl5.lang.pod.parser.psi.PodFile) PsiElement(com.intellij.psi.PsiElement)

Aggregations

PsiElement (com.intellij.psi.PsiElement)4 IElementType (com.intellij.psi.tree.IElementType)3 CaretModel (com.intellij.openapi.editor.CaretModel)2 PsiFile (com.intellij.psi.PsiFile)2 PodFile (com.perl5.lang.pod.parser.psi.PodFile)2 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 Project (com.intellij.openapi.project.Project)1 FileViewProvider (com.intellij.psi.FileViewProvider)1 PsiReference (com.intellij.psi.PsiReference)1 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)1 GlobalSearchScope (com.intellij.psi.search.GlobalSearchScope)1 PerlLanguage (com.perl5.lang.perl.PerlLanguage)1 PerlExportDescriptor (com.perl5.lang.perl.extensions.packageprocessor.PerlExportDescriptor)1 PerlLightConstantDefinitionElement (com.perl5.lang.perl.parser.constant.psi.light.PerlLightConstantDefinitionElement)1 PerlNamespaceElement (com.perl5.lang.perl.psi.PerlNamespaceElement)1 PerlSubElement (com.perl5.lang.perl.psi.PerlSubElement)1 PerlSubNameElement (com.perl5.lang.perl.psi.PerlSubNameElement)1