{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric   #-}
{-# LANGUAGE DeriveAnyClass   #-}
{-|
Module      : Language.JVM.Attribute.Exceptions
Copyright   : (c) Christian Gram Kalhauge, 2017
License     : MIT
Maintainer  : kalhuage@cs.ucla.edu

Based on the Exceptions Attribute, as documented [here](http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.5). It describes the checked
exceptions that a method can make.
-}
module Language.JVM.Attribute.Exceptions
  ( Exceptions (..)
  ) where

import           Language.JVM.Attribute.Base
import           Language.JVM.Staged
import           Language.JVM.Constant
import           Language.JVM.Utils


-- | 'Exceptions' is an Attribute.
instance IsAttribute (Exceptions Low) where
  attrName :: Const Text (Exceptions Low)
attrName = Text -> Const Text (Exceptions Low)
forall k a (b :: k). a -> Const a b
Const Text
"Exceptions"

-- | An Exceptions attribute is a list of references into the
-- constant pool.
newtype Exceptions r = Exceptions
  { Exceptions r -> SizedList16 (Ref ClassName r)
exceptions :: SizedList16 (Ref ClassName r)
  }

instance Staged Exceptions where
  evolve :: Exceptions Low -> m (Exceptions High)
evolve (Exceptions SizedList16 (Ref ClassName Low)
t) = SizedList Word16 ClassName -> Exceptions High
forall r. SizedList16 (Ref ClassName r) -> Exceptions r
Exceptions (SizedList Word16 ClassName -> Exceptions High)
-> m (SizedList Word16 ClassName) -> m (Exceptions High)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word16 -> m ClassName)
-> SizedList Word16 Word16 -> m (SizedList Word16 ClassName)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Word16 -> m ClassName
forall (m :: * -> *) r.
(EvolveM m, Referenceable r) =>
Word16 -> m r
link SizedList Word16 Word16
SizedList16 (Ref ClassName Low)
t
  devolve :: Exceptions High -> m (Exceptions Low)
devolve (Exceptions SizedList16 (Ref ClassName High)
t) = SizedList Word16 Word16 -> Exceptions Low
forall r. SizedList16 (Ref ClassName r) -> Exceptions r
Exceptions (SizedList Word16 Word16 -> Exceptions Low)
-> m (SizedList Word16 Word16) -> m (Exceptions Low)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ClassName -> m Word16)
-> SizedList Word16 ClassName -> m (SizedList Word16 Word16)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ClassName -> m Word16
forall (m :: * -> *) r.
(DevolveM m, Referenceable r) =>
r -> m Word16
unlink SizedList16 (Ref ClassName High)
SizedList Word16 ClassName
t

$(deriveBaseWithBinary ''Exceptions)