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;
}
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();
}
}
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());
}
}
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));
}
}
}
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());
}
Aggregations