===========
empty class
===========

class Foo extends Bar {}

---
(ql (moduleMember (dataclass (className) (typeExpr (className)))))

===================================
class with characteristic predicate
===================================

abstract class Foo extends Bar {

  pragma[inline]
  Foo() {
    this = this
  }

}

---

(ql (moduleMember
  (annotation (annotName))
  (dataclass (className) (typeExpr (className))
    (classMember (annotation (annotName)  (annotArg (simpleId)))
      (charpred (className)
        (comp_term (variable (this)) (compop) (variable (this))))))))
==================
class with members
==================

class X extends Y {
  m::F f;

  m::F a() {
    result = f
  }
}

---

(ql (moduleMember
  (dataclass (className) (typeExpr (className))
    (classMember (field (varDecl (typeExpr (moduleExpr (simpleId)) (className)) (varName (simpleId)))))
    (classMember (memberPredicate (typeExpr (moduleExpr (simpleId)) (className)) (predicateName)
    (body (comp_term (variable (result)) (compop) (variable (varName (simpleId))))))))))

===========
class alias
===========

class X = foo::Bas;

---
(ql (moduleMember
  (dataclass (className) (typeAliasBody (typeExpr (moduleExpr (simpleId)) (className))))))


================
class instanceof
================

class X extends Y1, Y2 instanceof Z1, Z2 {
  X() { none() }
}

---

(ql
  (moduleMember
    (dataclass
      (className)
      (typeExpr
        (className))
      (typeExpr
        (className))
      (typeExpr
        (className))
      (typeExpr
        (className))
      (classMember
        (charpred
          (className)
          (special_call
            (specialId)))))))