@Override public boolean checkAvailable( @NotNull final Editor editor, @NotNull final PsiFile file, @NotNull final MoveInfo info, final boolean down) { // if (!(file instanceof PsiJavaFile)) return false; final boolean available = super.checkAvailable(editor, file, info, down); if (!available) return false; LineRange range = info.toMove; range = expandLineRangeToCoverPsiElements(range, editor, file); if (range == null) return false; info.toMove = range; final int startOffset = editor.logicalPositionToOffset(new LogicalPosition(range.startLine, 0)); final int endOffset = editor.logicalPositionToOffset(new LogicalPosition(range.endLine, 0)); final PsiElement[] statements = CodeInsightUtil.findStatementsInRange(file, startOffset, endOffset); if (statements.length == 0) return false; range.firstElement = statements[0]; range.lastElement = statements[statements.length - 1]; if (!checkMovingInsideOutside(file, editor, range, info, down)) { info.toMove2 = null; return true; } return true; }
private boolean checkMovingInsideOutside( PsiFile file, final Editor editor, LineRange range, @NotNull final MoveInfo info, final boolean down) { final int offset = editor.getCaretModel().getOffset(); PsiElement elementAtOffset = file.getViewProvider().findElementAt(offset, StdLanguages.JAVA); if (elementAtOffset == null) return false; PsiElement guard = elementAtOffset; do { guard = PsiTreeUtil.getParentOfType( guard, PsiMethod.class, PsiClassInitializer.class, PsiClass.class, PsiComment.class); } while (guard instanceof PsiAnonymousClass); PsiElement brace = itIsTheClosingCurlyBraceWeAreMoving(file, editor); if (brace != null) { int line = editor.getDocument().getLineNumber(offset); final LineRange toMove = new LineRange(line, line + 1); toMove.firstElement = toMove.lastElement = brace; info.toMove = toMove; } // cannot move in/outside method/class/initializer/comment if (!calcInsertOffset(file, editor, info.toMove, info, down)) return false; int insertOffset = down ? getLineStartSafeOffset(editor.getDocument(), info.toMove2.endLine) : editor.getDocument().getLineStartOffset(info.toMove2.startLine); PsiElement elementAtInsertOffset = file.getViewProvider().findElementAt(insertOffset, StdLanguages.JAVA); PsiElement newGuard = elementAtInsertOffset; do { newGuard = PsiTreeUtil.getParentOfType( newGuard, PsiMethod.class, PsiClassInitializer.class, PsiClass.class, PsiComment.class); } while (newGuard instanceof PsiAnonymousClass); if (brace != null && PsiTreeUtil.getParentOfType(brace, PsiCodeBlock.class, false) != PsiTreeUtil.getParentOfType(elementAtInsertOffset, PsiCodeBlock.class, false)) { info.indentSource = true; } if (newGuard == guard && isInside(insertOffset, newGuard) == isInside(offset, guard)) return true; // moving in/out nested class is OK if (guard instanceof PsiClass && guard.getParent() instanceof PsiClass) return true; if (newGuard instanceof PsiClass && newGuard.getParent() instanceof PsiClass) return true; return false; }
@Test public void shouldTestInclusionInRangeOfLines() { LineRange range = new LineRange(12, 15); assertThat(range.in(3)).isFalse(); assertThat(range.in(12)).isTrue(); assertThat(range.in(13)).isTrue(); assertThat(range.in(14)).isTrue(); assertThat(range.in(15)).isTrue(); assertThat(range.in(16)).isFalse(); }
@Test public void shouldConvertLineRangeToLines() { LineRange range = new LineRange(12, 15); assertThat(range.toLines()).containsOnly(12, 13, 14, 15); }