===========
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))))))
