Search in sources :

Example 1 with UnfairTextRange

use of com.intellij.openapi.util.UnfairTextRange in project intellij-community by JetBrains.

the class XmlMover method checkAvailable.

//private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.actions.moveUpDown.XmlMover");
@Override
public boolean checkAvailable(@NotNull final Editor editor, @NotNull final PsiFile file, @NotNull final MoveInfo info, final boolean down) {
    if (!(file instanceof XmlFile)) {
        return false;
    }
    if (!super.checkAvailable(editor, file, info, down))
        return false;
    // updated moved range end to cover multiline tag start
    final Document document = editor.getDocument();
    int movedLineStart = document.getLineStartOffset(info.toMove.startLine);
    final int movedLineEnd = document.getLineEndOffset(info.toMove.endLine - 1);
    PsiElement movedEndElement = file.findElementAt(movedLineEnd);
    if (movedEndElement instanceof PsiWhiteSpace)
        movedEndElement = PsiTreeUtil.prevLeaf(movedEndElement);
    PsiElement movedStartElement = file.findElementAt(movedLineStart);
    if (movedStartElement instanceof PsiWhiteSpace)
        movedStartElement = PsiTreeUtil.nextLeaf(movedStartElement);
    if (movedEndElement == null || movedStartElement == null)
        return false;
    final PsiNamedElement namedParentAtEnd = PsiTreeUtil.getParentOfType(movedEndElement, PsiNamedElement.class);
    final PsiNamedElement namedParentAtStart = PsiTreeUtil.getParentOfType(movedStartElement, PsiNamedElement.class);
    if (checkInjections(movedEndElement, movedStartElement))
        return false;
    PsiNamedElement movedParent = null;
    if (namedParentAtEnd == namedParentAtStart)
        movedParent = namedParentAtEnd;
    else if (namedParentAtEnd instanceof XmlAttribute && namedParentAtStart instanceof XmlTag && namedParentAtEnd.getParent() == namedParentAtStart) {
        movedParent = namedParentAtStart;
    } else if (namedParentAtStart instanceof XmlAttribute && namedParentAtEnd instanceof XmlTag && namedParentAtStart.getParent() == namedParentAtEnd) {
        movedParent = namedParentAtEnd;
    }
    if (movedParent == null) {
        return false;
    }
    final TextRange textRange = movedParent.getTextRange();
    if (movedParent instanceof XmlTag) {
        final XmlTag tag = (XmlTag) movedParent;
        PsiElement parent = tag.getParent();
        if (!(parent instanceof XmlTag) && PsiTreeUtil.getChildrenOfType(parent, XmlTag.class).length < 2) {
            // the only top-level tag
            return info.prohibitMove();
        }
        final TextRange valueRange = tag.getValue().getTextRange();
        final int valueStart = valueRange.getStartOffset();
        if (HtmlUtil.isHtmlTag(tag) && (HtmlUtil.isScriptTag(tag) || HtmlUtil.STYLE_TAG_NAME.equals(tag.getName()))) {
            info.toMove = new LineRange(tag);
            int nextLine = down ? info.toMove.endLine : info.toMove.startLine - 1;
            info.toMove2 = new LineRange(nextLine, nextLine + 1);
        }
        if (movedLineStart < valueStart && valueStart + 1 < document.getTextLength()) {
            movedLineStart = updateMovedRegionEnd(document, movedLineStart, valueStart + 1, info, down);
        }
        if (movedLineStart < valueStart) {
            movedLineStart = updateMovedRegionStart(document, movedLineStart, tag.getTextRange().getStartOffset(), info, down);
        }
    } else if (movedParent instanceof XmlAttribute) {
        final int endOffset = textRange.getEndOffset() + 1;
        if (endOffset < document.getTextLength())
            movedLineStart = updateMovedRegionEnd(document, movedLineStart, endOffset, info, down);
        movedLineStart = updateMovedRegionStart(document, movedLineStart, textRange.getStartOffset(), info, down);
    }
    final TextRange moveDestinationRange = new UnfairTextRange(document.getLineStartOffset(info.toMove2.startLine), document.getLineEndOffset(info.toMove2.endLine - 1));
    if (movedParent instanceof XmlAttribute) {
        final XmlTag parent = ((XmlAttribute) movedParent).getParent();
        if (parent != null) {
            final TextRange valueRange = parent.getValue().getTextRange();
            // Do not move attributes out of tags
            if ((down && moveDestinationRange.getEndOffset() >= valueRange.getStartOffset()) || (!down && moveDestinationRange.getStartOffset() <= parent.getTextRange().getStartOffset())) {
                return info.prohibitMove();
            }
        }
    }
    if (down) {
        PsiElement updatedElement = file.findElementAt(moveDestinationRange.getEndOffset());
        if (updatedElement instanceof PsiWhiteSpace)
            updatedElement = PsiTreeUtil.prevLeaf(updatedElement);
        if (updatedElement != null) {
            final PsiNamedElement targetParent = PsiTreeUtil.getParentOfType(updatedElement, movedParent.getClass());
            if (targetParent instanceof XmlTag) {
                if (targetParent == movedParent)
                    return false;
                if (moveTags(info, (XmlTag) movedParent, (XmlTag) targetParent, down))
                    return true;
                final XmlTag tag = (XmlTag) targetParent;
                final int offset = tag.isEmpty() ? tag.getTextRange().getStartOffset() : tag.getValue().getTextRange().getStartOffset();
                updatedMovedIntoEnd(document, info, offset);
                if (tag.isEmpty()) {
                    info.toMove2 = new LineRange(targetParent);
                }
            } else if (targetParent instanceof XmlAttribute) {
                updatedMovedIntoEnd(document, info, targetParent.getTextRange().getEndOffset());
            }
        }
    } else {
        PsiElement updatedElement = file.findElementAt(moveDestinationRange.getStartOffset());
        if (updatedElement instanceof PsiWhiteSpace)
            updatedElement = PsiTreeUtil.nextLeaf(updatedElement);
        if (updatedElement != null) {
            final PsiNamedElement targetParent = PsiTreeUtil.getParentOfType(updatedElement, movedParent.getClass());
            if (targetParent instanceof XmlTag) {
                final XmlTag tag = (XmlTag) targetParent;
                final TextRange tagValueRange = tag.getValue().getTextRange();
                // We need to update destination range to jump over tag start
                final XmlTag[] subtags = tag.getSubTags();
                if ((tagValueRange.contains(movedLineStart) && subtags.length > 0 && subtags[0] == movedParent) || (tagValueRange.getLength() == 0 && tag.getTextRange().intersects(moveDestinationRange))) {
                    final int line = document.getLineNumber(tag.getTextRange().getStartOffset());
                    final LineRange toMove2 = info.toMove2;
                    info.toMove2 = new LineRange(Math.min(line, toMove2.startLine), toMove2.endLine);
                }
                if (targetParent == movedParent)
                    return false;
                if (moveTags(info, (XmlTag) movedParent, (XmlTag) targetParent, down))
                    return true;
            } else if (targetParent instanceof XmlAttribute) {
                final int line = document.getLineNumber(targetParent.getTextRange().getStartOffset());
                final LineRange toMove2 = info.toMove2;
                info.toMove2 = new LineRange(Math.min(line, toMove2.startLine), toMove2.endLine);
            }
        }
    }
    if (movedParent instanceof XmlTag) {
        // it's quite simple after all...
        info.toMove = new LineRange(movedParent);
    }
    return true;
}
Also used : UnfairTextRange(com.intellij.openapi.util.UnfairTextRange) PsiNamedElement(com.intellij.psi.PsiNamedElement) TextRange(com.intellij.openapi.util.TextRange) UnfairTextRange(com.intellij.openapi.util.UnfairTextRange) Document(com.intellij.openapi.editor.Document) PsiElement(com.intellij.psi.PsiElement) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace)

Example 2 with UnfairTextRange

use of com.intellij.openapi.util.UnfairTextRange in project intellij-community by JetBrains.

the class HtmlConditionalCommentInjector method getLanguagesToInject.

@Override
public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull final PsiElement host) {
    Pair<ASTNode, ASTNode> pair = parseConditionalCommentBoundaries(host);
    if (pair == null) {
        return;
    }
    final TextRange textRange = host.getTextRange();
    final int startOffset = textRange.getStartOffset();
    Language language = host.getParent().getLanguage();
    ASTNode conditionalStart = pair.first;
    ASTNode conditionalEnd = pair.second;
    TextRange range = new UnfairTextRange(conditionalStart.getTextRange().getEndOffset() - startOffset, conditionalEnd.getStartOffset() - startOffset);
    if (range.getStartOffset() < range.getEndOffset()) {
        registrar.startInjecting(language).addPlace(null, null, (PsiLanguageInjectionHost) host, range).doneInjecting();
    }
}
Also used : Language(com.intellij.lang.Language) UnfairTextRange(com.intellij.openapi.util.UnfairTextRange) PsiLanguageInjectionHost(com.intellij.psi.PsiLanguageInjectionHost) ASTNode(com.intellij.lang.ASTNode) TextRange(com.intellij.openapi.util.TextRange) UnfairTextRange(com.intellij.openapi.util.UnfairTextRange)

Example 3 with UnfairTextRange

use of com.intellij.openapi.util.UnfairTextRange in project intellij-community by JetBrains.

the class ChangeNewOperatorTypeFix method changeNewOperatorType.

private static void changeNewOperatorType(PsiNewExpression originalExpression, PsiType toType, final Editor editor) throws IncorrectOperationException {
    PsiNewExpression newExpression;
    PsiElementFactory factory = JavaPsiFacade.getInstance(originalExpression.getProject()).getElementFactory();
    int caretOffset;
    TextRange selection;
    if (toType instanceof PsiArrayType) {
        final PsiExpression[] originalExpressionArrayDimensions = originalExpression.getArrayDimensions();
        caretOffset = 0;
        @NonNls String text = "new " + toType.getDeepComponentType().getCanonicalText() + "[";
        if (originalExpressionArrayDimensions.length > 0) {
            text += originalExpressionArrayDimensions[0].getText();
        } else {
            text += "0";
            caretOffset = -2;
        }
        text += "]";
        for (int i = 1; i < toType.getArrayDimensions(); i++) {
            text += "[";
            String arrayDimension = "";
            if (originalExpressionArrayDimensions.length > i) {
                arrayDimension = originalExpressionArrayDimensions[i].getText();
                text += arrayDimension;
            }
            text += "]";
            if (caretOffset < 0) {
                caretOffset -= arrayDimension.length() + 2;
            }
        }
        newExpression = (PsiNewExpression) factory.createExpressionFromText(text, originalExpression);
        if (caretOffset < 0) {
            selection = new UnfairTextRange(caretOffset, caretOffset + 1);
        } else {
            selection = null;
        }
    } else {
        final PsiAnonymousClass anonymousClass = originalExpression.getAnonymousClass();
        newExpression = (PsiNewExpression) factory.createExpressionFromText("new " + toType.getCanonicalText() + "()" + (anonymousClass != null ? "{}" : ""), originalExpression);
        PsiExpressionList argumentList = originalExpression.getArgumentList();
        if (argumentList == null)
            return;
        newExpression.getArgumentList().replace(argumentList);
        if (anonymousClass == null) {
            //just to prevent useless inference
            if (PsiDiamondTypeUtil.canCollapseToDiamond(newExpression, originalExpression, toType)) {
                final PsiElement paramList = PsiDiamondTypeUtil.replaceExplicitWithDiamond(newExpression.getClassOrAnonymousClassReference().getParameterList());
                newExpression = PsiTreeUtil.getParentOfType(paramList, PsiNewExpression.class);
            }
        }
        if (anonymousClass != null) {
            PsiAnonymousClass newAnonymousClass = newExpression.getAnonymousClass();
            final PsiElement childInside = anonymousClass.getLBrace().getNextSibling();
            if (childInside != null) {
                newAnonymousClass.addRange(childInside, anonymousClass.getRBrace().getPrevSibling());
            }
        }
        selection = null;
        caretOffset = -1;
    }
    PsiElement element = originalExpression.replace(newExpression);
    editor.getCaretModel().moveToOffset(element.getTextRange().getEndOffset() + caretOffset);
    editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
    if (selection != null) {
        selection = selection.shiftRight(element.getTextRange().getEndOffset());
        editor.getSelectionModel().setSelection(selection.getStartOffset(), selection.getEndOffset());
    }
}
Also used : NonNls(org.jetbrains.annotations.NonNls) TextRange(com.intellij.openapi.util.TextRange) UnfairTextRange(com.intellij.openapi.util.UnfairTextRange) UnfairTextRange(com.intellij.openapi.util.UnfairTextRange)

Example 4 with UnfairTextRange

use of com.intellij.openapi.util.UnfairTextRange in project intellij-community by JetBrains.

the class GenericPatchApplier method iterateTransformations.

// indexes are passed inclusive
private void iterateTransformations(final Consumer<TextRange> consumerExcluded, final Consumer<TextRange> consumerIncluded) {
    if (myTransformations.isEmpty()) {
        consumerExcluded.consume(new UnfairTextRange(0, myLines.size() - 1));
    } else {
        final Set<Map.Entry<TextRange, MyAppliedData>> entries = myTransformations.entrySet();
        final Iterator<Map.Entry<TextRange, MyAppliedData>> iterator = entries.iterator();
        assert iterator.hasNext();
        final Map.Entry<TextRange, MyAppliedData> first = iterator.next();
        final TextRange range = first.getKey();
        if (range.getStartOffset() > 0) {
            consumerExcluded.consume(new TextRange(0, range.getStartOffset() - 1));
        }
        consumerIncluded.consume(range);
        int previousEnd = range.getEndOffset() + 1;
        while (iterator.hasNext() && previousEnd < myLines.size()) {
            final Map.Entry<TextRange, MyAppliedData> entry = iterator.next();
            final TextRange key = entry.getKey();
            consumerExcluded.consume(new UnfairTextRange(previousEnd, key.getStartOffset() - 1));
            consumerIncluded.consume(key);
            previousEnd = key.getEndOffset() + 1;
        }
        if (previousEnd < myLines.size()) {
            consumerExcluded.consume(new TextRange(previousEnd, myLines.size() - 1));
        }
    }
}
Also used : UnfairTextRange(com.intellij.openapi.util.UnfairTextRange) TextRange(com.intellij.openapi.util.TextRange) UnfairTextRange(com.intellij.openapi.util.UnfairTextRange)

Example 5 with UnfairTextRange

use of com.intellij.openapi.util.UnfairTextRange in project intellij-plugins by JetBrains.

the class DartReferenceImpl method getRangeInElement.

@Override
public TextRange getRangeInElement() {
    final TextRange textRange = getTextRange();
    DartReference[] dartReferences = PsiTreeUtil.getChildrenOfType(this, DartReference.class);
    if (dartReferences != null && dartReferences.length > 0) {
        TextRange lastReferenceRange = dartReferences[dartReferences.length - 1].getTextRange();
        return new UnfairTextRange(lastReferenceRange.getStartOffset() - textRange.getStartOffset(), lastReferenceRange.getEndOffset() - textRange.getEndOffset());
    }
    return new UnfairTextRange(0, textRange.getEndOffset() - textRange.getStartOffset());
}
Also used : UnfairTextRange(com.intellij.openapi.util.UnfairTextRange) TextRange(com.intellij.openapi.util.TextRange) UnfairTextRange(com.intellij.openapi.util.UnfairTextRange)

Aggregations

UnfairTextRange (com.intellij.openapi.util.UnfairTextRange)13 TextRange (com.intellij.openapi.util.TextRange)12 PsiElement (com.intellij.psi.PsiElement)4 PsiWhiteSpace (com.intellij.psi.PsiWhiteSpace)3 Nullable (org.jetbrains.annotations.Nullable)3 ASTNode (com.intellij.lang.ASTNode)2 NotNull (org.jetbrains.annotations.NotNull)2 IntPair (com.intellij.diff.util.IntPair)1 Language (com.intellij.lang.Language)1 FoldingDescriptor (com.intellij.lang.folding.FoldingDescriptor)1 Document (com.intellij.openapi.editor.Document)1 SelectionModel (com.intellij.openapi.editor.SelectionModel)1 ManualRangeMarker (com.intellij.openapi.editor.impl.ManualRangeMarker)1 PsiComment (com.intellij.psi.PsiComment)1 PsiLanguageInjectionHost (com.intellij.psi.PsiLanguageInjectionHost)1 PsiNamedElement (com.intellij.psi.PsiNamedElement)1 PsiReference (com.intellij.psi.PsiReference)1 XmlAttributeValue (com.intellij.psi.xml.XmlAttributeValue)1 BeforeAfter (com.intellij.util.BeforeAfter)1 ArrayList (java.util.ArrayList)1