{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-} {-| Module : Language.JVM.Attribute.InnerClasses Copyright : (c) Christian Gram Kalhauge, 2018 License : MIT Maintainer : kalhuage@cs.ucla.edu Based on the InnerClasses Attribute, as documented [here](http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.6). -} 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 -- | 'InnerClasses' is an Attribute. instance IsAttribute (InnerClasses Low) where attrName = Const "InnerClasses" -- | The 'InnerClasses' is a reference to the enclosing method of the class 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)