feat: class flag parsing

This commit is contained in:
vegowotenks 2025-07-12 17:52:59 +02:00
parent 7826aa880e
commit 10ca143163
6 changed files with 80 additions and 2 deletions

View file

@ -25,7 +25,7 @@ source-repository head
library
exposed-modules:
Data.Bounded.Generic
Data.Enum.Util
Data.Hex
Language.Java.Classfile
Language.Java.Classfile.ClassFlag

5
src/Data/Enum/Util.hs Normal file
View file

@ -0,0 +1,5 @@
module Data.Enum.Util (enumerate) where
enumerate :: Bounded a => Enum a => [a]
enumerate = [minBound..maxBound]

View file

@ -6,12 +6,17 @@ import Language.Java.Classfile.Magic (Magic)
import GHC.Generics (Generic, Generically(Generically))
import Language.Java.Classfile.Extractable (Extractable)
import Language.Java.Classfile.ConstantPool (ConstantPool)
import Language.Java.Classfile.Flags (Flags)
import Language.Java.Classfile.ClassFlag (ClassFlag)
import Language.Java.Classfile.ConstantPool.References (ClassReference)
data Classfile = Classfile
{ magic :: Magic
, version :: Version
, constantPool :: ConstantPool
, accessFlags :: AccessFlags
, accessFlags :: Flags ClassFlag
, this :: ClassReference
, super :: ClassReference
}
deriving stock (Show, Generic)
deriving Extractable via Generically Classfile

View file

@ -0,0 +1,33 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE LambdaCase #-}
module Language.Java.Classfile.ClassFlag (ClassFlag(..)) where
import Data.Word (Word16)
import Language.Java.Classfile.Flag (FlagMask (..))
data ClassFlag
= Public
| Final
| Super
| Interface
| Abstract
| Synthetic
| Annotation
| Enum
| Module
deriving (Show, Eq, Ord, Enum, Bounded)
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

View file

@ -0,0 +1,8 @@
{-# LANGUAGE TypeFamilies #-}
module Language.Java.Classfile.Flag (FlagMask(..)) where
import Data.Kind (Type)
class FlagMask a where
type FlagType a :: Type
maskOf :: a -> FlagType a

View file

@ -0,0 +1,27 @@
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
module Language.Java.Classfile.Flags (Flags(..)) where
import Data.Set (Set)
import Language.Java.Classfile.Extractable (Extractable (extract))
import Language.Java.Classfile.Extract (Extract)
import Language.Java.Classfile.Flag (FlagMask(..))
import Data.Enum.Util (enumerate)
import qualified Data.Set as Set
import Data.Bits (Bits((.&.)))
newtype Flags a = Flags (Set a)
deriving (Show)
instance (Extractable (FlagType a), Bounded a, Enum a, Ord a, FlagMask a, Bits (FlagType a), Num (FlagType a)) => Extractable (Flags a) where
extract :: Extract (Flags a)
extract = do
flags <- extract @(FlagType a)
let allFlags = enumerate @a
let isContained flag = (maskOf flag .&. flags) /= 0
pure . Flags . Set.fromList $ filter isContained allFlags