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 library
exposed-modules: exposed-modules:
Data.Bounded.Generic Data.Enum.Util
Data.Hex Data.Hex
Language.Java.Classfile Language.Java.Classfile
Language.Java.Classfile.ClassFlag 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 GHC.Generics (Generic, Generically(Generically))
import Language.Java.Classfile.Extractable (Extractable) import Language.Java.Classfile.Extractable (Extractable)
import Language.Java.Classfile.ConstantPool (ConstantPool) 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 data Classfile = Classfile
{ magic :: Magic { magic :: Magic
, version :: Version , version :: Version
, constantPool :: ConstantPool , constantPool :: ConstantPool
, accessFlags :: AccessFlags , accessFlags :: Flags ClassFlag
, this :: ClassReference
, super :: ClassReference
} }
deriving stock (Show, Generic) deriving stock (Show, Generic)
deriving Extractable via Generically Classfile 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