Пример #1
0
  @Nullable
  private static JetBlockExpression findClosestBlock(
      @NotNull PsiElement anchor, boolean down, boolean strict) {
    PsiElement current = PsiTreeUtil.getParentOfType(anchor, JetBlockExpression.class, strict);
    while (current != null) {
      PsiElement parent = current.getParent();
      if (parent instanceof JetClassBody
          || parent instanceof JetClassInitializer
          || parent instanceof JetNamedFunction
          || (parent instanceof JetProperty && !((JetProperty) parent).isLocal())) {
        return null;
      }

      if (parent instanceof JetBlockExpression) return (JetBlockExpression) parent;

      PsiElement sibling = down ? current.getNextSibling() : current.getPrevSibling();
      if (sibling != null) {
        //noinspection unchecked
        JetBlockExpression block =
            (JetBlockExpression)
                JetPsiUtil.getOutermostDescendantElement(sibling, down, CHECK_BLOCK);
        if (block != null) return block;

        current = sibling;
      } else {
        current = parent;
      }
    }

    return null;
  }
Пример #2
0
  @Nullable
  private static JetBlockExpression getDSLLambdaBlock(@NotNull PsiElement element, boolean down) {
    JetCallExpression callExpression =
        (JetCallExpression)
            JetPsiUtil.getOutermostDescendantElement(element, down, IS_CALL_EXPRESSION);
    if (callExpression == null) return null;

    List<JetExpression> functionLiterals = callExpression.getFunctionLiteralArguments();
    if (functionLiterals.isEmpty()) return null;

    return ((JetFunctionLiteralExpression) functionLiterals.get(0)).getBodyExpression();
  }
Пример #3
0
  @Nullable
  private static LineRange getExpressionTargetRange(
      @NotNull Editor editor, @NotNull PsiElement sibling, boolean down) {
    if (sibling instanceof JetIfExpression && !down) {
      JetExpression elseBranch = ((JetIfExpression) sibling).getElse();
      if (elseBranch instanceof JetBlockExpression) {
        sibling = elseBranch;
      }
    }

    PsiElement start = sibling;
    PsiElement end = sibling;

    // moving out of code block
    if (sibling.getNode().getElementType() == (down ? JetTokens.RBRACE : JetTokens.LBRACE)) {
      PsiElement parent = sibling.getParent();
      if (!(parent instanceof JetBlockExpression || parent instanceof JetFunctionLiteral))
        return null;

      JetBlockExpression newBlock;
      if (parent instanceof JetFunctionLiteral) {
        //noinspection ConstantConditions
        newBlock = findClosestBlock(((JetFunctionLiteral) parent).getBodyExpression(), down, false);

        if (!down) {
          ASTNode arrow = ((JetFunctionLiteral) parent).getArrowNode();
          if (arrow != null) {
            end = arrow.getPsi();
          }
        }
      } else {
        newBlock = findClosestBlock(sibling, down, true);
      }

      if (newBlock == null) return null;

      if (PsiTreeUtil.isAncestor(newBlock, parent, true)) {
        PsiElement outermostParent = JetPsiUtil.getOutermostParent(parent, newBlock, true);

        if (down) {
          end = outermostParent;
        } else {
          start = outermostParent;
        }
      } else {
        if (down) {
          end = newBlock.getLBrace();
        } else {
          start = newBlock.getRBrace();
        }
      }
    }
    // moving into code block
    else {
      PsiElement blockLikeElement;

      JetBlockExpression dslBlock = getDSLLambdaBlock(sibling, down);
      if (dslBlock != null) {
        // Use JetFunctionLiteral (since it contains braces)
        blockLikeElement = dslBlock.getParent();
      } else {
        // JetBlockExpression and other block-like elements
        blockLikeElement =
            JetPsiUtil.getOutermostDescendantElement(sibling, down, CHECK_BLOCK_LIKE_ELEMENT);
      }

      if (blockLikeElement != null) {
        if (down) {
          end = JetPsiUtil.findChildByType(blockLikeElement, JetTokens.LBRACE);
          if (blockLikeElement instanceof JetFunctionLiteral) {
            ASTNode arrow = ((JetFunctionLiteral) blockLikeElement).getArrowNode();
            if (arrow != null) {
              end = arrow.getPsi();
            }
          }
        } else {
          start = JetPsiUtil.findChildByType(blockLikeElement, JetTokens.RBRACE);
        }
      }
    }

    return start != null && end != null ? new LineRange(start, end, editor.getDocument()) : null;
  }