{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
module Language.JVM.Attribute.InnerClasses
( InnerClasses (..)
, InnerClass (..)
) where
import qualified Data.Text as Text
import Language.JVM.Attribute.Base
import Language.JVM.Constant
import Language.JVM.Utils
import Language.JVM.Staged
import Language.JVM.AccessFlag
instance IsAttribute (InnerClasses Low) where
attrName = Const "InnerClasses"
newtype InnerClasses r = InnerClasses
{ innerClasses :: Choice (SizedList16 (InnerClass Low)) [InnerClass High] r
}
data InnerClass r = InnerClass
{ icClassName :: !(Ref ClassName r)
, icOuterClassName :: !(Ref (Maybe ClassName) r)
, icInnerName :: !(Ref (Maybe Text.Text) r)
, icInnerAccessFlags :: !(BitSet16 ICAccessFlag)
}
instance Staged InnerClasses where
evolve (InnerClasses (SizedList r)) = InnerClasses <$> mapM evolve r
devolve (InnerClasses r) = InnerClasses . SizedList <$> mapM devolve r
instance Staged InnerClass where
evolve (InnerClass cn ocn inn iac) = label "InnerClass" $ do
InnerClass
<$> link cn
<*> (if ocn == 0 then return Nothing else Just <$> link ocn)
<*> (if inn == 0 then return Nothing else Just <$> link inn)
<*> pure iac
devolve (InnerClass cn mn inn iac) = label "InnerClass" $ do
InnerClass
<$> unlink cn
<*> case mn of
Nothing -> return 0
Just mn' -> unlink mn'
<*> case inn of
Nothing -> return 0
Just inn' -> unlink inn'
<*> pure iac
$(deriveBaseWithBinary ''InnerClasses)
$(deriveBaseWithBinary ''InnerClass)