code: public static Type getReceiverType(ExpressionTree expressionTree) {
      if (expressionTree instanceof JCFieldAccess) {
        JCFieldAccess methodSelectFieldAccess = (JCFieldAccess) expressionTree;
        return methodSelectFieldAccess.selected.type;
      } else if (expressionTree instanceof JCIdent) {
        JCIdent methodCall = (JCIdent) expressionTree;
        return methodCall.sym.owner.type;
      } else if (expressionTree instanceof JCMethodInvocation) {
        return getReceiverType(((JCMethodInvocation) expressionTree).getMethodSelect());
      } else if (expressionTree instanceof JCMemberReference) {
        return ((JCMemberReference) expressionTree).getQualifierExpression().type;
      }
      throw new IllegalArgumentException(
          "Expected a JCFieldAccess or JCIdent from expression " + expressionTree);
    }
docs: Returns the type of a receiver of a method call expression. Precondition: the expressionTree
  corresponds to a method call.
  
  <p>Examples:
  
  <pre>{@code
  a.b.foo() ==> type of a.b
  a.bar().foo() ==> type of a.bar()
  this.foo() ==> type of this
  foo() ==> type of this
  TheClass.aStaticMethod() ==> TheClass
  aStaticMethod() ==> type of class in which method is defined
  }</pre>