-- | Classfile module, it contains everything from the binary file representation. {-# LANGUAGE DerivingVia #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE StandaloneKindSignatures #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE InstanceSigs #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Language.Java.Classfile (Classfile(..)) where import GHC.Generics (Generic, Generically(Generically)) import Data.Kind (Type) import Language.Java.Classfile.Stage (Stage(Parse)) import Language.Java.Classfile.Version (Version) import Language.Java.Classfile.Magic (Magic) import Language.Java.Classfile.Extractable (Extractable) import Language.Java.Classfile.ConstantPool (ConstantPool) import Language.Java.Classfile.Flags (Flags, FlagMask (..)) import Language.Java.Classfile.ConstantPool.References (Class) import Language.Java.Classfile.Interfaces (Interfaces) import Language.Java.Classfile.Fields (Fields) import Language.Java.Classfile.Methods (Methods) import Language.Java.Classfile.Attributes (Attributes) import Data.Word (Word16) import Pretty.Serialize (PrettySerialize) -- | 'Stage'-indexed classfile. It can represent a class, an interface or a module. type Classfile :: Stage -> Type data Classfile stage = Classfile { magic :: Magic stage , version :: Version , constantPool :: ConstantPool stage , accessFlags :: ClassFlags stage , this :: Class stage , super :: Class stage , interfaces :: Interfaces , fields :: Fields , methods :: Methods , attributes :: Attributes } deriving stock (Generic) deriving instance (Show (Magic stage), Show (ConstantPool stage), Show (ClassFlags stage), Show (Class stage)) => Show (Classfile stage) deriving via Generically (Classfile Parse) instance (Extractable (Classfile Parse)) deriving via Generically (Classfile Parse) instance (PrettySerialize (Classfile Parse)) type ClassFlags :: Stage -> Type data family ClassFlags stage newtype instance ClassFlags Parse = ClassFlags (Flags ClassFlag) deriving stock (Show, Generic) deriving Extractable via Generically (ClassFlags Parse) deriving newtype PrettySerialize data ClassFlag = Public -- ^ may be accessed from outside the package | Final -- ^ no subclasses allowed | Super -- ^ treat superclass methods special when using InvokeSpecial | Interface -- ^ is an interface | Abstract -- ^ abstract, must not be instantiated | Synthetic -- ^ not present in source code | Annotation -- ^ is annotation interface | Enum -- ^ enumerated instances | Module -- ^ module, not a class deriving (Show, Eq, Ord, Enum, Bounded, Generic) deriving PrettySerialize via Generically ClassFlag instance FlagMask ClassFlag where type FlagType ClassFlag = Word16 maskOf :: ClassFlag -> FlagType ClassFlag maskOf = \case Public -> 0x0001 Final -> 0x0010 Super -> 0x0020 Interface -> 0x0200 Abstract -> 0x0400 Synthetic -> 0x1000 Annotation -> 0x2000 Enum -> 0x4000 Module -> 0x8000