Search in sources :

Example 21 with PsiElementProcessor

use of com.intellij.psi.search.PsiElementProcessor in project intellij-elixir by KronicDeth.

the class Builder method buildFoldRegions.

/*
     * Instance Methods
     */
/**
     * Builds the folding regions for the specified node in the AST tree and its children.
     *
     * @param root     the element for which folding is requested.
     * @param document the document for which folding is built. Can be used to retrieve line
     *                 numbers for folding regions.
     * @param quick    whether the result should be provided as soon as possible. Is true, when
     *                 an editor is opened and we need to auto-fold something immediately, like Java imports.
     *                 If true, one should perform no reference resolving and avoid complex checks if possible.
     * @return the array of folding descriptors.
     */
@NotNull
@Override
public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, final boolean quick) {
    final List<FoldingDescriptor> foldingDescriptorList = new ArrayList<FoldingDescriptor>();
    PsiTreeUtil.processElements(root, new PsiElementProcessor() {

        private Map<String, FoldingGroup> foldingGroupByModuleAttributeName = new HashMap<String, FoldingGroup>();

        /*
                     *
                     * Instance Methods
                     *
                     */
        /*
                     * Public Instance Methods
                     */
        @Override
        public boolean execute(@NotNull PsiElement element) {
            boolean keepProcessing = true;
            if (element instanceof AtNonNumericOperation) {
                keepProcessing = execute((AtNonNumericOperation) element);
            } else if (element instanceof AtUnqualifiedNoParenthesesCall) {
                keepProcessing = execute((AtUnqualifiedNoParenthesesCall) element);
            } else if (element instanceof ElixirDoBlock) {
                keepProcessing = execute((ElixirDoBlock) element);
            } else if (element instanceof ElixirStabOperation) {
                keepProcessing = execute((ElixirStabOperation) element);
            } else if (element instanceof Call) {
                keepProcessing = execute((Call) element);
            }
            return keepProcessing;
        }

        /*
                     * Private Instance Methods
                     */
        private boolean execute(@NotNull AtNonNumericOperation atNonNumericOperation) {
            boolean keepProcessing = true;
            if (!quick) {
                keepProcessing = slowExecute(atNonNumericOperation);
            }
            return keepProcessing;
        }

        private boolean execute(@NotNull AtUnqualifiedNoParenthesesCall atUnqualifiedNoParenthesesCall) {
            String moduleAttributeName = moduleAttributeName(atUnqualifiedNoParenthesesCall);
            String name = moduleAttributeName.substring(1);
            if (ModuleAttribute.isDocumentationName(name)) {
                ElixirNoParenthesesOneArgument noParenthesesOneArgument = atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument();
                foldingDescriptorList.add(new NamedFoldingDescriptor(noParenthesesOneArgument.getNode(), noParenthesesOneArgument.getTextRange(), null, "\"...\""));
            } else if (ModuleAttribute.isTypeName(name)) {
                ElixirNoParenthesesOneArgument noParenthesesOneArgument = atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument();
                PsiElement[] children = noParenthesesOneArgument.getChildren();
                if (children.length == 1) {
                    PsiElement child = children[0];
                    if (child instanceof Type) {
                        Type type = (Type) child;
                        PsiElement rightOperand = Normalized.rightOperand(type);
                        if (rightOperand != null) {
                            foldingDescriptorList.add(new NamedFoldingDescriptor(rightOperand.getNode(), rightOperand.getTextRange(), null, "..."));
                        }
                    }
                }
            }
            return true;
        }

        private boolean execute(@NotNull Call call) {
            for (String resolvedFunctionName : RESOLVED_FUNCTION_NAMES) {
                if (call.isCalling(KERNEL, resolvedFunctionName)) {
                    if (isFirstInGroup(call, KERNEL, resolvedFunctionName)) {
                        Call last = lastInGroup(call, KERNEL, resolvedFunctionName);
                        PsiElement[] finalArguments = finalArguments(call);
                        if (finalArguments != null && finalArguments.length >= 1) {
                            TextRange textRange = new TextRange(finalArguments[0].getTextOffset(), last.getTextRange().getEndOffset());
                            foldingDescriptorList.add(new NamedFoldingDescriptor(call.getParent().getNode(), textRange, null, "..."));
                        }
                    }
                }
            }
            return true;
        }

        private boolean execute(@NotNull ElixirDoBlock doBlock) {
            foldingDescriptorList.add(new FoldingDescriptor(doBlock, doBlock.getTextRange()));
            return true;
        }

        private boolean execute(@NotNull ElixirStabOperation stabOperation) {
            int startOffset = stabOperation.operator().getTextOffset();
            int endOffset = stabOperation.getTextRange().getEndOffset();
            TextRange textRange = new TextRange(startOffset, endOffset);
            foldingDescriptorList.add(new FoldingDescriptor(stabOperation, textRange));
            return true;
        }

        private boolean isFirstInGroup(@NotNull Call call, @NotNull String resolvedModuleName, @NotNull String resolvedFunctionName) {
            PsiElement previousSiblingExpression = previousSiblingExpression(call);
            boolean first = true;
            if (previousSiblingExpression instanceof Call) {
                Call previousSiblingExpressionCall = (Call) previousSiblingExpression;
                first = !previousSiblingExpressionCall.isCalling(resolvedModuleName, resolvedFunctionName);
            }
            return first;
        }

        @NotNull
        private Call lastInGroup(@NotNull Call first, @NotNull String resolvedModuleName, @NotNull String resolvedFunctionName) {
            PsiElement expression = first;
            Call last = first;
            while (true) {
                expression = nextSiblingExpression(expression);
                if (expression instanceof Call) {
                    Call call = (Call) expression;
                    if (call.isCalling(resolvedModuleName, resolvedFunctionName)) {
                        last = call;
                        continue;
                    }
                }
                break;
            }
            return last;
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation) {
            boolean keepProcessing = true;
            PsiReference reference = atNonNumericOperation.getReference();
            if (reference != null) {
                keepProcessing = slowExecute(atNonNumericOperation, reference);
            }
            return keepProcessing;
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull final AtUnqualifiedNoParenthesesCall atUnqualifiedNoParenthesesCall) {
            return slowExecute(atNonNumericOperation, atUnqualifiedNoParenthesesCall, atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument().getText());
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull PsiElement target) {
            boolean keepProcessing = true;
            if (target instanceof AtUnqualifiedNoParenthesesCall) {
                keepProcessing = slowExecute(atNonNumericOperation, (AtUnqualifiedNoParenthesesCall) target);
            } else if (target instanceof QualifiableAlias) {
                keepProcessing = slowExecute(atNonNumericOperation, (QualifiableAlias) target);
            }
            return keepProcessing;
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull PsiReference reference) {
            PsiElement target = reference.resolve();
            boolean keepProcessing = true;
            if (target != null) {
                keepProcessing = slowExecute(atNonNumericOperation, target);
            }
            return keepProcessing;
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull final QualifiableAlias qualifiableAlias) {
            return slowExecute(atNonNumericOperation, qualifiableAlias, qualifiableAlias.getName());
        }

        private boolean slowExecute(@NotNull AtNonNumericOperation atNonNumericOperation, @NotNull PsiElement element, @Nullable final String placeHolderText) {
            String moduleAttributeName = atNonNumericOperation.moduleAttributeName();
            FoldingGroup foldingGroup = foldingGroupByModuleAttributeName.get(moduleAttributeName);
            if (foldingGroup == null) {
                foldingGroup = FoldingGroup.newGroup(moduleAttributeName);
                foldingGroupByModuleAttributeName.put(moduleAttributeName, foldingGroup);
            }
            foldingDescriptorList.add(new FoldingDescriptor(atNonNumericOperation.getNode(), atNonNumericOperation.getTextRange(), foldingGroup, Collections.<Object>singleton(element)) {

                @Nullable
                @Override
                public String getPlaceholderText() {
                    return placeHolderText;
                }
            });
            return true;
        }
    });
    return foldingDescriptorList.toArray(new FoldingDescriptor[foldingDescriptorList.size()]);
}
Also used : Call(org.elixir_lang.psi.call.Call) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) FoldingDescriptor(com.intellij.lang.folding.FoldingDescriptor) FoldingGroup(com.intellij.openapi.editor.FoldingGroup) PsiReference(com.intellij.psi.PsiReference) TextRange(com.intellij.openapi.util.TextRange) NotNull(org.jetbrains.annotations.NotNull) PsiElementProcessor(com.intellij.psi.search.PsiElementProcessor) Type(org.elixir_lang.psi.operation.Type) NamedFoldingDescriptor(com.intellij.lang.folding.NamedFoldingDescriptor) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 22 with PsiElementProcessor

use of com.intellij.psi.search.PsiElementProcessor in project intellij-community by JetBrains.

the class LocalToFieldHandler method convertLocalToField.

public boolean convertLocalToField(final PsiLocalVariable local, final Editor editor) {
    boolean tempIsStatic = myIsConstant;
    PsiElement parent = local.getParent();
    final List<PsiClass> classes = new ArrayList<>();
    while (parent != null && parent.getContainingFile() != null) {
        if (parent instanceof PsiClass && !(myIsConstant && parent instanceof PsiAnonymousClass)) {
            classes.add((PsiClass) parent);
        }
        if (parent instanceof PsiFile && FileTypeUtils.isInServerPageFile(parent)) {
            String message = RefactoringBundle.message("error.not.supported.for.jsp", REFACTORING_NAME);
            CommonRefactoringUtil.showErrorHint(myProject, editor, message, REFACTORING_NAME, HelpID.LOCAL_TO_FIELD);
            return false;
        }
        if (parent instanceof PsiModifierListOwner && ((PsiModifierListOwner) parent).hasModifierProperty(PsiModifier.STATIC)) {
            tempIsStatic = true;
        }
        parent = parent.getParent();
    }
    if (classes.isEmpty())
        return false;
    final AbstractInplaceIntroducer activeIntroducer = AbstractInplaceIntroducer.getActiveIntroducer(editor);
    final boolean shouldSuggestDialog = activeIntroducer instanceof InplaceIntroduceConstantPopup && activeIntroducer.startsOnTheSameElement(null, local);
    if (classes.size() == 1 || ApplicationManager.getApplication().isUnitTestMode() || shouldSuggestDialog) {
        if (convertLocalToField(local, classes.get(getChosenClassIndex(classes)), editor, tempIsStatic))
            return false;
    } else {
        final boolean isStatic = tempIsStatic;
        final PsiClass firstClass = classes.get(0);
        final PsiClass preselection = AnonymousTargetClassPreselectionUtil.getPreselection(classes, firstClass);
        NavigationUtil.getPsiElementPopup(classes.toArray(new PsiClass[classes.size()]), new PsiClassListCellRenderer(), "Choose class to introduce " + (myIsConstant ? "constant" : "field"), new PsiElementProcessor<PsiClass>() {

            @Override
            public boolean execute(@NotNull PsiClass aClass) {
                AnonymousTargetClassPreselectionUtil.rememberSelection(aClass, aClass);
                convertLocalToField(local, aClass, editor, isStatic);
                return false;
            }
        }, preselection).showInBestPositionFor(editor);
    }
    return true;
}
Also used : AbstractInplaceIntroducer(com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer) ArrayList(java.util.ArrayList) NotNull(org.jetbrains.annotations.NotNull) PsiElementProcessor(com.intellij.psi.search.PsiElementProcessor) PsiClassListCellRenderer(com.intellij.ide.util.PsiClassListCellRenderer)

Example 23 with PsiElementProcessor

use of com.intellij.psi.search.PsiElementProcessor in project intellij-community by JetBrains.

the class GrHighlightUtil method collectReassignedNames.

private static Set<String> collectReassignedNames(PsiElement scope) {
    final Set<String> result = ContainerUtil.newHashSet();
    PsiTreeUtil.processElements(scope, new PsiElementProcessor() {

        @Override
        public boolean execute(@NotNull PsiElement element) {
            if (!(element instanceof GrReferenceExpression) || !((GrReferenceExpression) element).isQualified()) {
                return true;
            }
            GrReferenceExpression ref = (GrReferenceExpression) element;
            if (isWriteAccess(ref)) {
                String varName = ref.getReferenceName();
                if (!result.contains(varName)) {
                    PsiElement target = ref.resolve();
                    if (target instanceof GrVariable && ((GrVariable) target).getInitializerGroovy() != null || target instanceof GrParameter) {
                        result.add(varName);
                    }
                }
            }
            return true;
        }
    });
    return result;
}
Also used : GrVariable(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) PsiElementProcessor(com.intellij.psi.search.PsiElementProcessor) GrReferenceExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression)

Example 24 with PsiElementProcessor

use of com.intellij.psi.search.PsiElementProcessor in project intellij-community by JetBrains.

the class ElementProcessor method processExternalFile.

public void processExternalFile(PsiFile psiFile, XmlTag place) {
    final XmlDocument document = ((XmlFile) psiFile).getDocument();
    assert document != null;
    final XmlTag rootTag = document.getRootTag();
    assert rootTag != null;
    myInclude++;
    try {
        rootTag.processElements(new PsiElementProcessor() {

            public boolean execute(@NotNull PsiElement element) {
                if (element instanceof XmlTag) {
                    return process((XmlTag) element);
                }
                return shouldContinue();
            }
        }, place);
    } finally {
        myInclude--;
    }
}
Also used : XmlFile(com.intellij.psi.xml.XmlFile) XmlDocument(com.intellij.psi.xml.XmlDocument) PsiElementProcessor(com.intellij.psi.search.PsiElementProcessor) PsiElement(com.intellij.psi.PsiElement) XmlTag(com.intellij.psi.xml.XmlTag)

Example 25 with PsiElementProcessor

use of com.intellij.psi.search.PsiElementProcessor in project intellij-community by JetBrains.

the class XsltCodeInsightUtil method findFirstRealTagChild.

@Nullable
public static PsiElement findFirstRealTagChild(@NotNull XmlTag xmlTag) {
    final PsiElement[] child = new PsiElement[1];
    xmlTag.processElements(new PsiElementProcessor() {

        public boolean execute(@NotNull PsiElement element) {
            if (element instanceof XmlToken) {
                if (((XmlToken) element).getTokenType() == XmlTokenType.XML_TAG_END) {
                    child[0] = element.getNextSibling();
                    return false;
                }
            }
            return true;
        }
    }, xmlTag);
    return child[0];
}
Also used : PsiElement(com.intellij.psi.PsiElement) PsiElementProcessor(com.intellij.psi.search.PsiElementProcessor) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

PsiElementProcessor (com.intellij.psi.search.PsiElementProcessor)37 PsiElement (com.intellij.psi.PsiElement)20 NotNull (org.jetbrains.annotations.NotNull)12 ArrayList (java.util.ArrayList)8 ASTNode (com.intellij.lang.ASTNode)4 PsiFile (com.intellij.psi.PsiFile)4 IncorrectOperationException (com.intellij.util.IncorrectOperationException)4 PsiClassListCellRenderer (com.intellij.ide.util.PsiClassListCellRenderer)3 FileType (com.intellij.openapi.fileTypes.FileType)3 TextRange (com.intellij.openapi.util.TextRange)3 VirtualFile (com.intellij.openapi.vfs.VirtualFile)3 PsiReference (com.intellij.psi.PsiReference)3 XmlFile (com.intellij.psi.xml.XmlFile)3 List (java.util.List)3 Nullable (org.jetbrains.annotations.Nullable)3 LookupElementBuilder (com.intellij.codeInsight.lookup.LookupElementBuilder)2 Project (com.intellij.openapi.project.Project)2 Ref (com.intellij.openapi.util.Ref)2 CompositePsiElement (com.intellij.psi.impl.source.tree.CompositePsiElement)2 CachedValueProvider (com.intellij.psi.util.CachedValueProvider)2