title: Get context at caret
body: <p>I'm developing a IntelliJ IDEA plugin to get context at current caret. More specific, I need to get a list of variables' types and names that can be used at caret. For example:</p>
  
  <pre><code>public static void main(String[] args) throws IOException {
      Workbook wb = new HSSFWorkbook();
      // caret 1
      Sheet sheet = wb.createSheet("new sheet");
      Row row = sheet.createRow((short) 1);
      for(int i = 0; i &lt; 5; i++) {
          // caret 2
          row.createCell(i).setCellValue("X");
      }
      // caret 3
  }
  </code></pre>
  
  <p>I need to get <code>wb: Workbook</code> at caret 1, <code>wb: Workbook, sheet: Sheet, row: Row, i: int</code> at caret 2 and <code>wb: Workbook, sheet: Sheet, row: Row</code> at caret 3 because <code>i: int</code> is no longer in the scope.</p>
  
  <p><a href="https://intellij-support.jetbrains.com/hc/en-us/community/posts/206755815-Getting-the-PsiElement-at-the-caret" rel="nofollow noreferrer">This link</a> seems related, it suggests <code>file.findElementAt(editor.getCaretModel().getOffset())</code>. This expression returns a <code>PsiElement</code> object. However, when I get context of this object and traverse the context using <code>PsiRecursiveElementVisitor</code>, it will visit elements defined after caret, which doesn't meet my requirement above.</p>
  
  <p>My code:</p>
  
  <pre><code>public class ContextView extends AnAction {
  
      public void actionPerformed(AnActionEvent event) {
          final Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
          final Project project = event.getRequiredData(CommonDataKeys.PROJECT);
          //Access document, caret, and selection
          final Document document = editor.getDocument();
          PsiJavaFile javaFile = (PsiJavaFile) PsiDocumentManager.getInstance(project).getPsiFile(document);
  
          PsiElement currentEle = javaFile.findElementAt(editor.getCaretModel().getOffset());
          PsiElement cxt = currentEle.getContext();
  
          cxt.accept(new PsiRecursiveElementVisitor() {
              @Override
              public void visitElement(PsiElement element) {
                  System.out.println(element.toString());
                  super.visitElement(element);
              }
          });
      }
  }
  </code></pre>
  
  <p>So how to solve the problem?</p>