static List<IdentifierTree> getVariableUses(ExpressionTree tree) {
    List<IdentifierTree> freeVars = new ArrayList<>();

    new TreeScanner<Void, Void>() {
      @Override
      public Void visitIdentifier(IdentifierTree node, Void v) {
        if (((JCIdent) node).sym instanceof VarSymbol) {
          freeVars.add(node);
        }
        return super.visitIdentifier(node, null);
      }
    }.scan(tree, null);

    return freeVars;
  }
@Test
  public void getVariableUses() {
    writeFile("A.java", "public class A {", "  public String b;", "  void foo() {}", "}");
    writeFile(
        "B.java",
        "public class B {",
        "  A my;",
        "  B bar() { return null; }",
        "  void foo(String x, A a) {",
        "    x.trim().intern();",
        "    a.b.trim().intern();",
        "    this.my.foo();",
        "    my.foo();",
        "    this.bar();",
        "    String.valueOf(0);",
        "    java.lang.String.valueOf(1);",
        "    bar().bar();",
        "    System.out.println();",
        "    a.b.indexOf(x.substring(1));",
        "  }",
        "}");

    TestScanner scanner =
        new TestScanner.Builder()
            .add("x.trim().intern()", "x")
            .add("a.b.trim().intern()", "a")
            .add("this.my.foo()", "this")
            .add("my.foo()", "my")
            .add("this.bar()", "this")
            .add("String.valueOf(0)")
            .add("java.lang.String.valueOf(1)")
            .add("bar().bar()")
            .add("System.out.println()")
            .add("a.b.indexOf(x.substring(1))", "a", "x")
            .build();
    assertCompiles(scanner);
    scanner.assertFoundAll();
  }