content: {-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}
  module Language.Java.Syntax.Types where
  
  import Data.Data
  import GHC.Generics (Generic)
  
  -- | There are two kinds of types in the Java programming language: primitive types and reference types.
  data Type
      = PrimType PrimType
      | RefType RefType
    deriving (Eq,Show,Read,Typeable,Generic,Data)
  
  -- | There are three kinds of reference types: class types, interface types, and array types.
  --   Reference types may be parameterized with type arguments.
  --   Type variables cannot be syntactically distinguished from class type identifiers,
  --   and are thus represented uniformly as single ident class types.
  data RefType
      = ClassRefType ClassType
      {- | TypeVariable Ident -}
      | ArrayType Type
    deriving (Eq,Show,Read,Typeable,Generic,Data)
  
  -- | A class or interface type consists of a type declaration specifier,
  --   optionally followed by type arguments (in which case it is a parameterized type).
  data ClassType
      = ClassType [(Ident, [TypeArgument])]
    deriving (Eq,Show,Read,Typeable,Generic,Data)
  
  -- | Type arguments may be either reference types or wildcards.
  data TypeArgument
      = Wildcard (Maybe WildcardBound)
      | ActualType RefType
    deriving (Eq,Show,Read,Typeable,Generic,Data)
  
  data TypeDeclSpecifier
      = TypeDeclSpecifier ClassType
      | TypeDeclSpecifierWithDiamond ClassType Ident Diamond
      | TypeDeclSpecifierUnqualifiedWithDiamond Ident Diamond
    deriving (Eq,Show,Read,Typeable,Generic,Data)
  
  data Diamond = Diamond
    deriving (Eq,Show,Read,Typeable,Generic,Data)
  
  -- | Wildcards may be given explicit bounds, either upper (@extends@) or lower (@super@) bounds.
  data WildcardBound
      = ExtendsBound RefType
      | SuperBound RefType
    deriving (Eq,Show,Read,Typeable,Generic,Data)
  
  -- | A primitive type is predefined by the Java programming language and named by its reserved keyword.
  data PrimType
      = BooleanT
      | ByteT
      | ShortT
      | IntT
      | LongT
      | CharT
      | FloatT
      | DoubleT
    deriving (Eq,Show,Read,Typeable,Generic,Data)
  
  
  -- | A class is generic if it declares one or more type variables. These type variables are known
  --   as the type parameters of the class.
  data TypeParam = TypeParam Ident [RefType]
    deriving (Eq,Show,Read,Typeable,Generic,Data)
  
  -----------------------------------------------------------------------
  -- Names and identifiers
  
  -- | A single identifier.
  data Ident = Ident String
      deriving (Eq,Ord,Show,Read,Typeable,Generic,Data)
  
  -- | A name, i.e. a period-separated list of identifiers.
  data Name = Name [Ident]
      deriving (Eq,Ord,Show,Read,Typeable,Generic,Data)
  