jvm-binary-0.9.0: src/Language/JVM/Field.hs
{-|
Module : Language.JVM.Field
Copyright : (c) Christian Gram Kalhauge, 2017
License : MIT
Maintainer : kalhuage@cs.ucla.edu
-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE RecordWildCards #-}
module Language.JVM.Field
( Field (..)
, fAccessFlags
-- * Attributes
, fConstantValue
, fSignature
, FieldAttributes (..)
, emptyFieldAttributes
) where
import Data.Monoid
import qualified Data.Set as Set
import qualified Data.Text as Text
import Language.JVM.AccessFlag
import Language.JVM.Attribute
import Language.JVM.Constant
import Language.JVM.Staged
import Language.JVM.Utils
import Language.JVM.Type
-- | A Field in the class-file, as described
-- [here](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.5).
data Field r = Field
{ fAccessFlags' :: !(BitSet16 FAccessFlag)
, fName :: !(Ref Text.Text r)
, fDescriptor :: !(Ref FieldDescriptor r)
, fAttributes :: !(Attributes FieldAttributes r)
}
-- | Get the set of access flags
fAccessFlags :: Field r -> Set.Set FAccessFlag
fAccessFlags = toSet . fAccessFlags'
-- | Fetch the 'ConstantValue' attribute.
fConstantValue :: Field High -> Maybe (ConstantValue High)
fConstantValue =
firstOne . faConstantValues . fAttributes
-- | Fetches the 'Signature' attribute, if any.
fSignature :: Field High -> Maybe (Signature High)
fSignature =
firstOne . faSignatures . fAttributes
data FieldAttributes r = FieldAttributes
{ faConstantValues :: [ ConstantValue r ]
, faSignatures :: [ Signature r ]
, faVisibleAnnotations :: [ RuntimeVisibleAnnotations r ]
, faInvisibleAnnotations :: [ RuntimeInvisibleAnnotations r ]
, faVisibleTypeAnnotations ::
[ RuntimeVisibleTypeAnnotations FieldTypeAnnotation r ]
, faInvisibleTypeAnnotations ::
[ RuntimeInvisibleTypeAnnotations FieldTypeAnnotation r ]
, faOthers :: [ Attribute r ]
}
emptyFieldAttributes :: FieldAttributes High
emptyFieldAttributes =
FieldAttributes [] [] [] [] [] [] []
instance Staged Field where
evolve field = label "Field" $ do
fi <- link (fName field)
fd <- link (fDescriptor field)
label (Text.unpack . serialize $ fi <:> fd) $ do
fattr <- fmap (`appEndo` emptyFieldAttributes) . fromAttributes FieldAttribute (fAttributes field)
$ collect
[ Attr (\e a -> a {faConstantValues = e : faConstantValues a })
, Attr (\e a -> a {faSignatures = e : faSignatures a })
, Attr (\e a -> a {faVisibleAnnotations = e : faVisibleAnnotations a })
, Attr (\e a -> a {faInvisibleAnnotations = e : faInvisibleAnnotations a })
, Attr (\e a -> a {faVisibleTypeAnnotations = e : faVisibleTypeAnnotations a })
, Attr (\e a -> a {faInvisibleTypeAnnotations = e : faInvisibleTypeAnnotations a })
] (\e a -> a { faOthers = e : faOthers a })
return $ Field (fAccessFlags' field) fi fd fattr
devolve field = do
fi <- unlink (fName field)
fd <- unlink (fDescriptor field)
fattr <- fromFieldAttributes (fAttributes field)
return $ Field (fAccessFlags' field) fi fd (SizedList fattr)
where
fromFieldAttributes (FieldAttributes {..}) =
concat <$> sequence
[ mapM toAttribute faConstantValues
, mapM toAttribute faSignatures
, mapM toAttribute faVisibleAnnotations
, mapM toAttribute faInvisibleAnnotations
, mapM toAttribute faVisibleTypeAnnotations
, mapM toAttribute faInvisibleTypeAnnotations
, mapM devolve faOthers
]
$(deriveBase ''FieldAttributes)
$(deriveBaseWithBinary ''Field)