java-classfile/src/Language/Java/Classfile.hs

90 lines
3.2 KiB
Haskell

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