Search in sources :

Example 1 with PsiElementFilter

use of com.intellij.psi.util.PsiElementFilter in project intellij-community by JetBrains.

the class SaveAsTemplateAction method actionPerformed.

@Override
public void actionPerformed(AnActionEvent e) {
    DataContext dataContext = e.getDataContext();
    Editor editor = Objects.requireNonNull(CommonDataKeys.EDITOR.getData(dataContext));
    PsiFile file = Objects.requireNonNull(CommonDataKeys.PSI_FILE.getData(dataContext));
    final Project project = file.getProject();
    PsiDocumentManager.getInstance(project).commitAllDocuments();
    final TextRange selection = new TextRange(editor.getSelectionModel().getSelectionStart(), editor.getSelectionModel().getSelectionEnd());
    PsiElement current = file.findElementAt(selection.getStartOffset());
    int startOffset = selection.getStartOffset();
    while (current instanceof PsiWhiteSpace) {
        current = current.getNextSibling();
        if (current == null)
            break;
        startOffset = current.getTextRange().getStartOffset();
    }
    if (startOffset >= selection.getEndOffset())
        startOffset = selection.getStartOffset();
    final PsiElement[] psiElements = PsiTreeUtil.collectElements(file, new PsiElementFilter() {

        @Override
        public boolean isAccepted(PsiElement element) {
            return selection.contains(element.getTextRange()) && element.getReferences().length > 0;
        }
    });
    final Document document = EditorFactory.getInstance().createDocument(editor.getDocument().getText().substring(startOffset, selection.getEndOffset()));
    final boolean isXml = file.getLanguage().is(StdLanguages.XML);
    final int offsetDelta = startOffset;
    new WriteCommandAction.Simple(project, (String) null) {

        @Override
        protected void run() throws Throwable {
            Map<RangeMarker, String> rangeToText = new HashMap<>();
            for (PsiElement element : psiElements) {
                for (PsiReference reference : element.getReferences()) {
                    if (!(reference instanceof PsiQualifiedReference) || ((PsiQualifiedReference) reference).getQualifier() == null) {
                        String canonicalText = reference.getCanonicalText();
                        TextRange referenceRange = reference.getRangeInElement();
                        final TextRange elementTextRange = element.getTextRange();
                        LOG.assertTrue(elementTextRange != null, elementTextRange);
                        final TextRange range = elementTextRange.cutOut(referenceRange).shiftRight(-offsetDelta);
                        final String oldText = document.getText(range);
                        // workaround for Java references: canonicalText contains generics, and we need to cut them off because otherwise
                        // they will be duplicated
                        int pos = canonicalText.indexOf('<');
                        if (pos > 0 && !oldText.contains("<")) {
                            canonicalText = canonicalText.substring(0, pos);
                        }
                        if (isXml) {
                            //strip namespace prefixes
                            pos = canonicalText.lastIndexOf(':');
                            if (pos >= 0 && pos < canonicalText.length() - 1 && !oldText.contains(":")) {
                                canonicalText = canonicalText.substring(pos + 1);
                            }
                        }
                        if (!canonicalText.equals(oldText)) {
                            rangeToText.put(document.createRangeMarker(range), canonicalText);
                        }
                    }
                }
            }
            List<RangeMarker> markers = new ArrayList<>();
            for (RangeMarker m1 : rangeToText.keySet()) {
                boolean nested = false;
                for (RangeMarker m2 : rangeToText.keySet()) {
                    if (m1 != m2 && m2.getStartOffset() <= m1.getStartOffset() && m1.getEndOffset() <= m2.getEndOffset()) {
                        nested = true;
                        break;
                    }
                }
                if (!nested) {
                    markers.add(m1);
                }
            }
            for (RangeMarker marker : markers) {
                final String value = rangeToText.get(marker);
                document.replaceString(marker.getStartOffset(), marker.getEndOffset(), value);
            }
        }
    }.execute();
    final TemplateImpl template = new TemplateImpl(TemplateListPanel.ABBREVIATION, document.getText(), TemplateSettings.USER_GROUP_NAME);
    template.setToReformat(true);
    OffsetKey startKey = OffsetKey.create("pivot");
    OffsetsInFile offsets = new OffsetsInFile(file);
    offsets.getOffsets().addOffset(startKey, startOffset);
    OffsetsInFile copy = TemplateManagerImpl.copyWithDummyIdentifier(offsets, editor.getSelectionModel().getSelectionStart(), editor.getSelectionModel().getSelectionEnd(), CompletionUtil.DUMMY_IDENTIFIER_TRIMMED);
    Set<TemplateContextType> applicable = TemplateManagerImpl.getApplicableContextTypes(copy.getFile(), copy.getOffsets().getOffset(startKey));
    for (TemplateContextType contextType : TemplateManagerImpl.getAllContextTypes()) {
        template.getTemplateContext().setEnabled(contextType, applicable.contains(contextType));
    }
    final LiveTemplatesConfigurable configurable = new LiveTemplatesConfigurable();
    ShowSettingsUtil.getInstance().editConfigurable(project, configurable, () -> configurable.getTemplateListPanel().addTemplate(template));
}
Also used : WriteCommandAction(com.intellij.openapi.command.WriteCommandAction) OffsetsInFile(com.intellij.codeInsight.completion.OffsetsInFile) Document(com.intellij.openapi.editor.Document) DataContext(com.intellij.openapi.actionSystem.DataContext) TextRange(com.intellij.openapi.util.TextRange) RangeMarker(com.intellij.openapi.editor.RangeMarker) PsiElementFilter(com.intellij.psi.util.PsiElementFilter) Project(com.intellij.openapi.project.Project) OffsetKey(com.intellij.codeInsight.completion.OffsetKey) Editor(com.intellij.openapi.editor.Editor) HashMap(com.intellij.util.containers.HashMap) TemplateContextType(com.intellij.codeInsight.template.TemplateContextType)

Example 2 with PsiElementFilter

use of com.intellij.psi.util.PsiElementFilter in project intellij-community by JetBrains.

the class RegExpBackrefImpl method resolve.

public RegExpGroup resolve() {
    final int index = getIndex();
    final PsiElementProcessor.FindFilteredElement<RegExpElement> processor = new PsiElementProcessor.FindFilteredElement<>(new PsiElementFilter() {

        int groupCount;

        public boolean isAccepted(PsiElement element) {
            if (element instanceof RegExpGroup) {
                if (((RegExpGroup) element).isCapturing() && ++groupCount == index) {
                    return true;
                }
            }
            return element == RegExpBackrefImpl.this;
        }
    });
    PsiTreeUtil.processElements(getContainingFile(), processor);
    if (processor.getFoundElement() instanceof RegExpGroup) {
        return (RegExpGroup) processor.getFoundElement();
    }
    return null;
}
Also used : RegExpElement(org.intellij.lang.regexp.psi.RegExpElement) RegExpGroup(org.intellij.lang.regexp.psi.RegExpGroup) PsiElement(com.intellij.psi.PsiElement) PsiElementProcessor(com.intellij.psi.search.PsiElementProcessor) PsiElementFilter(com.intellij.psi.util.PsiElementFilter)

Example 3 with PsiElementFilter

use of com.intellij.psi.util.PsiElementFilter in project intellij-community by JetBrains.

the class RegExpNamedGroupRefImpl method resolve.

@Nullable
public RegExpGroup resolve() {
    final PsiElementProcessor.FindFilteredElement<RegExpGroup> processor = new PsiElementProcessor.FindFilteredElement<>(new PsiElementFilter() {

        public boolean isAccepted(PsiElement element) {
            if (!(element instanceof RegExpGroup)) {
                return false;
            }
            final RegExpGroup group = (RegExpGroup) element;
            return group.isAnyNamedGroup() && Comparing.equal(getGroupName(), group.getGroupName());
        }
    });
    PsiTreeUtil.processElements(getContainingFile(), processor);
    return processor.getFoundElement();
}
Also used : RegExpGroup(org.intellij.lang.regexp.psi.RegExpGroup) PsiElement(com.intellij.psi.PsiElement) PsiElementProcessor(com.intellij.psi.search.PsiElementProcessor) PsiElementFilter(com.intellij.psi.util.PsiElementFilter) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with PsiElementFilter

use of com.intellij.psi.util.PsiElementFilter in project intellij-community by JetBrains.

the class RegExpNamedGroupRefImpl method getReference.

@Override
public PsiReference getReference() {
    return new PsiReference() {

        public PsiElement getElement() {
            return RegExpNamedGroupRefImpl.this;
        }

        @Override
        public TextRange getRangeInElement() {
            final ASTNode groupNode = getNode().findChildByType(GROUP_REF_TOKENS);
            assert groupNode != null;
            return new TextRange(groupNode.getTextLength(), getTextLength() - 1);
        }

        public PsiElement resolve() {
            return RegExpNamedGroupRefImpl.this.resolve();
        }

        @NotNull
        public String getCanonicalText() {
            return getRangeInElement().substring(getText());
        }

        public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
            throw new UnsupportedOperationException();
        }

        public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
            throw new UnsupportedOperationException();
        }

        public boolean isReferenceTo(PsiElement element) {
            return resolve() == element;
        }

        @Override
        @NotNull
        public Object[] getVariants() {
            final PsiElementProcessor.CollectFilteredElements<RegExpGroup> processor = new PsiElementProcessor.CollectFilteredElements<>(new PsiElementFilter() {

                @Override
                public boolean isAccepted(PsiElement element) {
                    if (!(element instanceof RegExpGroup)) {
                        return false;
                    }
                    final RegExpGroup regExpGroup = (RegExpGroup) element;
                    return regExpGroup.isAnyNamedGroup();
                }
            });
            PsiTreeUtil.processElements(getContainingFile(), processor);
            return processor.toArray();
        }

        public boolean isSoft() {
            return false;
        }
    };
}
Also used : PsiReference(com.intellij.psi.PsiReference) TextRange(com.intellij.openapi.util.TextRange) RegExpGroup(org.intellij.lang.regexp.psi.RegExpGroup) NotNull(org.jetbrains.annotations.NotNull) PsiElementProcessor(com.intellij.psi.search.PsiElementProcessor) PsiElementFilter(com.intellij.psi.util.PsiElementFilter) ASTNode(com.intellij.lang.ASTNode) PsiElement(com.intellij.psi.PsiElement)

Aggregations

PsiElementFilter (com.intellij.psi.util.PsiElementFilter)4 PsiElement (com.intellij.psi.PsiElement)3 PsiElementProcessor (com.intellij.psi.search.PsiElementProcessor)3 RegExpGroup (org.intellij.lang.regexp.psi.RegExpGroup)3 TextRange (com.intellij.openapi.util.TextRange)2 OffsetKey (com.intellij.codeInsight.completion.OffsetKey)1 OffsetsInFile (com.intellij.codeInsight.completion.OffsetsInFile)1 TemplateContextType (com.intellij.codeInsight.template.TemplateContextType)1 ASTNode (com.intellij.lang.ASTNode)1 DataContext (com.intellij.openapi.actionSystem.DataContext)1 WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)1 Document (com.intellij.openapi.editor.Document)1 Editor (com.intellij.openapi.editor.Editor)1 RangeMarker (com.intellij.openapi.editor.RangeMarker)1 Project (com.intellij.openapi.project.Project)1 PsiReference (com.intellij.psi.PsiReference)1 HashMap (com.intellij.util.containers.HashMap)1 RegExpElement (org.intellij.lang.regexp.psi.RegExpElement)1 NotNull (org.jetbrains.annotations.NotNull)1 Nullable (org.jetbrains.annotations.Nullable)1