Beispiel #1
0
  public static TextWithImports getEditorText(final Editor editor) {
    if (editor == null) {
      return null;
    }
    final Project project = editor.getProject();
    if (project == null) return null;

    String defaultExpression = editor.getSelectionModel().getSelectedText();
    if (defaultExpression == null) {
      int offset = editor.getCaretModel().getOffset();
      PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
      if (psiFile != null) {
        PsiElement elementAtCursor = psiFile.findElementAt(offset);
        if (elementAtCursor != null) {
          final EditorTextProvider textProvider =
              EditorTextProvider.EP.forLanguage(elementAtCursor.getLanguage());
          if (textProvider != null) {
            final TextWithImports editorText = textProvider.getEditorText(elementAtCursor);
            if (editorText != null) return editorText;
          }
        }
      }
    } else {
      return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, defaultExpression);
    }
    return null;
  }
Beispiel #2
0
  public static List<PsiLambdaExpression> collectLambdas(
      @NotNull SourcePosition position, final boolean onlyOnTheLine) {
    ApplicationManager.getApplication().assertReadAccessAllowed();
    PsiFile file = position.getFile();
    final int line = position.getLine();
    final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
    if (document == null || line >= document.getLineCount()) {
      return Collections.emptyList();
    }
    PsiElement element = position.getElementAt();
    final TextRange lineRange = DocumentUtil.getLineTextRange(document, line);
    do {
      PsiElement parent = element.getParent();
      if (parent == null || (parent.getTextOffset() < lineRange.getStartOffset())) {
        break;
      }
      element = parent;
    } while (true);

    final List<PsiLambdaExpression> lambdas = new ArrayList<PsiLambdaExpression>(3);
    final PsiElementVisitor lambdaCollector =
        new JavaRecursiveElementVisitor() {
          @Override
          public void visitLambdaExpression(PsiLambdaExpression expression) {
            super.visitLambdaExpression(expression);
            if (!onlyOnTheLine || getFirstElementOnTheLine(expression, document, line) != null) {
              lambdas.add(expression);
            }
          }
        };
    element.accept(lambdaCollector);
    // add initial lambda if we're inside already
    PsiElement method = getContainingMethod(element);
    if (method instanceof PsiLambdaExpression) {
      lambdas.add((PsiLambdaExpression) method);
    }
    for (PsiElement sibling = getNextElement(element);
        sibling != null;
        sibling = getNextElement(sibling)) {
      if (!intersects(lineRange, sibling)) {
        break;
      }
      sibling.accept(lambdaCollector);
    }
    return lambdas;
  }
  private static Trinity<PsiElement, TextRange, Value> getSelectedExpression(
      final Project project, final Editor editor, final Point point, final ValueHintType type) {
    final Ref<PsiElement> selectedExpression = Ref.create(null);
    final Ref<TextRange> currentRange = Ref.create(null);
    final Ref<Value> preCalculatedValue = Ref.create(null);

    PsiDocumentManager.getInstance(project)
        .commitAndRunReadAction(
            new Runnable() {
              public void run() {
                // Point -> offset
                final int offset = calculateOffset(editor, point);

                PsiFile psiFile =
                    PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());

                if (psiFile == null || !psiFile.isValid()) return;

                int selectionStart = editor.getSelectionModel().getSelectionStart();
                int selectionEnd = editor.getSelectionModel().getSelectionEnd();

                if ((type == ValueHintType.MOUSE_CLICK_HINT
                        || type == ValueHintType.MOUSE_ALT_OVER_HINT)
                    && (selectionStart <= offset && offset <= selectionEnd)) {
                  PsiElement ctx =
                      (selectionStart > 0)
                          ? psiFile.findElementAt(selectionStart - 1)
                          : psiFile.findElementAt(selectionStart);
                  try {
                    String text = editor.getSelectionModel().getSelectedText();
                    if (text != null && ctx != null) {
                      selectedExpression.set(
                          JVMElementFactories.getFactory(ctx.getLanguage(), project)
                              .createExpressionFromText(text, ctx));
                      currentRange.set(
                          new TextRange(
                              editor.getSelectionModel().getSelectionStart(),
                              editor.getSelectionModel().getSelectionEnd()));
                    }
                  } catch (IncorrectOperationException ignored) {
                  }
                }

                if (currentRange.get() == null) {
                  PsiElement elementAtCursor = psiFile.findElementAt(offset);
                  if (elementAtCursor == null) {
                    return;
                  }
                  Pair<PsiElement, TextRange> pair =
                      findExpression(
                          elementAtCursor,
                          type == ValueHintType.MOUSE_CLICK_HINT
                              || type == ValueHintType.MOUSE_ALT_OVER_HINT);
                  if (pair == null) {
                    if (type == ValueHintType.MOUSE_OVER_HINT) {
                      final DebuggerSession debuggerSession =
                          DebuggerManagerEx.getInstanceEx(project)
                              .getContext()
                              .getDebuggerSession();
                      if (debuggerSession != null && debuggerSession.isPaused()) {
                        final Pair<Method, Value> lastExecuted =
                            debuggerSession.getProcess().getLastExecutedMethod();
                        if (lastExecuted != null) {
                          final Method method = lastExecuted.getFirst();
                          if (method != null) {
                            final Pair<PsiElement, TextRange> expressionPair =
                                findExpression(elementAtCursor, true);
                            if (expressionPair != null
                                && expressionPair.getFirst() instanceof PsiMethodCallExpression) {
                              final PsiMethodCallExpression methodCallExpression =
                                  (PsiMethodCallExpression) expressionPair.getFirst();
                              final PsiMethod psiMethod = methodCallExpression.resolveMethod();
                              if (psiMethod != null) {
                                final JVMName jvmSignature = JVMNameUtil.getJVMSignature(psiMethod);
                                try {
                                  if (method.name().equals(psiMethod.getName())
                                      && method
                                          .signature()
                                          .equals(
                                              jvmSignature.getName(debuggerSession.getProcess()))) {
                                    pair = expressionPair;
                                    preCalculatedValue.set(lastExecuted.getSecond());
                                  }
                                } catch (EvaluateException ignored) {
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                  if (pair == null) {
                    return;
                  }
                  selectedExpression.set(pair.getFirst());
                  currentRange.set(pair.getSecond());
                }
              }
            });
    return Trinity.create(selectedExpression.get(), currentRange.get(), preCalculatedValue.get());
  }