1 {-# LANGUAGE TypeFamilies, StandaloneDeriving, FlexibleInstances, FlexibleContexts, UndecidableInstances #-}
2 -- | This module declares `high-level' data types for Java classes, methods etc.
5 import Codec.Binary.UTF8.String hiding (encode, decode)
6 import Control.Applicative
9 import qualified Data.ByteString.Lazy as B
12 import qualified Data.Set as S
13 import qualified Data.Map as M
17 instance IsString B.ByteString where
18 fromString s = B.pack $ map (fromIntegral . ord) $ encodeString s
20 toString :: B.ByteString -> String
21 toString bstr = decodeString $ map (chr . fromIntegral) $ B.unpack bstr
23 toCharList :: B.ByteString -> [Int]
24 toCharList bstr = map fromIntegral $ B.unpack bstr
27 type Pool = M.Map Word16 Constant
29 poolSize :: Pool -> Int
32 (!) :: (Ord k) => M.Map k a -> k -> a
35 showListIx :: (Show a) => [a] -> String
36 showListIx list = unlines $ zipWith s [1..] list
37 where s i x = show i ++ ":\t" ++ show x
39 class HasAttributes a where
40 attributes :: a -> Attributes
45 classAccess :: Access,
46 this :: B.ByteString, -- ^ this class name
47 super :: Maybe B.ByteString, -- ^ super class name
48 implements :: [B.ByteString], -- ^ implemented interfaces
51 classAttrs :: Attributes
55 instance HasAttributes Class where
56 attributes = classAttrs
58 class HasSignature a where
61 -- | Name and signature pair. Used for methods and fields.
62 data NameType a = NameType {
63 ntName :: B.ByteString,
64 ntSignature :: Signature a }
66 instance Show (Signature a) => Show (NameType a) where
67 show (NameType n t) = toString n ++ ": " ++ show t
69 deriving instance Eq (Signature a) => Eq (NameType a)
71 -- | Constant pool item
74 | CField {refClass :: B.ByteString, fieldNameType :: NameType Field}
75 | CMethod {refClass :: B.ByteString, nameType :: NameType Method}
76 | CIfaceMethod {refClass :: B.ByteString, nameType :: NameType Method}
77 | CString B.ByteString
82 | CNameType B.ByteString B.ByteString
83 | CUTF8 {getString :: B.ByteString}
84 | CUnicode {getString :: B.ByteString}
87 className :: Constant -> B.ByteString
88 className (CClass s) = s
89 className x = error $ "Not a class: " ++ show x
91 instance Show Constant where
92 show (CClass name) = "class " ++ toString name
93 show (CField cls nt) = "field " ++ toString cls ++ "." ++ show nt
94 show (CMethod cls nt) = "method " ++ toString cls ++ "." ++ show nt
95 show (CIfaceMethod cls nt) = "interface method " ++ toString cls ++ "." ++ show nt
96 show (CString s) = "String \"" ++ toString s ++ "\""
97 show (CInteger x) = show x
98 show (CFloat x) = show x
99 show (CLong x) = show x
100 show (CDouble x) = show x
101 show (CNameType name tp) = toString name ++ ": " ++ toString tp
102 show (CUTF8 s) = "UTF8 \"" ++ toString s ++ "\""
103 show (CUnicode s) = "Unicode \"" ++ toString s ++ "\""
107 fieldAccess :: Access,
108 fieldName :: B.ByteString,
109 fieldSignature :: FieldSignature,
110 fieldAttrs :: Attributes }
113 instance HasSignature Field where
114 type Signature Field = FieldSignature
116 instance HasAttributes Field where
117 attributes = fieldAttrs
120 data Method = Method {
121 methodAccess :: Access,
122 methodName :: B.ByteString,
123 methodSignature :: MethodSignature,
124 methodAttrs :: Attributes }
127 instance HasSignature Method where
128 type Signature Method = MethodSignature
130 instance HasAttributes Method where
131 attributes = methodAttrs
133 -- | Set of access flags
134 type Access = S.Set AccessFlag
136 -- | Access flags. Used for classess, methods, variables.
138 ACC_PUBLIC -- ^ 0x0001 Visible for all
139 | ACC_PRIVATE -- ^ 0x0002 Visible only for defined class
140 | ACC_PROTECTED -- ^ 0x0004 Visible only for subclasses
141 | ACC_STATIC -- ^ 0x0008 Static method or variable
142 | ACC_FINAL -- ^ 0x0010 No further subclassing or assignments
143 | ACC_SYNCHRONIZED -- ^ 0x0020 Uses monitors
144 | ACC_VOLATILE -- ^ 0x0040 Could not be cached
145 | ACC_TRANSIENT -- ^ 0x0080
146 | ACC_NATIVE -- ^ 0x0100 Implemented in other language
147 | ACC_INTERFACE -- ^ 0x0200 Class is interface
148 | ACC_ABSTRACT -- ^ 0x0400
149 deriving (Eq, Show, Ord, Enum)
151 -- | Generic attribute
152 data Attribute = Attribute {
153 attrName :: B.ByteString,
154 attrValue :: B.ByteString }
157 -- | Set of attributes
158 type Attributes = M.Map B.ByteString B.ByteString
160 instance (Binary (Signature a)) => Binary (NameType a) where
161 put (NameType n t) = putLazyByteString n >> put t
163 get = NameType <$> get <*> get
165 byteString :: (Binary t) => t -> B.ByteString
166 byteString x = runPut (put x)